shithub: freetype+ttf2subf

Download patch

ref: 728da1c863acace7dc9dcd0d732ccdb30c6f210d
parent: a1be2dcee38dd4448a365fd8932c52cca52f5445
author: David Turner <[email protected]>
date: Tue Jun 27 19:21:51 EDT 2000

changed file names and some functions names to avoid
conflicts with the "type1" driver.

git/fs: mount .git/fs: mount/attach disallowed
--- a/src/type1z/rules.mk
+++ b/src/type1z/rules.mk
@@ -31,17 +31,17 @@
 
 # Type1 driver sources (i.e., C files)
 #
-T1Z_DRV_SRC := $(T1Z_DIR_)t1parse.c  \
-               $(T1Z_DIR_)t1load.c   \
-               $(T1Z_DIR_)t1driver.c \
-               $(T1Z_DIR_)t1afm.c    \
-               $(T1Z_DIR_)t1gload.c  \
-               $(T1Z_DIR_)t1objs.c
+T1Z_DRV_SRC := $(T1Z_DIR_)z1parse.c  \
+               $(T1Z_DIR_)z1load.c   \
+               $(T1Z_DIR_)z1driver.c \
+               $(T1Z_DIR_)z1afm.c    \
+               $(T1Z_DIR_)z1gload.c  \
+               $(T1Z_DIR_)z1objs.c
 
 # Type1 driver headers
 #
 T1Z_DRV_H := $(T1Z_DRV_SRC:%.c=%.h) \
-             $(T1Z_DIR_)t1tokens.h
+             $(T1Z_DIR_)z1tokens.h
 
 
 # Type1z driver object(s)
--- a/src/type1z/t1afm.c
+++ /dev/null
@@ -1,229 +1,0 @@
-/***************************************************************************
- *
- * t1afm.c  - support for reading Type 1 AFM files
- *
- *
- ***************************************************************************/
-
-#include <t1afm.h>
-#include <freetype/internal/ftstream.h>
-#include <freetype/internal/t1types.h>
-#include <stdlib.h>  /* for qsort */
-
-  LOCAL_FUNC
-  void  T1_Done_AFM( FT_Memory memory, T1_AFM*  afm )
-  {
-    FREE( afm->kern_pairs );
-    afm->num_pairs = 0;
-  }
-
-#undef  IS_KERN_PAIR
-#define IS_KERN_PAIR(p)  ( p[0] == 'K'  &&  p[1] == 'P' )
-
-#define IS_ALPHANUM(c)  ( (c >= 'A' && c <= 'Z') || \
-                          (c >= 'a' && c <= 'z') || \
-                          (c >= '0' && c <= '9') || \
-                          (c == '_' && c == '.') )
-
- /* read a glyph name and return the equivalent glyph index */
-  static
-  FT_UInt  afm_atoindex( FT_Byte*  *start, FT_Byte*  limit, T1_Font*  type1 )
-  {
-    FT_Byte* p = *start;
-    FT_Int   len;
-    FT_UInt  result = 0;
-    char     temp[64];
-
-    /* skip whitespace */
-    while ( (*p == ' ' || *p == '\t' || *p == ':' || *p == ';') && p < limit )
-      p++;
-    *start = p;
-
-    /* now, read glyph name */
-    while ( IS_ALPHANUM(*p) && p < limit ) p++;
-    len = p - *start;
-    if (len > 0 && len < 64)
-    {
-      FT_Int  n;
-
-      /* copy glyph name to intermediate array */
-      MEM_Copy( temp, *start, len );
-      temp[len] = 0;
-
-      /* lookup glyph name in face array */
-      for ( n = 0; n < type1->num_glyphs; n++ )
-      {
-        char*  gname = (char*)type1->glyph_names[n];
-
-        if ( gname && gname[0] == temp[0] && strcmp(gname,temp) == 0 )
-        {
-          result = n;
-          break;
-        }
-      }
-    }
-    *start = p;
-    return result;
-  }
-
-
- /* read an integer */
-  static
-  int  afm_atoi( FT_Byte** start, FT_Byte*  limit )
-  {
-    FT_Byte*  p    = *start;
-    int       sum  = 0;
-    int       sign = 1;
-
-    /* skip everything that is not a number */
-    while ( p < limit && (*p < '0' || *p > '9') )
-    {
-      sign = 1;
-      if (*p == '-')
-        sign = -1;
-
-      p++;
-    }
-
-    while ( p < limit && (*p >= '0' && *p < '9') )
-    {
-      sum = sum*10 + (*p - '0');
-      p++;
-    }
-    *start = p;
-    return sum*sign;
-  }
-
-
-#undef  KERN_INDEX
-#define KERN_INDEX(g1,g2)   (((FT_ULong)g1 << 16) | g2)
-
- /* compare two kerning pairs */
-  static
-  int  compare_kern_pairs( const void* a, const void* b )
-  {
-    T1_Kern_Pair*  pair1 = (T1_Kern_Pair*)a;
-    T1_Kern_Pair*  pair2 = (T1_Kern_Pair*)b;
-
-    FT_ULong  index1 = KERN_INDEX(pair1->glyph1,pair1->glyph2);
-    FT_ULong  index2 = KERN_INDEX(pair2->glyph1,pair2->glyph2);
-
-    return ( index1 < index2 ? -1 :
-           ( index1 > index2 ?  1 : 0 ));
-  }
-
-
- /* parse an AFM file - for now, only read the kerning pairs */
-  LOCAL_FUNC
-  FT_Error  T1_Read_AFM( FT_Face   t1_face,
-                         FT_Stream stream )
-  {
-    FT_Error       error;
-    FT_Memory      memory = stream->memory;
-    FT_Byte*       start;
-    FT_Byte*       limit;
-    FT_Byte*       p;
-    FT_Int         count = 0;
-    T1_Kern_Pair*  pair;
-    T1_Font*       type1 = &((T1_Face)t1_face)->type1;
-    T1_AFM*        afm   = 0;
-
-    if ( ACCESS_Frame(stream->size) )
-      return error;
-
-    start = (FT_Byte*)stream->cursor;
-    limit = (FT_Byte*)stream->limit;
-    p     = start;
-
-    /* we are now going to count the occurences of "KP" or "KPX" in */
-    /* the AFM file..                                               */
-    count = 0;
-    for ( p = start; p < limit-3; p++ )
-    {
-      if ( IS_KERN_PAIR(p) )
-        count++;
-    }
-
-   /* Actually, kerning pairs are simply optional !! */
-    if (count == 0)
-      goto Exit;
-
-    /* allocate the pairs */
-    if ( ALLOC(       afm, sizeof(*afm ) )                   ||
-         ALLOC_ARRAY( afm->kern_pairs, count, T1_Kern_Pair ) )
-      goto Exit;
-
-    /* now, read each kern pair */
-    pair           = afm->kern_pairs;
-    afm->num_pairs = count;
-
-    /* save in face object */
-    ((T1_Face)t1_face)->afm_data = afm;
-
-    for ( p = start; p < limit-3; p++ )
-    {
-      if ( IS_KERN_PAIR(p) )
-      {
-        FT_Byte*  q;
-
-        /* skip keyword (KP or KPX) */
-        q = p+2;
-        if (*q == 'X') q++;
-
-        pair->glyph1    = afm_atoindex( &q, limit, type1 );
-        pair->glyph2    = afm_atoindex( &q, limit, type1 );
-        pair->kerning.x = afm_atoi( &q, limit );
-
-        pair->kerning.y = 0;
-        if ( p[2] != 'X' )
-          pair->kerning.y = afm_atoi( &q, limit );
-
-        pair++;
-      }
-    }
-
-    /* now, sort the kern pairs according to their glyph indices */
-    qsort( afm->kern_pairs, count, sizeof(T1_Kern_Pair), compare_kern_pairs );
-
-  Exit:
-    if (error)
-      FREE( afm );
-
-    FORGET_Frame();
-    return error;
-  }
-
-
- /* find the kerning for a given glyph pair */
-  LOCAL_FUNC
-  void  T1_Get_Kerning( T1_AFM*     afm,
-                        FT_UInt     glyph1,
-                        FT_UInt     glyph2,
-                        FT_Vector*  kerning )
-  {
-    T1_Kern_Pair  *min, *mid, *max;
-    FT_ULong       index = KERN_INDEX(glyph1,glyph2);
-
-    /* simple binary search */
-    min = afm->kern_pairs;
-    max = min + afm->num_pairs-1;
-
-    while (min <= max)
-    {
-      FT_ULong  midi;
-
-      mid = min + (max-min)/2;
-      midi = KERN_INDEX(mid->glyph1,mid->glyph2);
-      if ( midi == index )
-      {
-        *kerning = mid->kerning;
-        return;
-      }
-
-      if ( midi < index ) min = mid+1;
-                     else max = mid-1;
-    }
-    kerning->x = 0;
-    kerning->y = 0;
-  }
-
--- a/src/type1z/t1afm.h
+++ /dev/null
@@ -1,50 +1,0 @@
-/***************************************************************************
- *
- * t1afm.h  - support for reading Type 1 AFM files
- *
- *
- ***************************************************************************/
-
-#ifndef T1AFM_H
-#define T1AFM_H
-
-#include <freetype/internal/ftstream.h>
-#include <freetype/internal/ftobjs.h>
-#include <freetype/internal/t1types.h>
-#include <freetype/internal/t1errors.h>
-
-/* In this version, we only read the kerning table from the */
-/* AFM file. We may add support for ligatures a bit later.. */
-
-typedef struct T1_Kern_Pair_
-{
-  FT_UInt   glyph1;
-  FT_UInt   glyph2;
-  FT_Vector kerning;
-
-} T1_Kern_Pair;
-
-
-typedef struct T1_AFM_
-{
-  FT_Int        num_pairs;
-  T1_Kern_Pair* kern_pairs;
-
-} T1_AFM;
-
-
-LOCAL_DEF
-FT_Error  T1_Read_AFM( FT_Face    face,
-                       FT_Stream  stream );
-
-LOCAL_DEF
-void  T1_Done_AFM( FT_Memory  memory,
-                   T1_AFM*    afm );
-
-LOCAL_DEF
-void  T1_Get_Kerning( T1_AFM*     afm,
-                      FT_UInt     glyph1,
-                      FT_UInt     glyph2,
-                      FT_Vector*  kerning );
-
-#endif /* T1AFM_H */
--- a/src/type1z/t1driver.c
+++ /dev/null
@@ -1,300 +1,0 @@
-/*******************************************************************
- *
- *  t1driver.c
- *
- *    High-level Type1 driver interface for FreeType 2.0
- *
- *  Copyright 1996-1998 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used,
- *  modified, and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- ******************************************************************/
-
-#include <t1driver.h>
-#include <t1gload.h>
-#include <t1load.h>
-#include <t1afm.h>
-
-#include <freetype/internal/ftdebug.h>
-#include <freetype/internal/ftstream.h>
-#include <freetype/internal/psnames.h>
-
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1driver
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Get_Interface                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Each driver can provide one or more extensions to the base         */
-  /*    FreeType API.  These can be used to access format specific         */
-  /*    features (e.g., all TrueType/OpenType resources share a common     */
-  /*    file structure and common tables which can be accessed through the */
-  /*    `sfnt' interface), or more simply generic ones (e.g., the          */
-  /*    `postscript names' interface which can be used to retrieve the     */
-  /*     PostScript name of a given glyph index).                          */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    driver    :: A handle to a driver object.                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    interface :: A string designing the interface.  Examples are       */
-  /*                 `sfnt', `post_names', `charmaps', etc.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    A typeless pointer to the extension's interface (normally a table  */
-  /*    of function pointers).  Returns NULL if the requested extension    */
-  /*    isn't available (i.e., wasn't compiled in the driver at build      */
-  /*    time).                                                             */
-  /*                                                                       */
-  static
-  FT_Module_Interface  Get_Interface( FT_Driver         driver,
-                                      const FT_String*  interface )
-  {
-    UNUSED(driver);
-    UNUSED(interface);
-    
-#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
-    if ( strcmp( (const char*)interface, "get_mm" ) == 0 )
-      return (FT_Module_Interface)T1_Get_Multi_Master;
-      
-    if ( strcmp( (const char*)interface, "set_mm_design") == 0 )
-      return (FT_Module_Interface)T1_Set_MM_Design;      
-
-    if ( strcmp( (const char*)interface, "set_mm_blend") == 0 )
-      return (FT_Module_Interface)T1_Set_MM_Blend;      
-#endif
-    return 0;
-  }
-
-
-#ifndef T1_CONFIG_OPTION_NO_AFM
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Get_Kerning                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A driver method used to return the kerning vector between two      */
-  /*    glyphs of the same face.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face        :: A handle to the source face object.                 */
-  /*                                                                       */
-  /*    left_glyph  :: The index of the left glyph in the kern pair.       */
-  /*                                                                       */
-  /*    right_glyph :: The index of the right glyph in the kern pair.      */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    kerning     :: The kerning vector.  This is in font units for      */
-  /*                   scalable formats, and in pixels for fixed-sizes     */
-  /*                   formats.                                            */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    Only horizontal layouts (left-to-right & right-to-left) are        */
-  /*    supported by this function.  Other layouts, or more sophisticated  */
-  /*    kernings are out of scope of this method (the basic driver         */
-  /*    interface is meant to be simple).                                  */
-  /*                                                                       */
-  /*    They can be implemented by format-specific interfaces.             */
-  /*                                                                       */
-  static
-  FT_Error  Get_Kerning( T1_Face     face,
-                         FT_UInt     left_glyph,
-                         FT_UInt     right_glyph,
-                         FT_Vector*  kerning )
-  {
-    T1_AFM*  afm;
-
-    kerning->x = 0;
-    kerning->y = 0;
-
-    afm = (T1_AFM*)face->afm_data;
-    if (afm)
-      T1_Get_Kerning( afm, left_glyph, right_glyph, kerning );
-
-    return T1_Err_Ok;
-  }
-#endif
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Get_Char_Index                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Uses a charmap to return a given character code's glyph index.     */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    charmap  :: A handle to the source charmap object.                 */
-  /*    charcode :: The character code.                                    */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Glyph index.  0 means `undefined character code'.                  */
-  /*                                                                       */
-  static
-  FT_UInt  Get_Char_Index( FT_CharMap  charmap,
-                           FT_Long     charcode )
-  {
-    T1_Face             face;
-    FT_UInt             result = 0;
-    PSNames_Interface*  psnames;
-
-    face = (T1_Face)charmap->face;
-    psnames = (PSNames_Interface*)face->psnames;
-    if (psnames)
-      switch (charmap->encoding)
-      {
-       /********************************************************************/
-       /*                                                                  */
-       /* Unicode encoding support                                         */
-       /*                                                                  */
-        case ft_encoding_unicode:
-          {
-            /* use the "psnames" module to synthetize the Unicode charmap */
-            result = psnames->lookup_unicode( &face->unicode_map,
-                                              (FT_ULong)charcode );
-
-            /* the function returns 0xFFFF when the Unicode charcode has */
-            /* no corresponding glyph..                                  */
-            if (result == 0xFFFF)
-              result = 0;
-            goto Exit;
-          }
-
-       /********************************************************************/
-       /*                                                                  */
-       /* Custom Type 1 encoding                                           */
-       /*                                                                  */
-        case ft_encoding_adobe_custom:
-          {
-            T1_Encoding*  encoding = &face->type1.encoding;
-            if (charcode >= encoding->code_first &&
-                charcode <= encoding->code_last)
-            {
-              result = encoding->char_index[charcode];
-            }
-            goto Exit;
-          }
-
-       /********************************************************************/
-       /*                                                                  */
-       /* Adobe Standard & Expert encoding support                         */
-       /*                                                                  */
-       default:
-         if (charcode < 256)
-         {
-           FT_UInt      code;
-           FT_Int       n;
-           const char*  glyph_name;
-
-           code = psnames->adobe_std_encoding[charcode];
-           if (charmap->encoding == ft_encoding_adobe_expert)
-             code = psnames->adobe_expert_encoding[charcode];
-
-           glyph_name = psnames->adobe_std_strings(code);
-           if (!glyph_name) break;
-
-           for ( n = 0; n < face->type1.num_glyphs; n++ )
-           {
-             const char*  gname = face->type1.glyph_names[n];
-
-             if ( gname && gname[0] == glyph_name[0] &&
-                  strcmp( gname, glyph_name ) == 0 )
-             {
-               result = n;
-               break;
-             }
-           }
-         }
-      }
-  Exit:
-    return result;
-  }
-
-
-  const  FT_Driver_Class  t1z_driver_class =
-  {
-    {
-      ft_module_font_driver | ft_module_driver_scalable,
-      sizeof( FT_DriverRec ),
-      
-      "type1z",
-      0x10000,
-      0x20000,
-  
-      0,   /* format interface */
-  
-      (FT_Module_Constructor)           T1_Init_Driver,
-      (FT_Module_Destructor)            T1_Done_Driver,
-      (FT_Module_Requester)             Get_Interface,
-    },
-
-    sizeof( T1_FaceRec ),
-    sizeof( T1_SizeRec ),
-    sizeof( T1_GlyphSlotRec ),
-
-    (FTDriver_initFace)             T1_Init_Face,
-    (FTDriver_doneFace)             T1_Done_Face,
-    (FTDriver_initSize)             0,
-    (FTDriver_doneSize)             0,
-    (FTDriver_initGlyphSlot)        0,
-    (FTDriver_doneGlyphSlot)        0,
-
-    (FTDriver_setCharSizes)         0,
-    (FTDriver_setPixelSizes)        0,
-    (FTDriver_loadGlyph)            T1_Load_Glyph,
-    (FTDriver_getCharIndex)         Get_Char_Index,
-
-#ifdef T1_CONFIG_OPTION_NO_AFM
-    (FTDriver_getKerning)           0,
-    (FTDriver_attachFile)           0,
-#else
-    (FTDriver_getKerning)           Get_Kerning,
-    (FTDriver_attachFile)           T1_Read_AFM,
-#endif
-    (FTDriver_getAdvances)          0
-
-  };
-
-
-  /******************************************************************/
-  /*                                                                */
-  /*  <Function> Get_FreeType_Driver_Interface                      */
-  /*                                                                */
-  /*  <Description>                                                 */
-  /*     This function is used when compiling the TrueType driver   */
-  /*     as a shared library (.DLL or .so). It will be used by the  */
-  /*     high-level library of FreeType to retrieve the address of  */
-  /*     the driver's generic interface.                            */
-  /*                                                                */
-  /*     It shouldn't be implemented in a static build, as each     */
-  /*     driver must have the same function as an exported entry    */
-  /*     point.                                                     */
-  /*                                                                */
-  /*  <Return>                                                      */
-  /*     address of TrueType's driver generic interface. The        */
-  /*     forma-specific interface can then be retrieved through     */
-  /*     the method interface->get_format_interface..               */
-  /*                                                                */
-
-#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
-
-  EXPORT_FUNC(const FT_Driver_Class*)  getDriverClass( void )
-  {
-    return &t1z_driver_class;
-  }
-
-#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
-
-
--- a/src/type1z/t1driver.h
+++ /dev/null
@@ -1,26 +1,0 @@
-/*******************************************************************
- *
- *  t1driver.h
- *
- *    High-level Type1 driver interface for FreeType 2.0
- *
- *  Copyright 1996-1998 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used,
- *  modified, and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- ******************************************************************/
-
-#ifndef T1DRIVER_H
-#define T1DRIVER_H
-
-#include <freetype/internal/ftdriver.h>
-
-  FT_EXPORT_VAR(const  FT_Driver_Class)  t1z_driver_class;
-
-#endif /* T1DRIVER_H */
-
--- a/src/type1z/t1gload.c
+++ /dev/null
@@ -1,1382 +1,0 @@
-/*******************************************************************
- *
- *  t1gload.c                                                   1.0
- *
- *    Type1 Glyph Loader.
- *
- *  Copyright 1996-1999 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used
- *  modified and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- ******************************************************************/
-
-#include <t1gload.h>
-#include <freetype/internal/ftdebug.h>
-#include <freetype/internal/ftstream.h>
-
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1gload
-
-  typedef enum T1_Operator_
-  {
-    op_none = 0,
-    op_endchar,
-    op_hsbw,
-    op_seac,
-    op_sbw,
-    op_closepath,
-    op_hlineto,
-    op_hmoveto,
-    op_hvcurveto,
-    op_rlineto,
-    op_rmoveto,
-    op_rrcurveto,
-    op_vhcurveto,
-    op_vlineto,
-    op_vmoveto,
-    op_dotsection,
-    op_hstem,
-    op_hstem3,
-    op_vstem,
-    op_vstem3,
-    op_div,
-    op_callothersubr,
-    op_callsubr,
-    op_pop,
-    op_return,
-    op_setcurrentpoint,
-
-    op_max    /* never remove this one */
-
-  } T1_Operator;
-
-  static const FT_Int  t1_args_count[ op_max ] =
-  {
-    0, /* none */
-    0, /* endchar */
-    2, /* hsbw */
-    5, /* seac */
-    4, /* sbw */
-    0, /* closepath */
-    1, /* hlineto */
-    1, /* hmoveto */
-    4, /* hvcurveto */
-    2, /* rlineto */
-    2, /* rmoveto */
-    6, /* rrcurveto */
-    4, /* vhcurveto */
-    1, /* vlineto */
-    1, /* vmoveto */
-    0, /* dotsection */
-    2, /* hstem */
-    6, /* hstem3 */
-    2, /* vstem */
-    6, /* vstem3 */
-    2, /* div */
-   -1, /* callothersubr */
-    1, /* callsubr */
-    0, /* pop */
-    0, /* return */
-    2  /* setcurrentpoint */
-  };
-
-
-  /**********************************************************************/
-  /**********************************************************************/
-  /**********************************************************************/
-  /**********                                                   *********/
-  /**********                                                   *********/
-  /**********           GENERIC CHARSTRINGS PARSING             *********/
-  /**********                                                   *********/
-  /**********                                                   *********/
-  /**********************************************************************/
-  /**********************************************************************/
-  /**********************************************************************/
-
-/*********************************************************************
- *
- * <Function>
- *    T1_Init_Builder
- *
- * <Description>
- *    Initialise a given glyph builder.
- *
- * <Input>
- *    builder :: glyph builder to initialise
- *    face    :: current face object
- *    size    :: current size object
- *    glyph   :: current glyph object
- *
- *********************************************************************/
-
-  LOCAL_FUNC
-  void  T1_Init_Builder( T1_Builder*   builder,
-                         T1_Face       face,
-                         T1_Size       size,
-                         T1_GlyphSlot  glyph )
-  {
-    builder->path_begun  = 0;
-    builder->load_points = 1;
-
-    builder->face   = face;
-    builder->glyph  = glyph;
-    builder->memory = face->root.memory;
-
-    if (glyph)
-    {
-      FT_GlyphLoader*  loader = glyph->root.loader;
-      
-      builder->loader = loader;
-      builder->current = &loader->current.outline;
-      builder->base    = &loader->base.outline;
-
-      FT_GlyphLoader_Rewind(loader);
-    }
-
-    if (size)
-    {
-      builder->scale_x = size->root.metrics.x_scale;
-      builder->scale_y = size->root.metrics.y_scale;
-    }
-
-    builder->pos_x = 0;
-    builder->pos_y = 0;
-
-    builder->left_bearing.x = 0;
-    builder->left_bearing.y = 0;
-    builder->advance.x      = 0;
-    builder->advance.y      = 0;
-  }
-
-
-/*********************************************************************
- *
- * <Function>
- *    T1_Done_Builder
- *
- * <Description>
- *    Finalise a given glyph builder. Its content can still be
- *    used after the call, but the function saves important information
- *    within the corresponding glyph slot.
- *
- * <Input>
- *    builder :: glyph builder to initialise
- *
- *********************************************************************/
-
-  LOCAL_FUNC
-  void T1_Done_Builder( T1_Builder*  builder )
-  {
-    T1_GlyphSlot  glyph = builder->glyph;
-
-    if (glyph)
-      glyph->root.outline = *builder->base;
-  }
-
-
-
-/*********************************************************************
- *
- * <Function>
- *    T1_Init_Decoder
- *
- * <Description>
- *    Initialise a given Type 1 decoder for parsing
- *
- * <Input>
- *    decoder :: Type 1 decoder to initialise
- *    funcs   :: hinter functions interface
- *
- *********************************************************************/
-
-  LOCAL_FUNC
-  void  T1_Init_Decoder( T1_Decoder* decoder )
-  {
-    decoder->top              = 0;
-    decoder->zone             = 0;
-    decoder->flex_state       = 0;
-    decoder->num_flex_vectors = 0;
-    decoder->blend            = 0;
-
-    /* Clear loader */
-    MEM_Set( &decoder->builder, 0, sizeof(decoder->builder) );
-  }
-
-
-  /* check that there is enough room for "count" more points */
-  static
-  FT_Error  check_points( T1_Builder*  builder,
-                          FT_Int       count )
-  {
-    return FT_GlyphLoader_Check_Points( builder->loader, count, 0 );
-  }
-
-
-  /* add a new point, do not check room */
-  static
-  void  add_point( T1_Builder*  builder,
-                   FT_Pos       x,
-                   FT_Pos       y,
-                   FT_Byte      flag )
-  {
-    FT_Outline*  outline = builder->current;
-
-    if (builder->load_points)
-    {
-      FT_Vector*  point   = outline->points + outline->n_points;
-      FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;
-
-      point->x = x;
-      point->y = y;
-      *control = ( flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic );
-
-      builder->last = *point;
-    }
-
-    outline->n_points++;
-  }
-
-
-  /* check room for a new on-curve point, then add it */
-  static
-  FT_Error  add_point1( T1_Builder*  builder,
-                        FT_Pos       x,
-                        FT_Pos       y )
-  {
-    FT_Error  error;
-
-    error = check_points(builder,1);
-    if (!error)
-      add_point( builder, x, y, 1 );
-
-    return error;
-  }
-
-
-  /* check room for a new contour, then add it */
-  static
-  FT_Error  add_contour( T1_Builder*  builder )
-  {
-    FT_Outline*  outline = builder->current;
-    FT_Error     error;
-
-    if (!builder->load_points)
-    {
-      outline->n_contours++;
-      return FT_Err_Ok;
-    }
-
-    /* realloc contours array if necessary */
-    error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 );
-    if (!error)
-    {
-      if (outline->n_contours > 0)
-        outline->contours[ outline->n_contours-1 ] = outline->n_points-1;
-        
-      outline->n_contours++;
-    }
-    return error;
-  }
-
-  /* if a path was begun, add its first on-curve point */
-  static
-  FT_Error  start_point( T1_Builder*  builder,
-                         FT_Pos       x,
-                         FT_Pos       y )
-  {
-    /* test wether we're building a new contour */
-    if (!builder->path_begun)
-    {
-      FT_Error  error;
-
-      builder->path_begun = 1;
-      error = add_contour( builder );
-      if (error) return error;
-    }
-    return add_point1( builder, x, y );
-  }
-
-
-  /* close the current contour */
-  static
-  void  close_contour( T1_Builder*  builder )
-  {
-    FT_Outline*  outline = builder->current;
-
-    if ( outline->n_contours > 0 )
-      outline->contours[outline->n_contours-1] = outline->n_points-1;
-  }
-
-
-/*********************************************************************
- *
- * <Function>
- *    lookup_glyph_by_stdcharcode
- *
- * <Description>
- *    Lookup a given glyph by its StandardEncoding charcode. Used
- *    to implement the SEAC Type 1 operator.
- *
- * <Input>
- *    face     :: current face object
- *    charcode :: charcode to look for
- *
- * <Return>
- *    glyph index in font face. Returns -1 if the corresponding
- *    glyph wasn't found.
- *
- *********************************************************************/
-
-  static
-  FT_Int    lookup_glyph_by_stdcharcode( T1_Face  face,
-                                         FT_Int   charcode )
-  {
-    FT_Int              n;
-    const FT_String*    glyph_name;
-    PSNames_Interface*  psnames = (PSNames_Interface*)face->psnames;
-
-    /* check range of standard char code */
-    if (charcode < 0 || charcode > 255)
-      return -1;
-
-    glyph_name = psnames->adobe_std_strings(
-                    psnames->adobe_std_encoding[charcode]);
-
-    for ( n = 0; n < face->type1.num_glyphs; n++ )
-    {
-      FT_String*  name = (FT_String*)face->type1.glyph_names[n];
-
-      if ( name && strcmp(name,glyph_name) == 0 )
-        return n;
-    }
-
-    return -1;
-  }
-
-
-
-/*********************************************************************
- *
- * <Function>
- *    t1operator_seac
- *
- * <Description>
- *    Implements the "seac" Type 1 operator for a Type 1 decoder
- *
- * <Input>
- *    decoder  :: current Type 1 decoder
- *    asb      :: accent's side bearing
- *    adx      :: horizontal position of accent
- *    ady      :: vertical position of accent
- *    bchar    :: base character's StandardEncoding charcode
- *    achar    :: accent character's StandardEncoding charcode
- *
- * <Return>
- *    Error code. 0 means success.
- *
- *********************************************************************/
-
-  static
-  FT_Error  t1operator_seac( T1_Decoder*  decoder,
-                             FT_Pos       asb,
-                             FT_Pos       adx,
-                             FT_Pos       ady,
-                             FT_Int       bchar,
-                             FT_Int       achar )
-  {
-    FT_Error     error;
-    FT_Int       bchar_index, achar_index, n_base_points;
-    FT_Outline*  cur  = decoder->builder.current;
-    FT_Outline*  base = decoder->builder.base;
-    FT_Vector    left_bearing, advance;
-    T1_Face      face  = decoder->builder.face;
-    T1_Font*     type1 = &face->type1;
-
-    bchar_index = lookup_glyph_by_stdcharcode( face, bchar );
-    achar_index = lookup_glyph_by_stdcharcode( face, achar );
-
-    if ( bchar_index < 0 || achar_index < 0 )
-    {
-      FT_ERROR(( "t1operator_seac: invalid seac character code arguments\n" ));
-      return T1_Err_Syntax_Error;
-    }
-
-    /* if we are trying to load a composite glyph, do not load the */
-    /* accent character and return the array of subglyphs.         */
-    if ( decoder->builder.no_recurse )
-    {
-
-      FT_GlyphSlot     glyph = (FT_GlyphSlot)decoder->builder.glyph;
-      FT_GlyphLoader*  loader = glyph->loader;
-      FT_SubGlyph*     subg;
-
-      /* reallocate subglyph array if necessary */
-      error = FT_GlyphLoader_Check_Subglyphs( loader, 2 );
-      if (error) goto Exit;
-      
-      subg = loader->current.subglyphs;
-
-      /* subglyph 0 = base character */
-      subg->index = bchar_index;
-      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
-                    FT_SUBGLYPH_FLAG_USE_MY_METRICS;
-      subg->arg1  = 0;
-      subg->arg2  = 0;
-      subg++;
-
-      /* subglyph 1 = accent character */
-      subg->index = achar_index;
-      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
-      subg->arg1  = adx - asb;
-      subg->arg2  = ady;
-
-      /* set up remaining glyph fields */
-      glyph->num_subglyphs = 2;
-      glyph->format        = ft_glyph_format_composite;
-      
-      loader->current.num_subglyphs = 2;
-    }
-
-    /* First load `bchar' in builder */
-    /* now load the unscaled outline */
-    
-    FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
-
-    error = T1_Parse_CharStrings( decoder,
-                                  type1->charstrings    [bchar_index],
-                                  type1->charstrings_len[bchar_index],
-                                  type1->num_subrs,
-                                  type1->subrs,
-                                  type1->subrs_len );
-    if ( error ) goto Exit;
-
-    n_base_points = cur->n_points;
-
-    {
-      /* save the left bearing and width of the base character */
-      /* as they will be erased by the next load.              */
-
-      left_bearing = decoder->builder.left_bearing;
-      advance      = decoder->builder.advance;
-
-      decoder->builder.left_bearing.x = 0;
-      decoder->builder.left_bearing.y = 0;
-
-      /* Now load `achar' on top of */
-      /* the base outline           */
-      error = T1_Parse_CharStrings( decoder,
-                                    type1->charstrings    [achar_index],
-                                    type1->charstrings_len[achar_index],
-                                    type1->num_subrs,
-                                    type1->subrs,
-                                    type1->subrs_len );
-      if ( error ) return error;
-
-      /* restore the left side bearing and   */
-      /* advance width of the base character */
-
-      decoder->builder.left_bearing = left_bearing;
-      decoder->builder.advance      = advance;
-
-      /* Finally, move the accent */
-      if ( decoder->builder.load_points )
-      {
-        FT_Outline  dummy;
-        
-        dummy.n_points = base->n_points - n_base_points;
-        dummy.points   = base->points   + n_base_points;
-        FT_Outline_Translate( &dummy, adx - asb, ady );
-      }
-    }
-  Exit:
-    return error;
-  }
-
-
-/*********************************************************************
- *
- * <Function>
- *    T1_Parse_CharStrings
- *
- * <Description>
- *    Parses a given Type 1 charstrings program
- *
- * <Input>
- *    decoder          :: current Type 1 decoder
- *    charstring_base  :: base of the charstring stream
- *    charstring_len   :: length in bytes of the charstring stream
- *    num_subrs        :: number of sub-routines
- *    subrs_base       :: array of sub-routines addresses
- *    subrs_len        :: array of sub-routines lengths
- *
- * <Return>
- *    Error code. 0 means success.
- *
- *********************************************************************/
-
-#define USE_ARGS(n)  top -= n; if (top < decoder->stack) goto Stack_Underflow
-
-  LOCAL_FUNC
-  FT_Error   T1_Parse_CharStrings( T1_Decoder*  decoder,
-                                   FT_Byte*     charstring_base,
-                                   FT_Int       charstring_len,
-                                   FT_Int       num_subrs,
-                                   FT_Byte**    subrs_base,
-                                   FT_Int*      subrs_len )
-  {
-    FT_Error            error;
-    T1_Decoder_Zone*    zone;
-    FT_Byte*            ip;
-    FT_Byte*            limit;
-    T1_Builder*         builder = &decoder->builder;
-    FT_Outline*         outline;
-    FT_Pos              x, y;
-
-    /* First of all, initialise the decoder */
-    decoder->top  = decoder->stack;
-    decoder->zone = decoder->zones;
-    zone          = decoder->zones;
-
-    builder->path_begun  = 0;
-
-    zone->base           = charstring_base;
-    limit = zone->limit  = charstring_base + charstring_len;
-    ip    = zone->cursor = zone->base;
-
-    error   = T1_Err_Ok;
-    outline = builder->current;
-
-    x = builder->pos_x;
-    y = builder->pos_y;
-
-    /* now, execute loop */
-    while ( ip < limit )
-    {
-      FT_Int*      top      = decoder->top;
-      T1_Operator  op       = op_none;
-      FT_Long      value    = 0;
-
-      /********************************************************************/
-      /*                                                                  */
-      /* Decode operator or operand                                       */
-      /*                                                                  */
-      /*                                                                  */
-
-      /* First of all, decompress operator or value */
-      switch (*ip++)
-      {
-        case 1:  op = op_hstem;     break;
-
-        case 3:  op = op_vstem;     break;
-        case 4:  op = op_vmoveto;   break;
-        case 5:  op = op_rlineto;   break;
-        case 6:  op = op_hlineto;   break;
-        case 7:  op = op_vlineto;   break;
-        case 8:  op = op_rrcurveto; break;
-        case 9:  op = op_closepath; break;
-        case 10: op = op_callsubr;  break;
-        case 11: op = op_return;    break;
-
-        case 13: op = op_hsbw;      break;
-        case 14: op = op_endchar;   break;
-
-        case 21: op = op_rmoveto;   break;
-        case 22: op = op_hmoveto;   break;
-
-        case 30: op = op_vhcurveto; break;
-        case 31: op = op_hvcurveto; break;
-
-        case 12:
-          {
-            if (ip > limit)
-            {
-              FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+EOF)\n" ));
-              goto Syntax_Error;
-            }
-
-            switch (*ip++)
-            {
-              case 0:  op = op_dotsection;      break;
-              case 1:  op = op_vstem3;          break;
-              case 2:  op = op_hstem3;          break;
-              case 6:  op = op_seac;            break;
-              case 7:  op = op_sbw;             break;
-              case 12: op = op_div;             break;
-              case 16: op = op_callothersubr;   break;
-              case 17: op = op_pop;             break;
-              case 33: op = op_setcurrentpoint; break;
-
-              default:
-                FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+%d)\n",
-                         ip[-1] ));
-                goto Syntax_Error;
-            }
-          }
-          break;
-
-        case 255:    /* four bytes integer */
-          {
-            if (ip+4 > limit)
-            {
-              FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
-              goto Syntax_Error;
-            }
-
-            value = ((long)ip[0] << 24) |
-                    ((long)ip[1] << 16) |
-                    ((long)ip[2] << 8)  |
-                           ip[3];
-            ip += 4;
-          }
-          break;
-
-        default:
-          if (ip[-1] >= 32)
-          {
-            if (ip[-1] < 247)
-              value = (long)ip[-1] - 139;
-            else
-            {
-              if (++ip > limit)
-              {
-                FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
-                goto Syntax_Error;
-              }
-
-              if (ip[-2] < 251)
-                value =  ((long)(ip[-2]-247) << 8) + ip[-1] + 108;
-              else
-                value = -((((long)ip[-2]-251) << 8) + ip[-1] + 108 );
-            }
-          }
-          else
-          {
-            FT_ERROR(( "T1.Parse_CharStrings : invalid byte (%d)\n",
-                     ip[-1] ));
-            goto Syntax_Error;
-          }
-      }
-
-      /********************************************************************/
-      /*                                                                  */
-      /*  Push value on stack, or process operator                        */
-      /*                                                                  */
-      /*                                                                  */
-      if ( op == op_none )
-      {
-        if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
-        {
-          FT_ERROR(( "T1.Parse_CharStrings : Stack overflow !!\n" ));
-          goto Syntax_Error;
-        }
-
-        FT_TRACE4(( " %ld", value ));
-        *top++       = value;
-        decoder->top = top;
-      }
-      else if ( op == op_callothersubr )  /* callothersubr */
-      {
-        FT_TRACE4(( " callothersubr" ));
-        if ( top - decoder->stack < 2 )
-          goto Stack_Underflow;
-
-        top -= 2;
-        switch ( top[1] )
-        {
-          case 1: /* start flex feature ---------------------- */
-            {
-              if ( top[0] != 0 ) goto Unexpected_OtherSubr;
-
-              decoder->flex_state        = 1;
-              decoder->num_flex_vectors  = 0;
-              if ( start_point(builder, x, y) ||
-                   check_points(builder,6) ) goto Memory_Error;
-            }
-            break;
-
-          case 2: /* add flex vectors ------------------------ */
-            {
-              FT_Int      index;
-
-              if ( top[0] != 0 ) goto Unexpected_OtherSubr;
-
-              /* note that we should not add a point for index 0 */
-              /* this will move our current position to the flex */
-              /* point without adding any point to the outline   */
-              index = decoder->num_flex_vectors++;
-              if (index > 0 && index < 7)
-                add_point( builder,
-                           x,
-                           y,
-                           (FT_Byte)( index==3 || index==6 ) );
-            }
-            break;
-
-          case 0: /* end flex feature ------------------------- */
-            {
-              if ( top[0] != 3 ) goto Unexpected_OtherSubr;
-
-              if ( decoder->flex_state       == 0 ||
-                   decoder->num_flex_vectors != 7 )
-              {
-                FT_ERROR(( "T1.Parse_CharStrings: unexpected flex end\n" ));
-                goto Syntax_Error;
-              }
-
-              /* now consume the remaining "pop pop setcurpoint" */
-              if ( ip+6 > limit ||
-                   ip[0] != 12  || ip[1] != 17 || /* pop */
-                   ip[2] != 12  || ip[3] != 17 || /* pop */
-                   ip[4] != 12  || ip[5] != 33 )  /* setcurpoint */
-              {
-                FT_ERROR(( "T1.Parse_CharStrings: invalid flex charstring\n" ));
-                goto Syntax_Error;
-              }
-
-              ip += 6;
-              decoder->flex_state = 0;
-              break;
-            }
-
-          case 3:  /* change hints ---------------------------- */
-            {
-              if ( top[0] != 1 ) goto Unexpected_OtherSubr;
-
-              /* eat the following "pop" */
-              if (ip+2 > limit)
-              {
-                FT_ERROR(( "T1.Parse_CharStrings: invalid escape (12+%d)\n",
-                         ip[-1] ));
-                goto Syntax_Error;
-              }
-
-              if (ip[0] != 12 || ip[1] != 17)
-              {
-                FT_ERROR(( "T1.Parse_CharStrings: 'pop' expected, found (%d %d)\n",
-                         ip[0], ip[1] ));
-                goto Syntax_Error;
-              }
-              ip += 2;
-              break;;
-            }
-
-          case 12:
-          case 13:
-            {
-              /* counter control hints, clear stack */
-              top = decoder->stack;
-              break;
-            }
-          
-          case 14:
-          case 15:
-          case 16:
-          case 17:
-          case 18: /* multiple masters */
-            {
-              T1_Blend*  blend = decoder->blend;
-              FT_UInt    num_points, nn, mm;
-              FT_Int*    delta;
-              FT_Int*    values;
-              
-              if (!blend)
-              {
-                FT_ERROR(( "T1.Parse_CharStrings: unexpected multiple masters operator !!\n" ));
-                goto Syntax_Error;
-              }
-              
-              num_points = top[1] - 13 + (top[1] == 18);
-              if (top[0] != num_points*blend->num_designs)
-              {
-                FT_ERROR(( "T1.Parse_CharStrings: incorrect number of mm arguments\n" ));
-                goto Syntax_Error;
-              }
-              
-              top       -= blend->num_designs*num_points;
-              if (top < decoder->stack)
-                goto Stack_Underflow;
-
-              /* we want to compute:                                   */
-              /*                                                       */
-              /*  a0*w0 + a1*w1 + ... + ak*wk                          */
-              /*                                                       */
-              /* but we only have the a0, a1-a0, a2-a0, .. ak-a0       */
-              /* however, given that w0 + w1 + ... + wk == 1, we can   */
-              /* rewrite it easily as:                                 */
-              /*                                                       */
-              /*  a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk       */
-              /*                                                       */
-              /* where k == num_designs-1                              */
-              /*                                                       */
-              /* I guess that's why it's written in this "compact"     */
-              /* form..                                                */
-              /*                                                       */
-              /*                                                       */
-              delta  = top + num_points;
-              values = top;
-              for ( nn = 0; nn < num_points; nn++ )
-              {
-                FT_Int  x = values[0];
-                for ( mm = 1; mm < blend->num_designs; mm++ )
-                  x += FT_MulFix( *delta++, blend->weight_vector[mm] );
-
-                *values++ = x;
-              }
-              /* note that "top" will be incremented later by calls to "pop" */
-              break;
-            }
-          
-          default:
-          Unexpected_OtherSubr:
-            FT_ERROR(( "T1.Parse_CharStrings: invalid othersubr [%d %d]!!\n",
-                       top[0], top[1] ));
-            goto Syntax_Error;
-        }
-        decoder->top = top;
-      }
-      else  /* general operator */
-      {
-        FT_Int  num_args = t1_args_count[op];
-
-        if ( top - decoder->stack < num_args )
-          goto Stack_Underflow;
-
-        top -= num_args;
-
-        switch (op)
-        {
-          case op_endchar: /*************************************************/
-          {
-            FT_TRACE4(( " endchar" ));
-            close_contour( builder );
-
-            /* add current outline to the glyph slot */
-            FT_GlyphLoader_Add( builder->loader );
-
-            /* return now !! */
-            FT_TRACE4(( "\n\n" ));
-            return T1_Err_Ok;
-          }
-
-
-          case op_hsbw: /****************************************************/
-          {
-            FT_TRACE4(( " hsbw" ));
-            builder->left_bearing.x += top[0];
-            builder->advance.x       = top[1];
-            builder->advance.y       = 0;
-
-            builder->last.x = x = top[0];
-            builder->last.y = y = 0;
-
-            /* the "metrics_only" indicates that we only want to compute */
-            /* the glyph's metrics (lsb + advance width), not load the   */
-            /* rest of it.. so exit immediately                          */
-            if (builder->metrics_only)
-              return T1_Err_Ok;
-
-            break;
-          }
-
-
-          case op_seac: /****************************************************/
-            /* return immediately after the processing */
-            return t1operator_seac( decoder, top[0], top[1],
-                                             top[2], top[3], top[4] );
-
-          case op_sbw:  /****************************************************/
-          {
-            FT_TRACE4(( " sbw" ));
-            builder->left_bearing.x += top[0];
-            builder->left_bearing.y += top[1];
-            builder->advance.x       = top[2];
-            builder->advance.y       = top[3];
-
-            builder->last.x = x = top[0];
-            builder->last.y = y = top[1];
-
-            /* the "metrics_only" indicates that we only want to compute */
-            /* the glyph's metrics (lsb + advance width), not load the   */
-            /* rest of it.. so exit immediately                          */
-            if (builder->metrics_only)
-              return T1_Err_Ok;
-
-            break;
-          }
-
-
-          case op_closepath:  /**********************************************/
-          {
-            FT_TRACE4(( " closepath" ));
-            close_contour( builder );
-            builder->path_begun = 0;
-          }
-          break;
-
-
-          case op_hlineto:  /************************************************/
-          {
-            FT_TRACE4(( " hlineto" ));
-            if ( start_point( builder, x, y ) ) goto Memory_Error;
-
-            x += top[0];
-            goto Add_Line;
-          }
-
-
-          case op_hmoveto:  /************************************************/
-          {
-            FT_TRACE4(( " hmoveto" ));
-            x += top[0];
-            break;
-          }
-
-
-          case op_hvcurveto:  /**********************************************/
-          {
-            FT_TRACE4(( " hvcurveto" ));
-            if ( start_point( builder, x, y ) ||
-                 check_points( builder, 3 )   ) goto Memory_Error;
-
-            x += top[0];
-            add_point( builder, x, y, 0 );
-            x += top[1];
-            y += top[2];
-            add_point( builder, x, y, 0 );
-            y += top[3];
-            add_point( builder, x, y, 1 );
-            break;
-          }
-
-
-          case op_rlineto: /*************************************************/
-          {
-            FT_TRACE4(( " rlineto" ));
-            if ( start_point( builder, x, y ) ) goto Memory_Error;
-
-            x += top[0];
-            y += top[1];
-   Add_Line:
-            if (add_point1( builder, x, y )) goto Memory_Error;
-            break;
-          }
-
-
-          case op_rmoveto: /*************************************************/
-          {
-            FT_TRACE4(( " rmoveto" ));
-            x += top[0];
-            y += top[1];
-            break;
-          }
-
-          case op_rrcurveto: /***********************************************/
-          {
-            FT_TRACE4(( " rcurveto" ));
-            if ( start_point( builder, x, y ) ||
-                 check_points( builder, 3 )   ) goto Memory_Error;
-
-            x += top[0];
-            y += top[1];
-            add_point( builder, x, y, 0 );
-
-            x += top[2];
-            y += top[3];
-            add_point( builder, x, y, 0 );
-
-            x += top[4];
-            y += top[5];
-            add_point( builder, x, y, 1 );
-            break;
-          }
-
-
-          case op_vhcurveto:  /**********************************************/
-          {
-            FT_TRACE4(( " vhcurveto" ));
-            if ( start_point( builder, x, y ) ||
-                 check_points( builder, 3 )   ) goto Memory_Error;
-
-            y += top[0];
-            add_point( builder, x, y, 0 );
-            x += top[1];
-            y += top[2];
-            add_point( builder, x, y, 0 );
-            x += top[3];
-            add_point( builder, x, y, 1 );
-            break;
-          }
-
-
-          case op_vlineto:  /************************************************/
-            {
-              FT_TRACE4(( " vlineto" ));
-              if ( start_point( builder, x, y ) ) goto Memory_Error;
-
-              y += top[0];
-              goto Add_Line;
-            }
-
-
-          case op_vmoveto:  /************************************************/
-            {
-              FT_TRACE4(( " vmoveto" ));
-              y += top[0];
-              break;
-            }
-
-
-          case op_div:  /****************************************************/
-          {
-            FT_TRACE4(( " div" ));
-            if (top[1])
-            {
-              *top = top[0] / top[1];
-              ++top;
-            }
-            else
-            {
-              FT_ERROR(( "T1.Parse_CharStrings : division by 0\n" ));
-              goto Syntax_Error;
-            }
-            break;
-          }
-
-
-          case op_callsubr:  /***********************************************/
-          {
-            FT_Int  index;
-
-            FT_TRACE4(( " callsubr" ));
-            index = top[0];
-            if ( index < 0 || index >= num_subrs )
-            {
-              FT_ERROR(( "T1.Parse_CharStrings : invalid subrs index\n" ));
-              goto Syntax_Error;
-            }
-
-            if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
-            {
-              FT_ERROR(( "T1.Parse_CharStrings : too many nested subrs\n" ));
-              goto Syntax_Error;
-            }
-
-            zone->cursor = ip;  /* save current instruction pointer */
-
-            zone++;
-            zone->base    = subrs_base[index];
-            zone->limit   = zone->base + subrs_len[index];
-            zone->cursor  = zone->base;
-
-            if (!zone->base)
-            {
-              FT_ERROR(( "T1.Parse_CharStrings : invoking empty subrs !!\n" ));
-              goto Syntax_Error;
-            }
-
-            decoder->zone = zone;
-            ip            = zone->base;
-            limit         = zone->limit;
-            break;
-          }
-
-
-          case op_pop:  /****************************************************/
-          {
-            FT_TRACE4(( " pop" ));
-            /* theorically, the arguments are already on the stack */
-            top++;
-            break;
-          }
-
-
-          case op_return:  /************************************************/
-          {
-            FT_TRACE4(( " return" ));
-            if ( zone <= decoder->zones )
-            {
-              FT_ERROR(( "T1.Parse_CharStrings : unexpected return\n" ));
-              goto Syntax_Error;
-            }
-
-            zone--;
-            ip            = zone->cursor;
-            limit         = zone->limit;
-            decoder->zone = zone;
-            break;
-          }
-
-          case op_dotsection:  /*********************************************/
-          {
-            FT_TRACE4(( " dotsection" ));
-            break;
-          }
-
-          case op_hstem:  /**************************************************/
-          {
-            FT_TRACE4(( " hstem" ));
-            break;
-          }
-
-          case op_hstem3:  /*************************************************/
-          {
-            FT_TRACE4(( " hstem3" ));
-            break;
-          }
-
-          case op_vstem:  /**************************************************/
-          {
-            FT_TRACE4(( " vstem" ));
-            break;
-          }
-
-          case op_vstem3:  /*************************************************/
-          {
-            FT_TRACE4(( " vstem3" ));
-            break;
-          }
-
-          case op_setcurrentpoint:  /*****************************************/
-          {
-            FT_TRACE4(( " setcurrentpoint" ));
-            FT_ERROR(( "T1.Parse_CharStrings : unexpected SETCURRENTPOINT\n" ));
-            goto Syntax_Error;
-          }
-
-          default:
-            FT_ERROR(( "T1.Parse_CharStrings : unhandled opcode %d\n", op ));
-            goto Syntax_Error;
-        }
-
-        decoder->top = top;
-
-      } /* general operator processing */
-
-
-    } /* while ip < limit */
-    FT_TRACE4(( "..end..\n\n" ));
-    return error;
-
-  Syntax_Error:
-    return T1_Err_Syntax_Error;
-
-  Stack_Underflow:
-    return T1_Err_Stack_Underflow;
-
-  Memory_Error:
-    return builder->error;
-  }
-
-
-
-  /**********************************************************************/
-  /**********************************************************************/
-  /**********************************************************************/
-  /**********                                                   *********/
-  /**********                                                   *********/
-  /**********           COMPUTE THE MAXIMUM ADVANCE WIDTH       *********/
-  /**********                                                   *********/
-  /**********   The following code is in charge of computing    *********/
-  /**********   the maximum advance width of the font. It       *********/
-  /**********   quickly process each glyph charstring to        *********/
-  /**********   extract the value from either a "sbw" or "seac" *********/
-  /**********   operator.                                       *********/
-  /**********                                                   *********/
-  /**********************************************************************/
-  /**********************************************************************/
-  /**********************************************************************/
-
-  LOCAL_FUNC
-  FT_Error  T1_Compute_Max_Advance( T1_Face  face,
-                                    FT_Int  *max_advance )
-  {
-    FT_Error    error;
-    T1_Decoder  decoder;
-    FT_Int      glyph_index;
-    T1_Font*    type1 = &face->type1;
-
-    *max_advance = 0;
-
-    /* Initialise load decoder */
-    T1_Init_Decoder( &decoder );
-    T1_Init_Builder( &decoder.builder, face, 0, 0 );
-
-    decoder.blend                = face->blend;
-    decoder.builder.metrics_only = 1;
-    decoder.builder.load_points  = 0;
-
-    /* For each glyph, parse the glyph charstring and extract */
-    /* the advance width..                                    */
-    for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
-    {
-      /* now get load the unscaled outline */
-      error = T1_Parse_CharStrings( &decoder,
-                                    type1->charstrings    [glyph_index],
-                                    type1->charstrings_len[glyph_index],
-                                    type1->num_subrs,
-                                    type1->subrs,
-                                    type1->subrs_len );
-      /* ignore the error if one occured - skip to next glyph */
-    }
-
-    *max_advance = decoder.builder.advance.x;
-    return T1_Err_Ok;
-  }
-
-
-  /**********************************************************************/
-  /**********************************************************************/
-  /**********************************************************************/
-  /**********                                                   *********/
-  /**********                                                   *********/
-  /**********              UNHINTED GLYPH LOADER                *********/
-  /**********                                                   *********/
-  /**********   The following code is in charge of loading a    *********/
-  /**********   single outline. It completely ignores hinting   *********/
-  /**********   and is used when FT_LOAD_NO_HINTING is set.     *********/
-  /**********                                                   *********/
-  /**********************************************************************/
-  /**********************************************************************/
-  /**********************************************************************/
-
-
-  LOCAL_FUNC
-  FT_Error  T1_Load_Glyph( T1_GlyphSlot  glyph,
-                           T1_Size       size,
-                           FT_Int        glyph_index,
-                           FT_Int        load_flags )
-  {
-    FT_Error        error;
-    T1_Decoder      decoder;
-    T1_Face         face = (T1_Face)glyph->root.face;
-    FT_Bool         hinting;
-    T1_Font*        type1 = &face->type1;
-
-    if (load_flags & FT_LOAD_NO_RECURSE)
-      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
-
-    glyph->x_scale = size->root.metrics.x_scale;
-    glyph->y_scale = size->root.metrics.y_scale;
-
-    glyph->root.outline.n_points   = 0;
-    glyph->root.outline.n_contours = 0;
-
-    hinting = ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
-              ( load_flags & FT_LOAD_NO_HINTING ) == 0;
-
-    glyph->root.format = ft_glyph_format_none;
-
-    {
-      T1_Init_Decoder( &decoder );
-      T1_Init_Builder( &decoder.builder, face, size, glyph );
-
-      decoder.blend              = ((T1_Face)glyph->root.face)->blend;
-      decoder.builder.no_recurse = (FT_Bool)!!(load_flags & FT_LOAD_NO_RECURSE);
-
-      /* now load the unscaled outline */
-      error = T1_Parse_CharStrings( &decoder,
-                                    type1->charstrings    [glyph_index],
-                                    type1->charstrings_len[glyph_index],
-                                    type1->num_subrs,
-                                    type1->subrs,
-                                    type1->subrs_len );
-
-      /* save new glyph tables */
-      T1_Done_Builder( &decoder.builder );
-    }
-
-    /* Now, set the metrics.. - this is rather simple, as : */
-    /* the left side bearing is the xMin, and the top side  */
-    /* bearing the yMax..                                   */
-    if (!error)
-    {
-      /* for composite glyphs, return only the left side bearing and the */
-      /* advance width..                                                 */
-      if ( load_flags & FT_LOAD_NO_RECURSE )
-      {
-        glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
-        glyph->root.metrics.horiAdvance  = decoder.builder.advance.x;
-      }
-      else
-      {
-        FT_BBox           cbox;
-        FT_Glyph_Metrics* metrics = &glyph->root.metrics;
-
-        /* copy the _unscaled_ advance width */
-        metrics->horiAdvance  = decoder.builder.advance.x;
-
-        /* make up vertical metrics */
-        metrics->vertBearingX = 0;
-        metrics->vertBearingY = 0;
-        metrics->vertAdvance  = 0;
-
-        glyph->root.format = ft_glyph_format_outline;
-
-        glyph->root.outline.flags &= ft_outline_owner;
-        if ( size && size->root.metrics.y_ppem < 24 )
-          glyph->root.outline.flags |= ft_outline_high_precision;
-
-        glyph->root.outline.flags |= ft_outline_reverse_fill;
-
-        /*
-        glyph->root.outline.second_pass    = TRUE;
-        glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
-        glyph->root.outline.dropout_mode   = 2;
-        */
-
-        if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
-        {
-          /* scale the outline and the metrics */
-          FT_Int       n;
-          FT_Outline*  cur = decoder.builder.base;
-          FT_Vector*   vec = cur->points;
-          FT_Fixed     x_scale = glyph->x_scale;
-          FT_Fixed     y_scale = glyph->y_scale;
-
-          /* First of all, scale the points */
-          for ( n = cur->n_points; n > 0; n--, vec++ )
-          {
-            vec->x = FT_MulFix( vec->x, x_scale );
-            vec->y = FT_MulFix( vec->y, y_scale );
-          }
-
-          FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
-
-          /* Then scale the metrics */
-          metrics->horiAdvance  = FT_MulFix( metrics->horiAdvance,  x_scale );
-
-          metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
-          metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
-          metrics->vertAdvance  = FT_MulFix( metrics->vertAdvance,  x_scale );
-        }
-
-        /* apply the font matrix */
-        FT_Outline_Transform( &glyph->root.outline, &face->type1.font_matrix );
-
-        /* compute the other metrics */
-        FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
-
-        /* grid fit the bounding box if necessary */
-        if (hinting)
-        {
-          cbox.xMin &= -64;
-          cbox.yMin &= -64;
-          cbox.xMax = ( cbox.xMax+63 ) & -64;
-          cbox.yMax = ( cbox.yMax+63 ) & -64;
-        }
-
-        metrics->width  = cbox.xMax - cbox.xMin;
-        metrics->height = cbox.yMax - cbox.yMin;
-
-        metrics->horiBearingX = cbox.xMin;
-        metrics->horiBearingY = cbox.yMax;
-      }
-    }
-    return error;
-  }
-
--- a/src/type1z/t1gload.h
+++ /dev/null
@@ -1,188 +1,0 @@
-/*******************************************************************
- *
- *  t1gload.h                                                   1.0
- *
- *    Type1 Glyph Loader.
- *
- *  Copyright 1996-1998 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used
- *  modified and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- *
- *  The Type 1 glyph loader uses three distinct objects to build
- *  scaled and hinted outlines from a charstrings program. These are :
- *
- *  - a glyph builder, T1_Builder, used to store the built outline
- *
- *  - a glyph hinter, T1_Hinter, used to record and apply the stem
- *    hints
- *
- *  - a charstrings interpreter, T1_Decoder, used to parse the
- *    Type 1 charstrings stream, manage a stack and call the builder
- *    and/or hinter depending on the opcodes.
- *
- *  Ideally, a Type 2 glyph loader would only need to have its own
- *  T2_Decoder object (assuming the hinter is able to manage all
- *  kinds of hints).
- *
- ******************************************************************/
-
-#ifndef T1GLOAD_H
-#define T1GLOAD_H
-
-#include <t1objs.h>
-
-#ifdef __cplusplus
-  extern "C" {
-#endif
-
-
-/*************************************************************************/
-/*                                                                       */
-/* <Structure> T1_Builder                                                */
-/*                                                                       */
-/* <Description>                                                         */
-/*     a structure used during glyph loading to store its outline.       */
-/*                                                                       */
-/* <Fields>                                                              */
-/*    system :: current system object                                    */
-/*    face   :: current face object                                      */
-/*    glyph  :: current glyph slot                                       */
-/*                                                                       */
-/*    current :: current glyph outline                                   */
-/*    base    :: base glyph outline                                      */
-/*                                                                       */
-/*    max_points   :: maximum points in builder outline                  */
-/*    max_contours :: maximum contours in builder outline                */
-/*                                                                       */
-/*    last     :: last point position                                    */
-/*                                                                       */
-/*    scale_x  :: horizontal scale ( FUnits to sub-pixels )              */
-/*    scale_y  :: vertical scale   ( FUnits to sub-pixels )              */
-/*    pos_x    :: horizontal translation (composite glyphs)              */
-/*    pos_y    :: vertical translation   (composite glyph)               */
-/*                                                                       */
-/*    left_bearing  :: left side bearing point                           */
-/*    advance       :: horizontal advance vector                         */
-/*                                                                       */
-/*    path_begun    :: flag, indicates that a new path has begun         */
-/*    load_points   :: flag, if not set, no points are loaded            */
-/*                                                                       */
-/*    error         :: an error code that is only used to report         */
-/*                     memory allocation problems..                      */
-/*                                                                       */
-/*    metrics_only  :: a boolean indicating that we only want to         */
-/*                     compute the metrics of a given glyph, not load    */
-/*                     all of its points..                               */
-/*                                                                       */
-
-  typedef struct T1_Builder_
-  {
-    FT_Memory        memory;
-    T1_Face          face;
-    T1_GlyphSlot     glyph;
-    FT_GlyphLoader*  loader;
-
-    FT_Outline*      current;       /* the current glyph outline   */
-    FT_Outline*      base;          /* the composite glyph outline */
-
-    FT_Vector        last;
-
-    FT_Fixed         scale_x;
-    FT_Fixed         scale_y;
-
-    FT_Pos           pos_x;
-    FT_Pos           pos_y;
-
-    FT_Vector        left_bearing;
-    FT_Vector        advance;
-
-    FT_BBox          bbox;          /* bounding box */
-    FT_Bool          path_begun;
-    FT_Bool          load_points;
-    FT_Bool          no_recurse;
-
-    FT_Error         error;         /* only used for memory errors */
-    FT_Bool          metrics_only;
-
-  } T1_Builder;
-
-
-  /* execution context charstring zone */
-  typedef struct T1_Decoder_Zone_
-  {
-    FT_Byte*  base;
-    FT_Byte*  limit;
-    FT_Byte*  cursor;
-
-  } T1_Decoder_Zone;
-
-
-  typedef struct T1_Decoder_
-  {
-    T1_Builder         builder;
-
-    FT_Int             stack[ T1_MAX_CHARSTRINGS_OPERANDS ];
-    FT_Int*            top;
-
-    T1_Decoder_Zone    zones[ T1_MAX_SUBRS_CALLS+1 ];
-    T1_Decoder_Zone*   zone;
-
-    FT_Int             flex_state;
-    FT_Int             num_flex_vectors;
-    FT_Vector          flex_vectors[7];
-
-    T1_Blend*          blend;  /* for multiple masters */
-
-  } T1_Decoder;
-
-
-
-  LOCAL_DEF
-  void  T1_Init_Builder( T1_Builder*             builder,
-                         T1_Face                 face,
-                         T1_Size                 size,
-                         T1_GlyphSlot            glyph );
-
-  LOCAL_DEF
-  void T1_Done_Builder( T1_Builder*  builder );
-
-
-  LOCAL_DEF
-  void  T1_Init_Decoder( T1_Decoder* decoder );
-
-
-  /* Compute the maximum advance width of a font through quick parsing */
-  LOCAL_DEF
-  FT_Error  T1_Compute_Max_Advance( T1_Face  face,
-                                    FT_Int  *max_advance );
-
-
-  /* This function is exported, because it is used by the T1Dump utility */
-  LOCAL_DEF
-  FT_Error   T1_Parse_CharStrings( T1_Decoder*  decoder,
-                                   FT_Byte*     charstring_base,
-                                   FT_Int       charstring_len,
-                                   FT_Int       num_subrs,
-                                   FT_Byte**    subrs_base,
-                                   FT_Int*      subrs_len );
-
-
-
-  LOCAL_DEF
-  FT_Error  T1_Load_Glyph( T1_GlyphSlot  glyph,
-                           T1_Size       size,
-                           FT_Int        glyph_index,
-                           FT_Int        load_flags );
-
-
-#ifdef __cplusplus
-  }
-#endif
-
-#endif /* T1GLOAD_H */
--- a/src/type1z/t1load.c
+++ /dev/null
@@ -1,1473 +1,0 @@
-/*******************************************************************
- *
- *  t1load.h                                                    2.0
- *
- *    Type1 Loader.
- *
- *  Copyright 1996-2000 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used
- *  modified and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- *
- *  This is the new and improved Type 1 data loader for FreeType 2.
- *  The old loader has several problems: it is slow, complex, difficult
- *  to maintain, and contains incredible hacks to make it accept some
- *  ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5%
- *  of the Type 1 fonts on my machine still aren't loaded correctly
- *  by it.
- *
- *  This version is much simpler, much faster and also easier to
- *  read and maintain by a great order of magnitude. The idea behind
- *  it is to _not_ try to read the Type 1 token stream with a state
- *  machine (i.e. a Postscript-like interpreter) but rather to perform
- *  simple pattern-matching.
- *
- *  Indeed, nearly all data definitions follow a simple pattern
- *  like :
- *
- *      ..... /Field <data> ....
- *
- *  where <data> can be a number, a boolean, a string, or an
- *  array of numbers. There are a few exceptions, namely the
- *  encoding, font name, charstrings and subrs and they are
- *  handled with a special pattern-matching routine.
- *
- *  All other common cases are handled very simply. The matching
- *  rules are defined in the file "t1tokens.h" through the use
- *  of several macros calls PARSE_XXXX
- *
- *  This file is included twice here, the first time to generate
- *  parsing callback functions, the second to generate a table
- *  of keywords (with pointers to the associated callback).
- *
- *  The function "parse_dict" simply scans *linearly* a given
- *  dictionary (either the top-level or private one) and calls
- *  the appropriate callback when it encounters an immediate
- *  keyword.
- *
- *  This is by far the fastest way one can find to parse and read
- *  all data :-)
- *
- *  This led to tremendous code size reduction. Note that later,
- *  the glyph loader will also be _greatly_ simplified, and the
- *  automatic hinter will replace the clumsy "t1hinter"..
- *
- ******************************************************************/
-
-#include <freetype/internal/ftdebug.h>
-#include <freetype/config/ftconfig.h>
-#include <freetype/ftmm.h>
-
-#include <freetype/internal/t1types.h>
-#include <freetype/internal/t1errors.h>
-#include <t1load.h>
-#include <stdio.h>
-
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1load
-
-#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
- /***************************************************************************/
- /***************************************************************************/
- /*****                                                                 *****/
- /*****                    MULTIPLE MASTERS SUPPORT                     *****/
- /*****                                                                 *****/
- /***************************************************************************/
- /***************************************************************************/
-
- static  FT_Error  t1_allocate_blend( T1_Face   face,
-                                      FT_UInt   num_designs,
-                                      FT_UInt   num_axis )
- {
-   T1_Blend*  blend;
-   FT_Memory  memory = face->root.memory;
-   FT_Error   error  = 0;
-   
-   blend = face->blend;
-   if (!blend)
-   {
-     if ( ALLOC( blend, sizeof(*blend) ) )
-       goto Exit;
-       
-     face->blend = blend;
-   }
-   
-   /* allocate design data if needed */
-   if (num_designs > 0)
-   {
-     if (blend->num_designs == 0)
-     {
-       /* allocate the blend "private" and "font_info" dictionaries */
-       if ( ALLOC_ARRAY( blend->font_infos[1], num_designs, T1_FontInfo ) ||
-            ALLOC_ARRAY( blend->privates[1], num_designs, T1_Private )    ||
-            ALLOC_ARRAY( blend->weight_vector, num_designs*2, FT_Fixed )  )
-         goto Exit;
-  
-       blend->default_weight_vector = blend->weight_vector + num_designs;
-
-       blend->font_infos[0] = &face->type1.font_info;
-       blend->privates  [0] = &face->type1.private_dict;
-       blend->num_designs   = num_designs;
-     }
-     else if (blend->num_designs != num_designs)
-       goto Fail;
-   }
-   
-   /* allocate axis data if needed */
-   if (num_axis > 0)
-   {
-     if (blend->num_axis != 0 && blend->num_axis != num_axis)
-       goto Fail;
-       
-     blend->num_axis = num_axis;
-   }
-   
-   /* allocate the blend design pos table if needed */
-   num_designs = blend->num_designs;
-   num_axis    = blend->num_axis;
-   if ( num_designs && num_axis && blend->design_pos[0] == 0)
-   {
-     FT_UInt  n;
-     
-     if ( ALLOC_ARRAY( blend->design_pos[0], num_designs*num_axis, FT_Fixed ) )
-       goto Exit;
-       
-     for ( n = 1; n < num_designs; n++ )
-       blend->design_pos[n] = blend->design_pos[0] + num_axis*n;       
-   }
-   
- Exit:
-   return error;
- Fail:
-   error = -1;
-   goto Exit;
- }                                  
-
- LOCAL_FUNC  FT_Error  T1_Get_Multi_Master( T1_Face          face,
-                                            FT_Multi_Master* master )
- {
-   T1_Blend*  blend = face->blend;
-   FT_UInt    n;
-   FT_Error   error;
-   
-   error = T1_Err_Invalid_Argument;
-   if (blend)
-   {
-     master->num_axis    = blend->num_axis;
-     master->num_designs = blend->num_designs;
-     for ( n = 0; n < blend->num_axis; n++ )
-     {
-       FT_MM_Axis*    axis = master->axis + n;
-       T1_DesignMap*  map = blend->design_map + n;
-       
-       axis->name    = blend->axis_names[n];
-       axis->minimum = map->design_points[0];
-       axis->maximum = map->design_points[map->num_points-1];
-     }
-     error = 0;
-   }
-   return error;
- }                                            
-
-
- LOCAL_FUNC  FT_Error  T1_Set_MM_Blend( T1_Face    face,
-                                        FT_UInt    num_coords,
-                                        FT_Fixed*  coords )
- {
-   T1_Blend*  blend = face->blend;
-   FT_Error   error;
-   FT_UInt    n, m;
-   
-   error = T1_Err_Invalid_Argument;
-   if (blend && blend->num_axis == num_coords)
-   {
-     /* recompute the weight vector from the blend coordinates */
-     error = 0;
-     for ( n = 0; n < blend->num_designs; n++ )
-     {
-       FT_Fixed  result = 0x10000L;  /* 1.0 fixed */
-       for ( m = 0; m < blend->num_axis; m++ )
-       {
-         FT_Fixed  factor;
-
-         /* get current blend axis position */
-         factor = coords[m];
-         if (factor < 0) factor = 0;
-         if (factor > 0x10000L) factor = 0x10000L;
-         
-         if ((n & (1 << m)) == 0)
-           factor = 0x10000L - factor;
-           
-         result = FT_MulFix( result, factor );
-       }
-       blend->weight_vector[n] = result;
-     }
-     error = 0;
-   }
-   return error;
- }
- 
-
- LOCAL_FUNC  FT_Error  T1_Set_MM_Design( T1_Face   face,
-                                         FT_UInt   num_coords,
-                                         FT_Long*  coords )
- {
-   T1_Blend*  blend = face->blend;
-   FT_Error   error;
-   FT_UInt    n, p;
-   
-   error = T1_Err_Invalid_Argument;
-   if (blend && blend->num_axis == num_coords)
-   {
-     /* compute the blend coordinates through the blend design map */
-     FT_Fixed  final_blends[ T1_MAX_MM_DESIGNS ];
-     
-     for ( n = 0; n < blend->num_axis; n++ )
-     {
-       FT_Long        design = coords[n];
-       FT_Fixed       the_blend;
-       T1_DesignMap*  map     = blend->design_map + n;
-       FT_Fixed*      designs = map->design_points;
-       FT_Fixed*      blends  = map->blend_points;
-       FT_Int         before = -1, after = -1;
-       
-       for ( p = 0; p < map->num_points; p++ )
-       {
-         FT_Fixed  p_design = designs[p];
-         
-         /* exact match ? */
-         if (design == p_design)
-         {
-           the_blend = blends[p];
-           goto Found;
-         }
-         
-         if (design < p_design)
-         {
-           after = p;
-           break;
-         }
-         
-         before = p;
-       }
-       
-       /* now, interpolate if needed */
-       if (before < 0)
-         the_blend = blends[0];
-         
-       else if (after < 0)
-         the_blend = blends[map->num_points-1];
-         
-       else
-         the_blend = FT_MulDiv( design         - designs[before],
-                                blends [after] - blends [before],
-                                designs[after] - designs[before] );
-     Found:
-       final_blends[n] = the_blend;
-     }
-
-     error = T1_Set_MM_Blend( face, num_coords, final_blends );     
-   }
-   return error;
- }
-
- 
- LOCAL_FUNC  void T1_Done_Blend( T1_Face  face )
- {
-   FT_Memory  memory = face->root.memory;
-   T1_Blend*  blend  = face->blend;
-   
-   if (blend)
-   {
-     FT_UInt  num_designs = blend->num_designs;
-     FT_UInt  num_axis    = blend->num_axis;
-     FT_UInt  n;
-          
-     /* release design pos table */
-     FREE( blend->design_pos[0] );
-     for ( n = 1; n < num_designs; n++ )
-       blend->design_pos[n] = 0;
-
-     /* release blend "private" and "font info" dictionaries */
-     FREE( blend->privates[1] );
-     FREE( blend->font_infos[1] );
-     for ( n = 0; n < num_designs; n++ )
-     {
-       blend->privates  [n] = 0;
-       blend->font_infos[n] = 0;
-     }
-
-     /* release weight vectors */
-     FREE( blend->weight_vector );
-     blend->default_weight_vector = 0;
-
-     /* release axis names */
-     for ( n = 0; n < num_axis; n++ )
-       FREE( blend->axis_names[n] );
-     
-     /* release design map */
-     for ( n = 0; n < num_axis; n++ )
-     {
-       T1_DesignMap*  dmap = blend->design_map + n;
-       FREE( dmap->design_points );
-       dmap->num_points = 0;
-     }
-     
-     FREE( face->blend );
-   }
- }
-
-
-
- static  void  parse_blend_axis_types( T1_Face  face, T1_Loader*  loader )
- {
-   T1_Token_Rec  axis_tokens[ T1_MAX_MM_AXIS ];
-   FT_Int        n, num_axis;
-   FT_Error      error = 0;
-   T1_Blend*     blend;
-   FT_Memory     memory;
-
-   /* take an array of objects */
-   T1_ToTokenArray( &loader->parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis );
-   if (num_axis <= 0 || num_axis > T1_MAX_MM_AXIS)
-   {
-     FT_ERROR(( "T1.parse_blend_axis_types: incorrect number of axis: %d\n",
-                num_axis ));
-     error = T1_Err_Invalid_File_Format;
-     goto Exit;
-   }
-   
-   /* allocate blend if necessary */
-   error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
-   if (error) goto Exit;
-   
-   blend  = face->blend;
-   memory = face->root.memory;
-   
-   /* each token is an immediate containing the name of the axis */
-   for ( n = 0; n < num_axis; n++ )
-   {
-     T1_Token_Rec*  token = axis_tokens + n;
-     FT_Byte*       name;
-     FT_Int         len;
-     
-     /* skip first slash, if any */
-     if (token->start[0] == '/')
-       token->start++;
-       
-     len = token->limit - token->start;
-     if (len <= 0)
-     {
-       error = T1_Err_Invalid_File_Format;
-       goto Exit;
-     }
-       
-     if ( ALLOC( blend->axis_names[n], len+1 ) )
-       goto Exit;
-     
-     name = (FT_Byte*)blend->axis_names[n];
-     MEM_Copy( name, token->start, len );
-     name[len] = 0;
-   }
-
- Exit:   
-   loader->parser.error = error;
- }
- 
- 
- static void  parse_blend_design_positions( T1_Face  face, T1_Loader*  loader )
- {
-   T1_Token_Rec  design_tokens[ T1_MAX_MM_DESIGNS ];
-   FT_Int        num_designs;
-   FT_Int        num_axis;
-   T1_Parser*    parser = &loader->parser;
-   
-   FT_Error      error = 0;
-   T1_Blend*     blend;
-
-   /* get the array of design tokens - compute number of designs */   
-   T1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs );
-   if (num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS)
-   {
-     FT_ERROR(( "T1.design positions: incorrect number of designs: %d\n",
-                num_designs ));
-     error = T1_Err_Invalid_File_Format;
-     goto Exit;
-   }
-   
-   {
-     FT_Byte*  old_cursor = parser->cursor;
-     FT_Byte*  old_limit  = parser->limit;
-     FT_UInt   n;
-
-     blend    = face->blend;
-     num_axis = 0;  /* make compiler happy */
-     for ( n = 0; n < (FT_UInt)num_designs; n++ )
-     {
-       T1_Token_Rec  axis_tokens[ T1_MAX_MM_DESIGNS ];
-       T1_Token_Rec* token;
-       FT_Int        axis, n_axis;
-
-       /* read axis/coordinates tokens */
-       token = design_tokens + n;
-       parser->cursor = token->start - 1;
-       parser->limit  = token->limit + 1;
-       T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
-       
-       if (n == 0)
-       {
-         num_axis = n_axis;
-         error = t1_allocate_blend( face, num_designs, num_axis );
-         if (error) goto Exit;
-         blend = face->blend;
-       }
-       else if (n_axis != num_axis)
-       {
-         FT_ERROR(( "T1.design_positions: incorrect table\n" ));
-         error = T1_Err_Invalid_File_Format;
-         goto Exit;
-       }
-       
-       /* now, read each axis token into the design position */
-       for (axis = 0; axis < n_axis; axis++ )
-       {
-         T1_Token_Rec*  token2 = axis_tokens + axis;
-         parser->cursor = token2->start;
-         parser->limit  = token2->limit;
-         blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
-       }
-     }
-     
-     loader->parser.cursor = old_cursor;
-     loader->parser.limit  = old_limit;
-   }
-   
- Exit:
-   loader->parser.error = error;
- }
-
- static void  parse_blend_design_map( T1_Face  face, T1_Loader*  loader )
- {
-   FT_Error      error  = 0;
-   T1_Parser*    parser = &loader->parser;
-   T1_Blend*     blend;
-   T1_Token_Rec  axis_tokens[ T1_MAX_MM_AXIS ];
-   FT_Int        n, num_axis;
-   FT_Byte*      old_cursor;
-   FT_Byte*      old_limit;
-   FT_Memory     memory = face->root.memory;
-   
-   T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis );
-   if (num_axis <= 0 || num_axis > T1_MAX_MM_AXIS)
-   {
-     FT_ERROR(( "T1.design map: incorrect number of axis: %d\n",
-                num_axis ));
-     error = T1_Err_Invalid_File_Format;
-     goto Exit;
-   }
-   old_cursor = parser->cursor;
-   old_limit  = parser->limit;
-
-   error = t1_allocate_blend( face, 0, num_axis );
-   if (error) goto Exit;
-   blend = face->blend;
-
-   /* now, read each axis design map */
-   for ( n = 0; n < num_axis; n++ )
-   {
-     T1_DesignMap*   map = blend->design_map + n;
-     T1_Token_Rec*   token;
-     FT_Int          p, num_points;
-     
-     token = axis_tokens + n;
-     parser->cursor = token->start;
-     parser->limit  = token->limit;
-     
-     /* count the number of map points */
-     {
-       FT_Byte*  p     = token->start;
-       FT_Byte*  limit = token->limit;
-       
-       num_points = 0;
-       for ( ; p < limit; p++ )
-         if (p[0] == '[')
-           num_points++;
-     }
-     if (num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS)
-     {
-       FT_ERROR(( "T1.design map: incorrect table\n" ));
-       error = T1_Err_Invalid_File_Format;
-       goto Exit;
-     }
-     
-     /* allocate design map data */
-     if ( ALLOC_ARRAY( map->design_points, num_points*2, FT_Fixed ) )
-       goto Exit;
-     map->blend_points = map->design_points + num_points;
-     map->num_points   = (FT_Byte)num_points;
-     
-     for ( p = 0; p < num_points; p++ )
-     {
-       map->design_points[p] = T1_ToInt( parser );
-       map->blend_points [p] = T1_ToFixed( parser, 0 );
-     }
-   }   
-   
-   parser->cursor = old_cursor;
-   parser->limit  = old_limit;
- Exit:
-   parser->error = error;
- }
-
- static void parse_weight_vector( T1_Face   face, T1_Loader*  loader )
- {
-   FT_Error      error  = 0;
-   T1_Parser*    parser = &loader->parser;
-   T1_Blend*     blend  = face->blend;
-   T1_Token_Rec  master;
-   FT_UInt       n;
-   FT_Byte*      old_cursor;
-   FT_Byte*      old_limit;
-   
-   if (!blend || blend->num_designs == 0)
-   {
-     FT_ERROR(( "t1.weight_vector: too early !!\n" ));
-     error = T1_Err_Invalid_File_Format;
-     goto Exit;
-   }
-   
-   T1_ToToken( parser, &master );
-   if (master.type != t1_token_array)
-   {
-     FT_ERROR(( "t1.weight_vector: incorrect format !!\n" ));
-     error = T1_Err_Invalid_File_Format;
-     goto Exit;
-   }
-   
-   old_cursor = parser->cursor;
-   old_limit  = parser->limit;
-
-   parser->cursor = master.start;
-   parser->limit  = master.limit;
-   for ( n = 0; n < blend->num_designs; n++ )
-   {
-     blend->default_weight_vector[n] =
-     blend->weight_vector[n]         = T1_ToFixed( parser, 0 );
-   }
-   
-   parser->cursor = old_cursor;
-   parser->limit  = old_limit;
- Exit:
-   parser->error = error;
- }
-
- /* the keyword /shareddict appears in some multiple master fonts with a lot */
- /* of Postscript garbage behind it (that's completely out of spec !!), we   */
- /* detect it and terminate the parsing                                      */
- static  void parse_shared_dict( T1_Face  face, T1_Loader*  loader )
- {
-   T1_Parser*  parser = &loader->parser;
-   
-   UNUSED(face);
-   
-   parser->cursor = parser->limit;
-   parser->error  = 0;
- }
-#endif
- 
- /***************************************************************************/
- /***************************************************************************/
- /*****                                                                 *****/
- /*****                      TYPE 1 SYMBOL PARSING                      *****/
- /*****                                                                 *****/
- /***************************************************************************/
- /***************************************************************************/
-
- /*********************************************************************
-  *
-  *  First of all, define the token field static variables. This is
-  *  a set of T1_Field_Rec variables used later..
-  *
-  *********************************************************************/
-
-#define T1_NEW_STRING( _name, _field ) \
-   static const  T1_Field_Rec  t1_field_ ## _field = T1_FIELD_STRING( T1TYPE, _field );
-
-#define T1_NEW_BOOL( _name, _field )   \
-   static const  T1_Field_Rec  t1_field_ ## _field = T1_FIELD_BOOL( T1TYPE, _field );
-   
-#define T1_NEW_NUM( _name, _field )    \
-   static const  T1_Field_Rec  t1_field_ ## _field = T1_FIELD_NUM( T1TYPE, _field );
-   
-#define T1_NEW_FIXED( _name, _field )  \
-   static const  T1_Field_Rec  t1_field_ ## _field = T1_FIELD_FIXED( T1TYPE, _field, _power );
-
-#define T1_NEW_NUM_TABLE( _name, _field, _max, _count ) \
-   static const  T1_Field_Rec  t1_field_ ## _field = T1_FIELD_NUM_ARRAY( T1TYPE, _field, _count, _max );
-   
-#define T1_NEW_FIXED_TABLE( _name, _field, _max, _count ) \
-   static const  T1_Field_Rec  t1_field_ ## _field = T1_FIELD_FIXED_ARRAY( T1TYPE, _field, _count, _max );
-
-#define T1_NEW_NUM_TABLE2( _name, _field, _max ) \
-   static const  T1_Field_Rec  t1_field_ ## _field = T1_FIELD_NUM_ARRAY2( T1TYPE, _field, _max );
-   
-#define T1_NEW_FIXED_TABLE2( _name, _field, _max ) \
-   static const  T1_Field_Rec  t1_field_ ## _field = T1_FIELD_FIXED_ARRAY2( T1TYPE, _field, _max );
-
-
-#define T1_FONTINFO_STRING(n,f)        T1_NEW_STRING(n,f)
-#define T1_FONTINFO_NUM(n,f)           T1_NEW_NUM(n,f)
-#define T1_FONTINFO_BOOL(n,f)          T1_NEW_BOOL(n,f)
-#define T1_PRIVATE_NUM(n,f)            T1_NEW_NUM(n,f)
-#define T1_PRIVATE_FIXED(n,f)          T1_NEW_FIXED(n,f)
-#define T1_PRIVATE_NUM_TABLE(n,f,m,c)  T1_NEW_NUM_TABLE(n,f,m,c)
-#define T1_PRIVATE_NUM_TABLE2(n,f,m)   T1_NEW_NUM_TABLE2(n,f,m)
-#define T1_TOPDICT_NUM(n,f)            T1_NEW_NUM(n,f)
-#define T1_TOPDICT_NUM_FIXED2(n,f,m)   T1_NEW_FIXED_TABLE2(n,f,m)
-
-/* including this file defines all field variables */
-#include <t1tokens.h>
-
- /*********************************************************************
-  *
-  *  Second, define the keyword variables. This is a set of T1_KeyWord
-  *  structures used to model the way each keyword is "loaded"..
-  *
-  *********************************************************************/
-
-  typedef  void  (*T1_Parse_Func)( T1_Face   face, T1_Loader*  loader );
-
-  typedef enum T1_KeyWord_Type_
-  {
-    t1_keyword_callback = 0,
-    t1_keyword_field,
-    t1_keyword_field_table
-    
-  } T1_KeyWord_Type;
-  
-  typedef enum T1_KeyWord_Location_
-  {
-    t1_keyword_type1 = 0,
-    t1_keyword_font_info,
-    t1_keyword_private
-  
-  } T1_KeyWord_Location;
-  
-  typedef  struct T1_KeyWord_
-  {
-    const char*          name;
-    T1_KeyWord_Type      type;
-    T1_KeyWord_Location  location;
-    T1_Parse_Func        parsing;
-    const T1_Field_Rec*  field;
-
-  } T1_KeyWord;
-
-
-#define T1_KEYWORD_CALLBACK( name, callback )  \
-         { name, t1_keyword_callback, t1_keyword_type1, callback, 0 }
-
-#define T1_KEYWORD_TYPE1( name, f ) \
-         { name, t1_keyword_field, t1_keyword_type1, 0, &t1_field_ ## f }
-         
-#define T1_KEYWORD_FONTINFO( name, f ) \
-         { name, t1_keyword_field, t1_keyword_font_info, 0, &t1_field_ ## f }
-
-#define T1_KEYWORD_PRIVATE( name, f ) \
-         { name, t1_keyword_field, t1_keyword_private, 0, &t1_field_ ## f }
-
-#define T1_KEYWORD_FONTINFO_TABLE( name, f ) \
-         { name, t1_keyword_field_table, t1_keyword_font_info, 0, &t1_field_ ## f }
-
-#define T1_KEYWORD_PRIVATE_TABLE( name, f ) \
-         { name, t1_keyword_field_table, t1_keyword_private, 0, &t1_field_ ## f }
-
-#undef  T1_FONTINFO_STRING
-#undef  T1_FONTINFO_NUM
-#undef  T1_FONTINFO_BOOL
-#undef  T1_PRIVATE_NUM
-#undef  T1_PRIVATE_FIXED
-#undef  T1_PRIVATE_NUM_TABLE
-#undef  T1_PRIVATE_NUM_TABLE2
-#undef  T1_TOPDICT_NUM
-#undef  T1_TOPDICT_NUM_FIXED2
-
-#define T1_FONTINFO_STRING(n,f)        T1_KEYWORD_FONTINFO(n,f),
-#define T1_FONTINFO_NUM(n,f)           T1_KEYWORD_FONTINFO(n,f),
-#define T1_FONTINFO_BOOL(n,f)          T1_KEYWORD_FONTINFO(n,f),
-#define T1_PRIVATE_NUM(n,f)            T1_KEYWORD_PRIVATE(n,f),
-#define T1_PRIVATE_FIXED(n,f)          T1_KEYWORD_PRIVATE(n,f),
-#define T1_PRIVATE_NUM_TABLE(n,f,m,c)  T1_KEYWORD_PRIVATE_TABLE(n,f),
-#define T1_PRIVATE_NUM_TABLE2(n,f,m)   T1_KEYWORD_PRIVATE_TABLE(n,f),
-#define T1_TOPDICT_NUM(n,f)            T1_KEYWORD_TYPE1(n,f),
-#define T1_TOPDICT_NUM_FIXED2(n,f,m)   T1_KEYWORD_TYPE1(n,f),
-
-
-  static  FT_Error   t1_load_keyword( T1_Face     face,
-                                      T1_Loader*  loader,
-                                      T1_KeyWord* keyword )
-  {
-    FT_Error  error;
-    void*     dummy_object;
-    void**    objects;
-    FT_UInt   max_objects;
-    T1_Blend* blend = face->blend;
-    
-    /* if the keyword has a dedicated callback, call it */
-    if (keyword->type == t1_keyword_callback)
-    {
-      keyword->parsing( face, loader );
-      error = loader->parser.error;
-      goto Exit;
-    }
-    
-    /* now, the keyword is either a simple field, or a table of fields */
-    /* we are now going to take care of it..                           */
-    switch (keyword->location)
-    {
-      case t1_keyword_font_info:
-        {
-          dummy_object = &face->type1.font_info;
-          objects      = &dummy_object;
-          max_objects  = 0;
-          if (blend)
-          {
-            objects     = (void**)blend->font_infos;
-            max_objects = blend->num_designs;
-          }
-        }
-        break;
-        
-      case t1_keyword_private:
-        {
-          dummy_object = &face->type1.private_dict;
-          objects      = &dummy_object;
-          max_objects  = 0;
-          if (blend)
-          {
-            objects     = (void**)blend->privates;
-            max_objects = blend->num_designs;
-          }
-        }
-        break;
-      
-      default:
-        dummy_object = &face->type1;
-        objects      = &dummy_object;
-        max_objects  = 0;
-    }
-    
-    if (keyword->type == t1_keyword_field_table)
-      error = T1_Load_Field_Table( &loader->parser, keyword->field, objects, max_objects, 0 );
-    else
-      error = T1_Load_Field( &loader->parser, keyword->field, objects, max_objects, 0 );
-    
-  Exit:
-    return error;
-  }                                
-
-
-  static
-  int  is_space( char c )
-  {
-    return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' );
-  }
-
-  static
-  int  is_alpha( char c )
-  {
-    return ( (c >= 'A' && c <= 'Z') ||
-             (c >= 'a' && c <= 'z') ||
-             (c >= '0' && c <= '9') ||
-             (c == '.')             ||
-             (c == '_') );
-  }
-
-  static
-  void  skip_whitespace( T1_Parser* parser )
-  {
-    FT_Byte*  cur = parser->cursor;
-
-    while ( cur < parser->limit && is_space(*cur) )
-      cur++;
-
-    parser->cursor = cur;
-  }
-
-  static
-  void skip_blackspace( T1_Parser* parser )
-  {
-    FT_Byte*  cur = parser->cursor;
-
-    while ( cur < parser->limit && !is_space(*cur) )
-      cur++;
-
-    parser->cursor = cur;
-  }
-
-  static
-  int   read_binary_data( T1_Parser*  parser, FT_Int *size, FT_Byte* *base )
-  {
-    FT_Byte*  cur;
-    FT_Byte*  limit = parser->limit;
-
-    /* the binary data has the following format */
-    /*                                          */
-    /* "size" [white*] RD white ....... ND      */
-    /*                                          */
-
-    skip_whitespace(parser);
-    cur = parser->cursor;
-
-    if ( cur < limit && (FT_Byte)(*cur-'0') < 10 )
-    {
-      *size = T1_ToInt(parser);
-
-      skip_whitespace(parser);
-      skip_blackspace(parser);  /* "RD" or "-|" or something else */
-
-      /* there is only one whitespace char after the */
-      /* "RD" or "-|" token                          */
-      *base = parser->cursor + 1;
-
-      parser->cursor += *size+1;
-      return 1;
-    }
-
-    FT_ERROR(( "type1.read_binary_data: invalid size field\n" ));
-    parser->error = T1_Err_Invalid_File_Format;
-    return 0;
-  }
-
-
-  /* we will now define the routines used to handle */
-  /* the /Encoding, /Subrs and /CharStrings         */
-  /* dictionaries..                                 */
-
-  static
-  void  parse_font_name( T1_Face  face, T1_Loader*  loader )
-  {
-    T1_Parser*  parser = &loader->parser;
-    FT_Error    error;
-    FT_Memory   memory = parser->memory;
-    FT_Int      len;
-    FT_Byte*    cur;
-    FT_Byte*    cur2;
-    FT_Byte*    limit;
-
-    skip_whitespace(parser);
-    cur   = parser->cursor;
-    limit = parser->limit;
-    if ( cur >= limit-1 || *cur != '/' ) return;
-
-    cur++;
-    cur2 = cur;
-    while (cur2 < limit && is_alpha(*cur2)) cur2++;
-    len = cur2-cur;
-    if (len > 0)
-    {
-      if ( ALLOC( face->type1.font_name, len+1 ) )
-      {
-        parser->error = error;
-        return;
-      }
-
-      MEM_Copy( face->type1.font_name, cur, len );
-      face->type1.font_name[len] = '\0';
-    }
-    parser->cursor = cur2;
-  }
-
-  static
-  void  parse_font_bbox( T1_Face  face, T1_Loader*  loader )
-  {
-    T1_Parser*  parser = &loader->parser;
-    FT_Short    temp[4];
-    FT_BBox*    bbox = &face->type1.font_bbox;
-
-    (void)T1_ToCoordArray( parser, 4, temp );
-    bbox->xMin = temp[0];
-    bbox->yMin = temp[1];
-    bbox->xMax = temp[2];
-    bbox->yMax = temp[3];
-  }
-
-  static
-  void  parse_font_matrix( T1_Face  face, T1_Loader*  loader )
-  {
-    T1_Parser*  parser = &loader->parser;
-    FT_Matrix*  matrix = &face->type1.font_matrix;
-    FT_Fixed    temp[4];
-
-    (void)T1_ToFixedArray( parser, 4, temp, 3 );
-    matrix->xx = temp[0];
-    matrix->yx = temp[1];
-    matrix->xy = temp[2];
-    matrix->yy = temp[3];
-  }
-
-
-
-  static
-  void  parse_encoding( T1_Face  face, T1_Loader*  loader )
-  {
-    T1_Parser*  parser = &loader->parser;
-    FT_Byte*    cur   = parser->cursor;
-    FT_Byte*    limit = parser->limit;
-
-    /* skip whitespace */
-    while (is_space(*cur))
-    {
-      cur++;
-      if (cur >= limit)
-      {
-        FT_ERROR(( "type1.parse_encoding: out of bounds !!\n" ));
-        parser->error = T1_Err_Invalid_File_Format;
-        return;
-      }
-    }
-
-    /* if we have a number, then the encoding is an array, */
-    /* and we must load it now                             */
-    if ((FT_Byte)(*cur - '0') < 10)
-    {
-      T1_Encoding*  encode     = &face->type1.encoding;
-      FT_Int        count, n;
-      T1_Table*     char_table = &loader->encoding_table;
-      FT_Memory     memory     = parser->memory;
-      FT_Error      error;
-
-      /* read the number of entries in the encoding, should be 256 */
-      count = T1_ToInt( parser );
-      if (parser->error) return;
-
-      /* we use a T1_Table to store our charnames */
-      encode->num_chars = count;
-      if ( ALLOC_ARRAY( encode->char_index, count, FT_Short   ) ||
-           ALLOC_ARRAY( encode->char_name,  count, FT_String* ) ||
-           (error = T1_New_Table( char_table, count, memory )) != 0     )
-      {
-        parser->error = error;
-        return;
-      }
-
-      /* now, we will need to read a record of the form         */
-      /* ... charcode /charname ... for each entry in our table */
-      /*                                                        */
-      /* we simply look for a number followed by an immediate   */
-      /* name. Note that this ignores correctly the sequence    */
-      /* that is often seen in type1 fonts :                    */
-      /*                                                        */
-      /*   0 1 255 { 1 index exch /.notdef put } for dup        */
-      /*                                                        */
-      /* used to clean the encoding array before anything else  */
-      /*                                                        */
-      /* we stop when we encounter a "def"                      */
-      /*                                                        */
-
-      cur   = parser->cursor;
-      limit = parser->limit;
-      n     = 0;
-
-      for ( ; cur < limit; )
-      {
-        FT_Byte  c;
-
-        c = *cur;
-
-        /* we stop when we encounter a 'def' */
-        if ( c == 'd' && cur+3 < limit )
-        {
-          if ( cur[1] == 'e' &&
-               cur[2] == 'f' &&
-               is_space(cur[-1]) &&
-               is_space(cur[3]) )
-          {
-              FT_TRACE6(( "encoding end\n" ));
-              break;
-          }
-        }
-
-        /* otherwise, we must find a number before anything else */
-        if ( (FT_Byte)(c-'0') < 10 )
-        {
-          FT_Int  charcode;
-
-          parser->cursor = cur;
-          charcode = T1_ToInt(parser);
-          cur = parser->cursor;
-
-          /* skip whitespace */
-          while (cur < limit && is_space(*cur)) cur++;
-
-          if (cur < limit && *cur == '/')
-          {
-            /* bingo, we have an immediate name - it must be a */
-            /* character name                                  */
-            FT_Byte*  cur2 = cur+1;
-            FT_Int    len;
-
-            while (cur2 < limit && is_alpha(*cur2)) cur2++;
-            len = cur2-cur-1;
-            parser->error = T1_Add_Table( char_table, charcode, cur+1, len+1 );
-            char_table->elements[charcode][len] = '\0';
-            if (parser->error) return;
-
-            cur = cur2;
-          }
-        }
-        else
-          cur++;
-      }
-
-      face->type1.encoding_type = t1_encoding_array;
-      parser->cursor            = cur;
-    }
-    /* Otherwise, we should have either "StandardEncoding" or */
-    /* "ExpertEncoding"                                       */
-    else
-    {
-      if ( cur+17 < limit &&
-           strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
-        face->type1.encoding_type = t1_encoding_standard;
-
-      else if ( cur+15 < limit &&
-                strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
-        face->type1.encoding_type = t1_encoding_expert;
-
-      else
-      {
-        FT_ERROR(( "type1.parse_encoding: invalid token !!\n" ));
-        parser->error = T1_Err_Invalid_File_Format;
-      }
-    }
-  }
-
-
-  static
-  void  parse_subrs( T1_Face  face, T1_Loader*  loader )
-  {
-    T1_Parser*  parser = &loader->parser;
-    T1_Table*   table  = &loader->subrs;
-    FT_Memory   memory = parser->memory;
-    FT_Error    error;
-    FT_Int      n;
-
-    loader->num_subrs = T1_ToInt( parser );
-    if (parser->error) return;
-
-    /* initialise subrs array */
-    error = T1_New_Table( table, loader->num_subrs, memory );
-    if (error) goto Fail;
-
-    /* the format is simple :                                */
-    /*                                                       */
-    /*   "index" + binary data                               */
-    /*                                                       */
-
-    for ( n = 0; n < loader->num_subrs; n++ )
-    {
-      FT_Int    index, size;
-      FT_Byte*  base;
-
-      index = T1_ToInt(parser);
-      if (!read_binary_data(parser,&size,&base)) return;
-
-      /* some fonts use a value of -1 for lenIV to indicate that */
-      /* the charstrings are unencoded..                         */
-      /*                                                         */
-      /* thanks to Tom Kacvinsky for pointing this out..         */
-      /*                                                         */
-      if (face->type1.private_dict.lenIV >= 0)
-      {
-        T1_Decrypt( base, size, 4330 );
-        size -= face->type1.private_dict.lenIV;
-        base += face->type1.private_dict.lenIV;
-      }
-
-      error = T1_Add_Table( table, index, base, size );
-      if (error) goto Fail;
-    }
-    return;
-
-  Fail:
-    parser->error = error;
-  }
-
-
-
-
-  static
-  void  parse_charstrings( T1_Face  face, T1_Loader*  loader )
-  {
-    T1_Parser*  parser     = &loader->parser;
-    T1_Table*   code_table = &loader->charstrings;
-    T1_Table*   name_table = &loader->glyph_names;
-    FT_Memory   memory     = parser->memory;
-    FT_Error    error;
-
-    FT_Byte*    cur;
-    FT_Byte*    limit = parser->limit;
-    FT_Int      n;
-
-    loader->num_glyphs = T1_ToInt( parser );
-    if (parser->error) return;
-
-    /* initialise tables */
-    error = T1_New_Table( code_table, loader->num_glyphs, memory ) ||
-            T1_New_Table( name_table, loader->num_glyphs, memory );
-    if (error) goto Fail;
-
-    n = 0;
-    for ( ;; )
-    {
-      FT_Int    size;
-      FT_Byte*  base;
-
-      /* the format is simple :                   */
-      /*   "/glyphname" + binary data             */
-      /*                                          */
-      /* note that we stop when we find a "def"   */
-      /*                                          */
-      skip_whitespace(parser);
-      cur = parser->cursor;
-      if (cur >= limit) break;
-
-      /* we stop when we find a "def" or "end" keyword */
-      if (*cur    == 'd' &&
-           cur+3 < limit &&
-           cur[1] == 'e' &&
-           cur[2] == 'f' )
-        break;
-
-      if (*cur == 'e'   &&
-          cur+3 < limit &&
-          cur[1] == 'n' &&
-          cur[2] == 'd' )
-        break;
-
-      if (*cur != '/')
-        skip_blackspace(parser);
-      else
-      {
-        FT_Byte*  cur2 = cur+1;
-        FT_Int    len;
-
-        while (cur2 < limit && is_alpha(*cur2)) cur2++;
-        len = cur2-cur-1;
-
-        error = T1_Add_Table( name_table, n, cur+1, len+1 );
-        if (error) goto Fail;
-
-        /* add a trailing zero to the name table */
-        name_table->elements[n][len] = '\0';
-
-        parser->cursor = cur2;
-        if (!read_binary_data(parser,&size,&base)) return;
-
-        /* some fonts use a value of -1 for lenIV to indicate that */
-        /* the charstrings are unencoded..                         */
-        /*                                                         */
-        /* thanks to Tom Kacvinsky for pointing this out..         */
-        /*                                                         */
-        if (face->type1.private_dict.lenIV >= 0)
-        {
-          T1_Decrypt( base, size, 4330 );
-          size -= face->type1.private_dict.lenIV;
-          base += face->type1.private_dict.lenIV;
-        }
-
-        error = T1_Add_Table( code_table, n, base, size );
-        if (error) goto Fail;
-
-        n++;
-        if (n >= loader->num_glyphs)
-          break;
-      }
-    }
-    loader->num_glyphs = n;
-    return;
-
-  Fail:
-    parser->error = error;
-  }
-
-
-
-
-  static
-  const T1_KeyWord  t1_keywords[] =
-  {
-#include <t1tokens.h>  
-    
-    /* now add the special functions... */
-    T1_KEYWORD_CALLBACK( "FontName", parse_font_name ),
-    T1_KEYWORD_CALLBACK( "FontBBox", parse_font_bbox ),
-    T1_KEYWORD_CALLBACK( "FontMatrix", parse_font_matrix ),
-    T1_KEYWORD_CALLBACK( "Encoding", parse_encoding  ),
-    T1_KEYWORD_CALLBACK( "Subrs",    parse_subrs     ),
-    T1_KEYWORD_CALLBACK( "CharStrings", parse_charstrings ),
-#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
-    T1_KEYWORD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions ),
-    T1_KEYWORD_CALLBACK( "BlendDesignMap", parse_blend_design_map ),
-    T1_KEYWORD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ),
-    T1_KEYWORD_CALLBACK( "WeightVector", parse_weight_vector ),
-    T1_KEYWORD_CALLBACK( "shareddict",   parse_shared_dict ),
-#endif    
-    T1_KEYWORD_CALLBACK( 0, 0 )
-  };
-
-
-  static
-  FT_Error  parse_dict( T1_Face     face,
-                        T1_Loader*  loader,
-                        FT_Byte*    base,
-                        FT_Long     size )
-  {
-    T1_Parser*  parser   = &loader->parser;
-
-    parser->cursor = base;
-    parser->limit  = base + size;
-    parser->error  = 0;
-
-    {
-      FT_Byte*  cur     = base;
-      FT_Byte*  limit   = cur + size;
-
-      for ( ;cur < limit; cur++ )
-      {
-        /* look for "FontDirectory", which causes problems on some fonts */
-        if ( *cur == 'F' && cur+25 < limit &&
-             strncmp( (char*)cur, "FontDirectory", 13 ) == 0 )
-        {
-          FT_Byte*  cur2;
-          
-          /* skip the "FontDirectory" keyword */
-          cur += 13;
-          cur2 = cur;
-          
-          /* lookup the 'known' keyword */
-          while (cur < limit && *cur != 'k' && strncmp( (char*)cur, "known", 5 ) )
-            cur++;
-          
-          if (cur < limit)
-          {
-            T1_Token_Rec  token;
-            
-            /* skip the "known" keyword and the token following it */
-            cur += 5;
-            loader->parser.cursor = cur;
-            T1_ToToken( &loader->parser, &token );
-            
-            /* if the last token was an array, skip it !! */
-            if (token.type == t1_token_array)
-              cur2 = parser->cursor;
-          }
-          cur = cur2;
-        }
-        /* look for immediates */
-        else if (*cur == '/' && cur+2 < limit)
-        {
-          FT_Byte* cur2;
-          FT_Int   len;
-
-          cur  ++;
-          cur2 = cur;
-          while (cur2 < limit && is_alpha(*cur2)) cur2++;
-          len  = cur2-cur;
-
-          if (len > 0 && len < 22)
-          {
-            if (!loader->fontdata)
-            {
-              if ( strncmp( (char*)cur, "FontInfo", 8 ) == 0 )
-                loader->fontdata = 1;
-            }
-            else
-            {
-              /* now, compare the immediate name to the keyword table */
-              T1_KeyWord*  keyword = (T1_KeyWord*)t1_keywords;
-  
-              for (;;)
-              {
-                FT_Byte*  name;
-  
-                name = (FT_Byte*)keyword->name;
-                if (!name) break;
-  
-                if ( cur[0] == name[0] &&
-                     len == (FT_Int)strlen((const char*)name) )
-                {
-                  FT_Int  n;
-                  for ( n = 1; n < len; n++ )
-                    if (cur[n] != name[n])
-                      break;
-  
-                  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;
-  
-                    cur = parser->cursor;
-                    break;
-                  }
-                }
-                keyword++;
-              }
-            }
-          }
-        }
-      }
-    }
-    return parser->error;
-  }
-
-  static
-  void t1_init_loader( T1_Loader* loader, T1_Face  face )
-  {
-    UNUSED(face);
-
-    MEM_Set( loader, 0, sizeof(*loader) );
-    loader->num_glyphs = 0;
-    loader->num_chars  = 0;
-
-    /* initialize the tables - simply set their 'init' field to 0 */
-    loader->encoding_table.init = 0;
-    loader->charstrings.init    = 0;
-    loader->glyph_names.init    = 0;
-    loader->subrs.init          = 0;
-    loader->fontdata            = 0;
-  }
-
-  static
-  void t1_done_loader( T1_Loader* loader )
-  {
-    T1_Parser*  parser = &loader->parser;
-
-    /* finalize tables */
-    T1_Release_Table( &loader->encoding_table );
-    T1_Release_Table( &loader->charstrings );
-    T1_Release_Table( &loader->glyph_names );
-    T1_Release_Table( &loader->subrs );
-
-    /* finalize parser */
-    T1_Done_Parser( parser );
-  }
-
-  LOCAL_FUNC
-  FT_Error  T1_Open_Face( T1_Face  face )
-  {
-    T1_Loader  loader;
-    T1_Parser* parser;
-    T1_Font*   type1 = &face->type1;
-    FT_Error   error;
-
-    t1_init_loader( &loader, face );
-
-    /* default lenIV */
-    type1->private_dict.lenIV = 4;
-
-    parser = &loader.parser;
-    error = T1_New_Parser( parser, face->root.stream, face->root.memory );
-    if (error) goto Exit;
-
-    error = parse_dict( face, &loader, parser->base_dict, parser->base_len );
-    if (error) goto Exit;
-
-    error = T1_Get_Private_Dict( parser );
-    if (error) goto Exit;
-
-    error = parse_dict( face, &loader, parser->private_dict, parser->private_len );
-    if (error) goto Exit;
-
-    /* now, propagate the subrs, charstrings and glyphnames tables */
-    /* to the Type1 data                                           */
-    type1->num_glyphs = loader.num_glyphs;
-
-    if ( !loader.subrs.init )
-    {
-      FT_ERROR(( "T1.Open_Face: no subrs array in face !!\n" ));
-      error = T1_Err_Invalid_File_Format;
-    }
-
-    if ( !loader.charstrings.init )
-    {
-      FT_ERROR(( "T1.Open_Face: no charstrings array in face !!\n" ));
-      error = T1_Err_Invalid_File_Format;
-    }
-
-    loader.subrs.init  = 0;
-    type1->num_subrs   = loader.num_subrs;
-    type1->subrs_block = loader.subrs.block;
-    type1->subrs       = loader.subrs.elements;
-    type1->subrs_len   = loader.subrs.lengths;
-
-    loader.charstrings.init  = 0;
-    type1->charstrings_block = loader.charstrings.block;
-    type1->charstrings       = loader.charstrings.elements;
-    type1->charstrings_len   = loader.charstrings.lengths;
-
-    /* we copy the glyph names "block" and "elements" fields */
-    /* but the "lengths" field must be released later..      */
-    type1->glyph_names_block    = loader.glyph_names.block;
-    type1->glyph_names          = (FT_String**)loader.glyph_names.elements;
-    loader.glyph_names.block    = 0;
-    loader.glyph_names.elements = 0;
-
-    /* we must now build type1.encoding when we have a custom */
-    /* array..                                                */
-    if ( type1->encoding_type == t1_encoding_array )
-    {
-      FT_Int    charcode, index, min_char, max_char;
-      FT_Byte*  char_name;
-      FT_Byte*  glyph_name;
-
-      /* OK, we do the following : for each element in the encoding */
-      /* table, lookup the index of the glyph having the same name  */
-      /* the index is then stored in type1.encoding.char_index, and */
-      /* a the name to type1.encoding.char_name                     */
-
-      min_char = +32000;
-      max_char = -32000;
-
-      charcode = 0;
-      for ( ; charcode < loader.encoding_table.num_elems; charcode++ )
-      {
-        type1->encoding.char_index[charcode] = 0;
-        type1->encoding.char_name [charcode] = ".notdef";
-
-        char_name = loader.encoding_table.elements[charcode];
-        if (char_name)
-          for ( index = 0; index < type1->num_glyphs; index++ )
-          {
-            glyph_name = (FT_Byte*)type1->glyph_names[index];
-            if ( strcmp( (const char*)char_name,
-                         (const char*)glyph_name ) == 0 )
-            {
-              type1->encoding.char_index[charcode] = index;
-              type1->encoding.char_name [charcode] = (char*)glyph_name;
-
-              if (charcode < min_char) min_char = charcode;
-              if (charcode > max_char) max_char = charcode;
-              break;
-            }
-          }
-      }
-      type1->encoding.code_first = min_char;
-      type1->encoding.code_last  = max_char;
-      type1->encoding.num_chars  = loader.num_chars;
-   }
-
-  Exit:
-    t1_done_loader( &loader );
-    return error;
-  }
--- a/src/type1z/t1load.h
+++ /dev/null
@@ -1,77 +1,0 @@
-/*******************************************************************
- *
- *  t1load.h                                                    2.0
- *
- *    Type1 Loader.
- *
- *  Copyright 1996-2000 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used
- *  modified and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- ******************************************************************/
-
-#ifndef T1LOAD_H
-#define T1LOAD_H
-
-#include <freetype/internal/ftstream.h>
-#include <freetype/internal/t1types.h>
-#include <freetype/ftmm.h>
-#include <t1parse.h>
-
-#ifdef __cplusplus
-  extern "C" {
-#endif
-
-  typedef struct T1_Loader_
-  {
-    T1_Parser        parser;          /* parser used to read the stream */
-
-    FT_Int           num_chars;       /* number of characters in encoding */
-    T1_Table         encoding_table;  /* T1_Table used to store the       */
-                                /* encoding character names         */
-
-    FT_Int           num_glyphs;
-    T1_Table         glyph_names;
-    T1_Table         charstrings;
-
-    FT_Int           num_subrs;
-    T1_Table         subrs;
-    FT_Bool          fontdata;
-
-  } T1_Loader;
-
-  LOCAL_DEF
-  FT_Error  T1_Open_Face( T1_Face  face );
-
-#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
-  LOCAL_DEF
-  FT_Error  T1_Get_Multi_Master( T1_Face           face,
-                                 FT_Multi_Master*  master );
-
-  LOCAL_DEF
-  FT_Error  T1_Set_MM_Blend( T1_Face    face,
-                             FT_UInt    num_coords,
-                             FT_Fixed*  coords );
-
-  LOCAL_DEF
-  FT_Error  T1_Set_MM_Design( T1_Face   face,
-                              FT_UInt   num_coords,
-                              FT_Long*  coords );
-
-  LOCAL_DEF
-  void  T1_Done_Blend( T1_Face  face );
-#endif
-
-#ifdef __cplusplus
-  }
-#endif
-
-#endif /* T1LOAD_H */
-
-
-/* END */
--- a/src/type1z/t1objs.c
+++ /dev/null
@@ -1,361 +1,0 @@
-/*******************************************************************
- *
- *  t1objs.c                                                     1.0
- *
- *    Type1 Objects manager.
- *
- *  Copyright 1996-1998 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used
- *  modified and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- ******************************************************************/
-
-#include <freetype/internal/ftdebug.h>
-#include <freetype/internal/ftstream.h>
-
-#include <t1gload.h>
-#include <t1load.h>
-#include <freetype/internal/psnames.h>
-#include <t1afm.h>
-
-/* Required by tracing mode */
-#undef   FT_COMPONENT
-#define  FT_COMPONENT  trace_t1objs
-
-/*******************************************************************
- *                                                                 *
- *                         FACE  FUNCTIONS                         *
- *                                                                 *
- *                                                                 *
- *******************************************************************/
-
-/*******************************************************************
- *
- *  <Function> T1_Done_Face
- *
- *  <Description>
- *     The face object destructor.
- *
- *  <Input>
- *     face  :: typeless pointer to the face object to destroy
- *
- *  <Return>
- *     Error code.
- *
- ******************************************************************/
-
-  LOCAL_FUNC
-  void  T1_Done_Face( T1_Face  face )
-  {
-    FT_Memory  memory;
-    T1_Font*   type1 = &face->type1;
-
-    if (face)
-    {
-      memory = face->root.memory;
-
-#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
-      /* release multiple masters information */
-      T1_Done_Blend( face );
-      face->blend = 0;
-#endif
-
-      /* release font info strings */
-      {
-        T1_FontInfo*  info = &type1->font_info;
-
-        FREE( info->version );
-        FREE( info->notice );
-        FREE( info->full_name );
-        FREE( info->family_name );
-        FREE( info->weight );
-      }
-
-      /* release top dictionary */
-      FREE( type1->charstrings_len );
-      FREE( type1->charstrings );
-      FREE( type1->glyph_names );
-
-      FREE( type1->subrs );
-      FREE( type1->subrs_len );
-
-      FREE( type1->subrs_block );
-      FREE( type1->charstrings_block );
-      FREE( type1->glyph_names_block );
-
-      FREE( type1->encoding.char_index );
-      FREE( type1->font_name );
-
-#ifndef T1_CONFIG_OPTION_NO_AFM
-      /* release afm data if present */
-      if ( face->afm_data)
-        T1_Done_AFM( memory, (T1_AFM*)face->afm_data );
-#endif
-
-      /* release unicode map, if any */
-      FREE( face->unicode_map.maps );
-      face->unicode_map.num_maps = 0;
-
-      face->root.family_name = 0;
-      face->root.style_name  = 0;
-    }
-  }
-
-/*******************************************************************
- *
- *  <Function>  T1_Init_Face
- *
- *  <Description>
- *     The face object constructor.
- *
- *  <Input>
- *     face  ::  face record to build
- *     Input ::  input stream where to load font data
- *
- *  <Return>
- *     Error code.
- *
- ******************************************************************/
-
-  LOCAL_FUNC
-  FT_Error  T1_Init_Face( FT_Stream      stream,
-                          T1_Face        face,
-                          FT_Int         face_index,
-                          FT_Int         num_params,
-                          FT_Parameter*  params )
-  {
-    FT_Error      error;
-    PSNames_Interface*  psnames;
-
-    UNUSED(num_params);
-    UNUSED(params);
-    UNUSED(face_index);
-    UNUSED(stream);
-
-    face->root.num_faces = 1;
-
-    psnames = (PSNames_Interface*)face->psnames;
-    if (!psnames)
-    {
-      psnames = (PSNames_Interface*)
-                 FT_Get_Module_Interface( FT_FACE_LIBRARY(face), "psnames" );
-
-      face->psnames = psnames;
-    }
-
-    /* open the tokenizer, this will also check the font format */
-    error = T1_Open_Face( face );
-    if (error) goto Exit;
-
-    /* if we just wanted to check the format, leave successfully now */
-    if (face_index < 0)
-      goto Exit;
-
-    /* check the face index */
-    if ( face_index != 0 )
-    {
-      FT_ERROR(( "T1.Init_Face : invalid face index\n" ));
-      error = T1_Err_Invalid_Argument;
-      goto Exit;
-    }
-
-    /* Now, load the font program into the face object */
-    {
-      /* Init the face object fields */
-      /* Now set up root face fields */
-      {
-        FT_Face  root = (FT_Face)&face->root;
-
-        root->num_glyphs   = face->type1.num_glyphs;
-        root->num_charmaps = 1;
-
-        root->face_index = face_index;
-        root->face_flags = FT_FACE_FLAG_SCALABLE;
-
-        root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
-
-        if ( face->type1.font_info.is_fixed_pitch )
-          root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
-
-        if ( face->blend )
-          root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
-
-        /* XXX : TO DO - add kerning with .afm support */
-
-        /* get style name - be careful, some broken fonts only */
-        /* have a /FontName dictionary entry .. !!             */
-        root->family_name = face->type1.font_info.family_name;
-        if (root->family_name)
-        {
-          char*  full   = face->type1.font_info.full_name;
-          char*  family = root->family_name;
-
-          while ( *family && *full == *family )
-          {
-            family++;
-            full++;
-          }
-
-          root->style_name = ( *full == ' ' ? full+1 : "Regular" );
-        }
-        else
-        {
-          /* do we have a /FontName ?? */
-          if (face->type1.font_name)
-          {
-            root->family_name = face->type1.font_name;
-            root->style_name  = "Regular";
-          }
-        }
-
-        /* no embedded bitmap support */
-        root->num_fixed_sizes = 0;
-        root->available_sizes = 0;
-
-        root->bbox         = face->type1.font_bbox;
-        root->units_per_EM = 1000;
-        root->ascender     =  (FT_Short)face->type1.font_bbox.yMax;
-        root->descender    = -(FT_Short)face->type1.font_bbox.yMin;
-        root->height       = ((root->ascender + root->descender)*12)/10;
-
-        /* now compute the maximum advance width */
-
-        root->max_advance_width = face->type1.private_dict.standard_width[0];
-
-        /* compute max advance width for proportional fonts */
-        if (!face->type1.font_info.is_fixed_pitch)
-        {
-          FT_Int  max_advance;
-
-          error = T1_Compute_Max_Advance( face, &max_advance );
-
-          /* in case of error, keep the standard width */
-          if (!error)
-            root->max_advance_width = max_advance;
-          else
-            error = 0;   /* clear error */
-        }
-
-        root->max_advance_height = root->height;
-
-        root->underline_position  = face->type1.font_info.underline_position;
-        root->underline_thickness = face->type1.font_info.underline_thickness;
-
-        root->max_points   = 0;
-        root->max_contours = 0;
-      }
-    }
-
-    /* charmap support - synthetize unicode charmap when possible */
-    {
-      FT_Face      root    = &face->root;
-      FT_CharMap   charmap = face->charmaprecs;
-
-      /* synthesize a Unicode charmap if there is support in the "psnames" */
-      /* module..                                                          */
-      if (face->psnames)
-      {
-        PSNames_Interface*  psnames = (PSNames_Interface*)face->psnames;
-        if (psnames->unicode_value)
-        {
-          error = psnames->build_unicodes( root->memory,
-                                           face->type1.num_glyphs,
-                                           (const char**)face->type1.glyph_names,
-                                           &face->unicode_map );
-          if (!error)
-          {
-            root->charmap        = charmap;
-            charmap->face        = (FT_Face)face;
-            charmap->encoding    = ft_encoding_unicode;
-            charmap->platform_id = 3;
-            charmap->encoding_id = 1;
-            charmap++;
-          }
-
-          /* simply clear the error in case of failure (which really) */
-          /* means that out of memory or no unicode glyph names       */
-          error = 0;
-        }
-      }
-
-      /* now, support either the standard, expert, or custom encodings */
-      charmap->face        = (FT_Face)face;
-      charmap->platform_id = 7;  /* a new platform id for Adobe fonts ?? */
-
-      switch (face->type1.encoding_type)
-      {
-        case t1_encoding_standard:
-          charmap->encoding    = ft_encoding_adobe_standard;
-          charmap->encoding_id = 0;
-          break;
-
-        case t1_encoding_expert:
-          charmap->encoding    = ft_encoding_adobe_expert;
-          charmap->encoding_id = 1;
-          break;
-
-        default:
-          charmap->encoding    = ft_encoding_adobe_custom;
-          charmap->encoding_id = 2;
-          break;
-      }
-
-      root->charmaps = face->charmaps;
-      root->num_charmaps = charmap - face->charmaprecs + 1;
-      face->charmaps[0] = &face->charmaprecs[0];
-      face->charmaps[1] = &face->charmaprecs[1];
-    }
-  Exit:
-    return error;
-  }
-
-
-/*******************************************************************
- *
- *  <Function>  T1_Init_Driver
- *
- *  <Description>
- *     Initialise a given Type 1 driver object
- *
- *  <Input>
- *     driver ::  handle to target driver object
- *
- *  <Return>
- *     Error code.
- *
- ******************************************************************/
-
-  LOCAL_FUNC
-  FT_Error  T1_Init_Driver( T1_Driver  driver )
-  {
-    UNUSED(driver);
-    return T1_Err_Ok;
-  }
-
-
-
-/*******************************************************************
- *
- *  <Function> T1_Done_Driver
- *
- *  <Description>
- *     finalise a given Type 1 driver
- *
- *  <Input>
- *     driver  :: handle to target Type 1 driver
- *
- ******************************************************************/
-
-  LOCAL_DEF
-  void  T1_Done_Driver( T1_Driver  driver )
-  {
-    UNUSED(driver);
-  }
-
-
-/* END */
--- a/src/type1z/t1objs.h
+++ /dev/null
@@ -1,215 +1,0 @@
-/*******************************************************************
- *
- *  t1objs.h                                                    1.0
- *
- *    Type1 objects definition.
- *
- *  Copyright 1996-1999 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used
- *  modified and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- ******************************************************************/
-
-#ifndef T1OBJS_H
-#define T1OBJS_H
-
-#include <freetype/internal/ftobjs.h>
-#include <freetype/config/ftconfig.h>
-#include <freetype/internal/t1errors.h>
-#include <freetype/internal/t1types.h>
-
-#ifdef __cplusplus
-  extern "C" {
-#endif
-
-  /* The following structures must be defined by the hinter */
-  typedef struct T1_Size_Hints_   T1_Size_Hints;
-  typedef struct T1_Glyph_Hints_  T1_Glyph_Hints;
-
-  /***********************************************************************/
-  /*                                                                     */
-  /* <Type> T1_Driver                                                    */
-  /*                                                                     */
-  /* <Description>                                                       */
-  /*    A handle to a Type 1 driver object.                              */
-  /*                                                                     */
-  typedef struct T1_DriverRec_   *T1_Driver;
-
-
-  /***********************************************************************/
-  /*                                                                     */
-  /* <Type> T1_Size                                                      */
-  /*                                                                     */
-  /* <Description>                                                       */
-  /*    A handle to a Type 1 size object.                                */
-  /*                                                                     */
-  typedef struct T1_SizeRec_*  T1_Size;
-
-
-  /***********************************************************************/
-  /*                                                                     */
-  /* <Type> T1_GlyphSlot                                                 */
-  /*                                                                     */
-  /* <Description>                                                       */
-  /*    A handle to a Type 1 glyph slot object.                          */
-  /*                                                                     */
-  typedef struct T1_GlyphSlotRec_*  T1_GlyphSlot;
-
-
-  /***********************************************************************/
-  /*                                                                     */
-  /* <Type> T1_CharMap                                                   */
-  /*                                                                     */
-  /* <Description>                                                       */
-  /*    A handle to a Type 1 character mapping object.                   */
-  /*                                                                     */
-  /* <Note>                                                              */
-  /*    The Type 1 format doesn't use a charmap but an encoding table.   */
-  /*    The driver is responsible for making up charmap objects          */
-  /*    corresponding to these tables..                                  */
-  /*                                                                     */
-  typedef struct T1_CharMapRec_*   T1_CharMap;
-
-
-
- /**************************************************************************/
- /*                                                                        */
- /*    NOW BEGINS THE TYPE1 SPECIFIC STUFF ..............................  */
- /*                                                                        */
- /**************************************************************************/
-
-
-  /***************************************************/
-  /*                                                 */
-  /*  T1_Size :                                      */
-  /*                                                 */
-  /*    Type 1 size record..                         */
-  /*                                                 */
-
-  typedef struct T1_SizeRec_
-  {
-    FT_SizeRec      root;
-    FT_Bool         valid;
-    T1_Size_Hints*  hints;  /* defined in the hinter. This allows */
-                            /* us to experiment with different    */
-                            /* hinting schemes without having to  */
-                            /* change 't1objs' each time..        */
-  } T1_SizeRec;
-
-
-
-  /***************************************************/
-  /*                                                 */
-  /*  T1_GlyphSlot :                                 */
-  /*                                                 */
-  /*    TrueDoc glyph record..                       */
-  /*                                                 */
-
-  typedef struct T1_GlyphSlotRec_
-  {
-    FT_GlyphSlotRec  root;
-
-    FT_Bool          hint;
-    FT_Bool          scaled;
-
-    FT_Int           max_points;
-    FT_Int           max_contours;
-
-    FT_Fixed         x_scale;
-    FT_Fixed         y_scale;
-
-    T1_Glyph_Hints*  hints;  /* defined in the hinter */
-
-  } T1_GlyphSlotRec;
-
-
-/*******************************************************************
- *
- *  <Function>  T1_Init_Face
- *
- *  <Description>
- *     Initialise a given Type 1 face object
- *
- *  <Input>
- *     face_index :: index of font face in resource
- *     resource   :: source font resource
- *     face       ::  face record to build
- *
- *  <Return>
- *     Error code.
- *
- ******************************************************************/
-
-  LOCAL_DEF
-  FT_Error  T1_Init_Face( FT_Stream     stream,
-                          T1_Face       face,
-                          FT_Int        face_index,
-                          FT_Int        num_params,
-                          FT_Parameter* params );
-
-
-
-/*******************************************************************
- *
- *  <Function> T1_Done_Face
- *
- *  <Description>
- *     Finalise a given face object
- *
- *  <Input>
- *     face  :: handle  to the face object to destroy
- *
- ******************************************************************/
-
-  LOCAL_DEF
-  void  T1_Done_Face( T1_Face  face );
-
-
-/*******************************************************************
- *
- *  <Function>  T1_Init_Driver
- *
- *  <Description>
- *     Initialise a given Type 1 driver object
- *
- *  <Input>
- *     driver ::  handle to target driver object
- *
- *  <Return>
- *     Error code.
- *
- ******************************************************************/
-
-  LOCAL_DEF
-  FT_Error  T1_Init_Driver( T1_Driver  driver );
-
-
-
-/*******************************************************************
- *
- *  <Function> T1_Done_Driver
- *
- *  <Description>
- *     finalise a given Type 1 driver
- *
- *  <Input>
- *     driver  :: handle to target Type 1 driver
- *
- ******************************************************************/
-
-  LOCAL_DEF
-  void  T1_Done_Driver( T1_Driver  driver );
-
-#ifdef __cplusplus
-  }
-#endif
-
-#endif /* T1OBJS_H */
-
-
-/* END */
--- a/src/type1z/t1parse.c
+++ /dev/null
@@ -1,1269 +1,0 @@
-/*******************************************************************
- *
- *  t1parse.c                                                   2.0
- *
- *    Type1 parser.
- *
- *  Copyright 1996-1998 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used
- *  modified and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- *  The Type 1 parser is in charge of the following:
- *
- *   - provide an implementation of a growing sequence of
- *     objects called a T1_Table (used to build various tables
- *     needed by the loader).
- *
- *   - opening .pfb and .pfa files to extract their top-level
- *     and private dictionaries
- *
- *   - read numbers, arrays & strings from any dictionary
- *
- *  See "t1load.c" to see how data is loaded from the font file
- *
- ******************************************************************/
-
-#include <freetype/internal/ftdebug.h>
-#include <freetype/internal/ftcalc.h>
-#include <freetype/internal/ftobjs.h>
-#include <freetype/internal/ftstream.h>
-#include <freetype/internal/t1errors.h>
-#include <t1parse.h>
-
-#undef FT_COMPONENT
-#define FT_COMPONENT  trace_t1load
-
-/*************************************************************************/
-/*************************************************************************/
-/*************************************************************************/
-/*****                                                               *****/
-/*****           IMPLEMENTATION OF T1_TABLE OBJECT                   *****/
-/*****                                                               *****/
-/*****                                                               *****/
-/*************************************************************************/
-/*************************************************************************/
-/*************************************************************************/
-
-
-/*************************************************************************/
-/*                                                                       */
-/* <Function> T1_New_Table                                               */
-/*                                                                       */
-/* <Description>                                                         */
-/*    Initialise a T1_Table.                                             */
-/*                                                                       */
-/* <Input>                                                               */
-/*    table  :: address of target table                                  */
-/*    count  :: table size = maximum number of elements                  */
-/*    memory :: memory object to use for all subsequent reallocations    */
-/*                                                                       */
-/* <Return>                                                              */
-/*    Error code. 0 means success                                        */
-/*                                                                       */
-
-  LOCAL_FUNC
-  FT_Error  T1_New_Table( T1_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;
-  }
-
-
-
-/*************************************************************************/
-/*                                                                       */
-/* <Function> T1_Add_Table                                               */
-/*                                                                       */
-/* <Description>                                                         */
-/*    Adds an object to a T1_Table, possibly growing its memory block    */
-/*                                                                       */
-/* <Input>                                                               */
-/*    table  :: target table                                             */
-/*    index  :: index of object in table                                 */
-/*    object :: address of object to copy in memory                      */
-/*    length :: length in bytes of source object                         */
-/*                                                                       */
-/* <Return>                                                              */
-/*    Error code. 0 means success. An error is returned when a           */
-/*    realloc failed..                                                   */
-/*                                                                       */
-
-
-      static void  shift_elements( T1_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( T1_Table*  table,
-                                     FT_Int     new_size )
-      {
-        FT_Memory  memory   = table->memory;
-        FT_Byte*   old_base = table->block;
-        FT_Error   error;
-
-        /* realloc the base block */
-        if ( REALLOC( table->block, table->capacity, new_size ) )
-          return error;
-
-        table->capacity = new_size;
-
-        /* shift all offsets when needed */
-        if (old_base)
-          shift_elements( table, old_base );
-
-        return T1_Err_Ok;
-      }
-
-
-
-  LOCAL_FUNC
-  FT_Error  T1_Add_Table( T1_Table*  table,
-                          FT_Int     index,
-                          void*      object,
-                          FT_Int     length )
-  {
-	if (index < 0 || index > table->max_elems)
-    {
-	  FT_ERROR(( "T1.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;
-  }
-
-
-/*************************************************************************/
-/*                                                                       */
-/* <Function> T1_Done_Table                                              */
-/*                                                                       */
-/* <Description>                                                         */
-/*    Finalise a T1_Table. (realloc it to its current cursor).           */
-/*                                                                       */
-/* <Input>                                                               */
-/*    table :: 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.  */
-/*                                                                       */
-#if 0
-  LOCAL_FUNC
-  void  T1_Done_Table( T1_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
-
-  LOCAL_FUNC
-  void  T1_Release_Table( T1_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                             *****/
-/*****                                                               *****/
-/*****                                                               *****/
-/*************************************************************************/
-/*************************************************************************/
-/*************************************************************************/
-
-  #define IS_T1_WHITESPACE(c)  ( (c) == ' '  || (c) == '\t' )
-  #define IS_T1_LINESPACE(c)   ( (c) == '\r' || (c) == '\n' )
-
-  #define IS_T1_SPACE(c)  ( IS_T1_WHITESPACE(c) || IS_T1_LINESPACE(c) )
-
-  LOCAL_FUNC
-  void     T1_Skip_Spaces( T1_Parser*  parser )
-  {
-    FT_Byte* cur   = parser->cursor;
-    FT_Byte* limit = parser->limit;
-
-    while (cur < limit)
-    {
-      FT_Byte  c = *cur;
-      if (!IS_T1_SPACE(c))
-        break;
-      cur++;
-    }
-    parser->cursor = cur;
-  }
-
-  LOCAL_FUNC
-  void  T1_ToToken( T1_Parser*     parser,
-                    T1_Token_Rec*  token )
-  {
-    FT_Byte*  cur;
-    FT_Byte*  limit;
-    FT_Byte   starter, ender;
-    FT_Int    embed;
-
-    token->type  = t1_token_none;
-    token->start = 0;
-    token->limit = 0;
-
-    /* first of all, skip space */
-    T1_Skip_Spaces(parser);
-
-    cur   = parser->cursor;
-    limit = parser->limit;
-
-    if ( cur < limit )
-    {
-      switch (*cur)
-      {
-        /************* check for strings ***********************/
-        case '(':
-          token->type = t1_token_string;
-          ender = ')';
-          goto Lookup_Ender;
-
-        /************* check for programs/array ****************/
-        case '{':
-          token->type = t1_token_array;
-          ender = '}';
-          goto Lookup_Ender;
-
-        /************* check for table/array ******************/
-        case '[':
-          token->type = t1_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  = t1_token_any;
-          while (cur < limit && !IS_T1_SPACE(*cur))
-            cur++;
-
-          token->limit = cur;
-      }
-
-      if (!token->limit)
-      {
-        token->start = 0;
-        token->type  = t1_token_none;
-      }
-
-      parser->cursor = cur;
-    }
-  }
-
-
-  LOCAL_FUNC
-  void  T1_ToTokenArray( T1_Parser*     parser,
-                         T1_Token_Rec*  tokens,
-                         FT_UInt        max_tokens,
-                         FT_Int        *pnum_tokens )
-  {
-    T1_Token_Rec  master;
-
-    *pnum_tokens = -1;
-
-    T1_ToToken( parser, &master );
-    if (master.type == t1_token_array)
-    {
-      FT_Byte*       old_cursor = parser->cursor;
-      FT_Byte*       old_limit  = parser->limit;
-      T1_Token_Rec*  cur        = tokens;
-      T1_Token_Rec*  limit      = cur + max_tokens;
-
-      parser->cursor = master.start;
-      parser->limit  = master.limit;
-
-      while (parser->cursor < parser->limit)
-      {
-        T1_Token_Rec  token;
-        
-        T1_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 )
-  {
-    FT_Long  result = 0;
-    FT_Byte* cur    = *cursor;
-    FT_Byte  c, d;
-
-    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, read the integer part */
-    result  = t1_toint( &cur, limit ) << 16;
-    num     = 0;
-    divider = 1;
-
-    if (result < 0)
-    {
-      sign   = 1;
-      result = -result;
-    }
-    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
-
-  static
-  int  t1_tobool( FT_Byte* *cursor, FT_Byte* limit )
-  {
-    FT_Byte*  cur    = *cursor;
-    FT_Bool   result = 0;
-
-    /* return 1 if we find a "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;
-  }
-
-
-
- /* Loads a simple field (i.e. non-table) into the current list of objects */
-  LOCAL_FUNC
-  FT_Error  T1_Load_Field( T1_Parser*           parser,
-                           const T1_Field_Rec*  field,
-                           void**               objects,
-                           FT_UInt              max_objects,
-                           FT_ULong*            pflags )
-  {
-    T1_Token_Rec  token;
-    FT_Byte*      cur;
-    FT_Byte*      limit;
-    FT_UInt       count;
-    FT_UInt       index;
-    FT_Error      error;
-
-    T1_ToToken( parser, &token );
-    if (!token.type)
-      goto Fail;
-
-    count = 1;
-    index = 0;
-    cur   = token.start;
-    limit = token.limit;
-
-    if (token.type == t1_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 t1_field_bool:
-          {
-            val = t1_tobool( &cur, limit );
-            goto Store_Integer;
-          }
-
-        case t1_field_fixed:
-          {
-            val = t1_tofixed( &cur, limit, 3 );
-            goto Store_Integer;
-          }
-
-        case t1_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;
-              default: *(FT_Long*)q   = val;
-            }
-          }
-          break;
-
-        case t1_field_string:
-          {
-            FT_Memory  memory = parser->memory;
-            FT_UInt    len    = limit-cur;
-            
-            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    = 0;
-
-  Exit:
-    return error;
-  Fail:
-    error = T1_Err_Invalid_File_Format;
-    goto Exit;
-  }
-
-
-#define T1_MAX_TABLE_ELEMENTS  32
-
-  LOCAL_FUNC
-  FT_Error  T1_Load_Field_Table( T1_Parser*           parser,
-                                 const T1_Field_Rec*  field,
-                                 void**               objects,
-                                 FT_UInt              max_objects,
-                                 FT_ULong*            pflags )
-  {
-    T1_Token_Rec  elements[T1_MAX_TABLE_ELEMENTS];
-    T1_Token_Rec* token;
-    FT_Int        num_elements;
-    FT_Error      error = 0;
-    FT_Byte*      old_cursor;
-    FT_Byte*      old_limit;
-    T1_Field_Rec  fieldrec = *(T1_Field_Rec*)field;
-    
-    T1_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;
-      T1_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  T1_ToInt  ( T1_Parser*  parser )
-  {
-    return t1_toint( &parser->cursor, parser->limit );
-  }
-
-
-  LOCAL_FUNC
-  FT_Long  T1_ToFixed( T1_Parser*  parser, FT_Int power_ten )
-  {
-    return t1_tofixed( &parser->cursor, parser->limit, power_ten );
-  }
-
-
-  LOCAL_FUNC
-  FT_Int  T1_ToCoordArray( T1_Parser* parser,
-                           FT_Int     max_coords,
-                           FT_Short*  coords )
-  {
-    return t1_tocoordarray( &parser->cursor, parser->limit, max_coords, coords );
-  }
-
-
-  LOCAL_FUNC
-  FT_Int  T1_ToFixedArray( T1_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*  T1_ToString( T1_Parser* parser )
-  {
-    return t1_tostring( &parser->cursor, parser->limit, parser->memory );
-  }
-
-
-  LOCAL_FUNC
-  FT_Bool   T1_ToBool( T1_Parser* parser )
-  {
-    return t1_tobool( &parser->cursor, parser->limit );
-  }
-#endif
-
-
-  static
-  FT_Error  read_pfb_tag( FT_Stream  stream, FT_UShort *tag, FT_Long*  size )
-  {
-    FT_Error  error;
-
-    if (READ_UShort(*tag)) goto Exit;
-    if (*tag == 0x8001 || *tag == 0x8002)
-    {
-      FT_Long  asize;
-
-      if (READ_ULong(asize)) goto Exit;
-
-      /* swap between big and little endianness */
-      *size  = ((asize & 0xFF000000) >> 24) |
-               ((asize & 0x00FF0000) >> 8 ) |
-               ((asize & 0x0000FF00) << 8 ) |
-               ((asize & 0x000000FF) << 24);
-    }
-
-  Exit:
-    return error;
-  }
-
-
-
-  LOCAL_FUNC
-  FT_Error  T1_New_Parser( T1_Parser*  parser,
-                           FT_Stream   stream,
-                           FT_Memory   memory )
-  {
-    FT_Error  error;
-    FT_UShort tag;
-    FT_Long   size;
-
-    parser->stream       = stream;
-    parser->memory       = memory;
-    parser->base_len     = 0;
-    parser->base_dict    = 0;
-    parser->private_len  = 0;
-    parser->private_dict = 0;
-    parser->in_pfb       = 0;
-    parser->in_memory    = 0;
-    parser->single_block = 0;
-
-    parser->cursor       = 0;
-    parser->limit        = 0;
-
-    /******************************************************************/
-    /*                                                                */
-    /* Here's a short summary of what is going on :                   */
-    /*                                                                */
-    /*   When creating a new Type 1 parser, we try to locate and      */
-    /*   load the base dictionary when this is possible (i.e. for     */
-    /*   .pfb files). Otherwise, we load the whole font in memory.    */
-    /*                                                                */
-    /*   When "loading" the base dictionary, we only setup pointers   */
-    /*   in the case of a memory-based stream. Otherwise, we allocate */
-    /*   and load the base dict in it.                                */
-    /*                                                                */
-    /*   parser->in_pfb is set when we are in a binary (".pfb") font  */
-    /*   parser->in_memory is set when we have a memory stream.       */
-    /*                                                                */
-
-    /* try to compute the size of the base dictionary    */
-    /* look for a Postscript binary file tag, i.e 0x8001 */
-    if ( FILE_Seek(0L) )
-      goto Exit;
-
-    error = read_pfb_tag( stream, &tag, &size );
-    if (error) goto Exit;
-
-    if (tag != 0x8001)
-    {
-      /* assume that this is a PFA file for now, an error will */
-      /* be produced later when more things are checked        */
-      (void)FILE_Seek(0L);
-      size = stream->size;
-    }
-    else
-      parser->in_pfb = 1;
-
-    /* now, try to load the "size" bytes of the "base" dictionary we */
-    /* found previously                                              */
-
-    /* if it's a memory-based resource, set up pointers */
-    if ( !stream->read )
-    {
-      parser->base_dict = (FT_Byte*)stream->base + stream->pos;
-      parser->base_len  = size;
-      parser->in_memory = 1;
-
-      /* check that the "size" field is valid */
-      if ( FILE_Skip(size) ) goto Exit;
-    }
-    else
-    {
-      /* read segment in memory */
-      if ( ALLOC( parser->base_dict, size )     ||
-           FILE_Read( parser->base_dict, size ) )
-        goto Exit;
-      parser->base_len = size;
-    }
-
-    /* Now check font format, we must see a '%!PS-AdobeFont-1' */
-    /* or a '%!FontType'                                       */
-    {
-      if ( size <= 16 ||
-           ( strncmp( (const char*)parser->base_dict, "%!PS-AdobeFont-1", 16 ) &&
-             strncmp( (const char*)parser->base_dict, "%!FontType", 10 )       ) )
-      {
-        FT_TRACE2(( "Not a Type1 font\n" ));
-        error = FT_Err_Unknown_File_Format;
-      }
-      else
-      {
-        parser->cursor = parser->base_dict;
-        parser->limit  = parser->cursor + parser->base_len;
-      }
-    }
-
-  Exit:
-    if (error && !parser->in_memory)
-      FREE( parser->base_dict );
-
-    return error;
-  }
-
-
-  LOCAL_FUNC
-  void  T1_Done_Parser( T1_Parser*  parser )
-  {
-    FT_Memory   memory = parser->memory;
-
-    /* always free the private dictionary */
-    FREE( parser->private_dict );
-
-    /* free the base dictionary only when we have a disk stream */
-    if (!parser->in_memory)
-      FREE( parser->base_dict );
-  }
-
-
- /* return the value of an hexadecimal digit */
- static
- int  hexa_value( char c )
- {
-   unsigned int  d;
-
-   d = (unsigned int)(c-'0');
-   if ( d <= 9 ) return (int)d;
-
-   d = (unsigned int)(c-'a');
-   if ( d <= 5 ) return (int)(d+10);
-
-   d = (unsigned int)(c-'A');
-   if ( d <= 5 ) return (int)(d+10);
-
-   return -1;
- }
-
-
-  LOCAL_FUNC
-  void  T1_Decrypt( FT_Byte*   buffer,
-                    FT_Int     length,
-                    FT_UShort  seed )
-  {
-    while ( length > 0 )
-    {
-      FT_Byte  plain;
-
-      plain     = (*buffer ^ (seed >> 8));
-      seed      = (*buffer+seed)*52845+22719;
-      *buffer++ = plain;
-      length--;
-    }
-  }
-
-
-  LOCAL_FUNC
-  FT_Error  T1_Get_Private_Dict( T1_Parser*  parser )
-  {
-    FT_Stream  stream = parser->stream;
-    FT_Memory  memory = parser->memory;
-    FT_Error   error  = 0;
-    FT_Long    size;
-
-    if (parser->in_pfb)
-    {
-      /* in the case of the PFB format, the private dictionary can be  */
-      /* made of several segments. We thus first read the number of    */
-      /* segments to compute the total size of the private dictionary  */
-      /* then re-read them into memory..                               */
-      FT_Long    start_pos    = FILE_Pos();
-      FT_UShort  tag;
-      FT_Long    size;
-
-      parser->private_len = 0;
-      for (;;)
-      {
-        error = read_pfb_tag(stream, &tag, &size);
-        if (error) goto Fail;
-
-        if (tag != 0x8002)
-          break;
-
-        parser->private_len += size;
-
-        if ( FILE_Skip(size) )
-          goto Fail;
-      }
-
-      /* Check that we have a private dictionary there */
-      /* and allocate private dictionary buffer        */
-      if ( parser->private_len == 0 )
-      {
-        FT_ERROR(( "T1.Open_Private: invalid private dictionary section\n" ));
-        error = T1_Err_Invalid_File_Format;
-        goto Fail;
-      }
-
-      if ( FILE_Seek( start_pos )                             ||
-           ALLOC( parser->private_dict, parser->private_len ) )
-        goto Fail;
-
-      parser->private_len = 0;
-      for (;;)
-      {
-        error = read_pfb_tag( stream, &tag, &size );
-        if (error || tag != 0x8002) { error = 0; break; }
-
-        if ( FILE_Read( parser->private_dict + parser->private_len, size ) )
-          goto Fail;
-
-        parser->private_len += size;
-      }
-    }
-    else
-    {
-      /* we have already "loaded" the whole PFA font file in memory */
-      /* if this is a memory resource, allocate a new block to hold */
-      /* the private dict. Otherwise, simply overwrite into the     */
-      /* base dict block in the heap..                              */
-
-      /* first of all, look at the "eexec" keyword */
-      FT_Byte*  cur   = parser->base_dict;
-      FT_Byte*  limit = cur + parser->base_len;
-      FT_Byte   c;
-
-      for (;;)
-      {
-        c = cur[0];
-        if (c == 'e' && cur+9 < limit)  /* 9 = 5 letters for 'eexec' + newline + 4 chars */
-        {
-          if ( cur[1] == 'e' && cur[2] == 'x' &&
-               cur[3] == 'e' && cur[4] == 'c' )
-          {
-            cur += 6; /* we skip the newling after the "eexec" */
-
-            /* XXX: Some fonts use DOS-linefeeds, i.e. \r\n, we need to skip */
-            /*      the extra \n when we find it..                           */
-            if (cur[0] == '\n')
-              cur++;
-
-            break;
-          }
-        }
-        cur++;
-        if (cur >= limit)
-        {
-          FT_ERROR(("T1.Open_Private: could not find 'eexec' keyword\n"));
-          error = T1_Err_Invalid_File_Format;
-          goto Exit;
-        }
-      }
-
-      /* now determine wether where to write the _encrypted_ binary private    */
-      /* dictionary. We overwrite the base dictionary for disk-based resources */
-      /* and allocate a new block otherwise                                    */
-
-      size = parser->base_len - (cur-parser->base_dict);
-
-      if ( parser->in_memory )
-      {
-        /* note that we allocate one more byte to put a terminating '0' */
-        if (ALLOC( parser->private_dict, size+1 )) goto Fail;
-        parser->private_len = size;
-      }
-      else
-      {
-        parser->single_block = 1;
-        parser->private_dict = parser->base_dict;
-        parser->private_len  = size;
-        parser->base_dict    = 0;
-        parser->base_len     = 0;
-      }
-
-      /* now determine wether the private dictionary is encoded in binary */
-      /* or hexadecimal ASCII format..                                    */
-      /* and decode it accordingly                                        */
-
-      /* we need to access the next 4 bytes (after the final \r following */
-      /* the 'eexec' keyword..) if they all are hexadecimal digits, then  */
-      /*we have a case of ASCII storage..                                 */
-
-      if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) |
-             hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 )
-      {
-       /* binary encoding - "simply" copy the private dict */
-       MEM_Copy( parser->private_dict, cur, size );
-      }
-      else
-      {
-        /* ASCII hexadecimal encoding.. This blows goats !!.. */
-
-        FT_Byte*  write;
-        FT_Int    count;
-
-        write = parser->private_dict;
-        count = 0;
-
-        for ( ;cur < limit; cur++)
-        {
-          int  hex1;
-
-          /* check for newline */
-          if (cur[0] == '\r' || cur[0] == '\n')
-            continue;
-
-          /* exit if we have a non-hexadecimal digit that isn't a newline */
-          hex1 = hexa_value(cur[0]);
-          if (hex1 < 0 || cur+1 >= limit)
-            break;
-
-          /* otherwise, store byte */
-          *write++ = (hex1 << 4) | hexa_value(cur[1]);
-          count++;
-          cur++;
-        }
-
-        /* put a safeguard */
-        parser->private_len = write - parser->private_dict;
-        *write++ = 0;
-      }
-    }
-
-    /* we now decrypt the encoded binary private dictionary */
-    T1_Decrypt( parser->private_dict, parser->private_len, 55665 );
-    parser->cursor = parser->private_dict;
-    parser->limit  = parser->cursor + parser->private_len;
-
-  Fail:
-  Exit:
-    return error;
-  }
-
--- a/src/type1z/t1parse.h
+++ /dev/null
@@ -1,348 +1,0 @@
-/*******************************************************************
- *
- *  t1parse.h                                                   2.0
- *
- *    Type1 parser.
- *
- *  Copyright 1996-1998 by
- *  David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used
- *  modified and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- *  The Type 1 parser is in charge of the following:
- *
- *   - provide an implementation of a growing sequence of
- *     objects called a T1_Table (used to build various tables
- *     needed by the loader).
- *
- *   - opening .pfb and .pfa files to extract their top-level
- *     and private dictionaries
- *
- *   - read numbers, arrays & strings from any dictionary
- *
- *  See "t1load.c" to see how data is loaded from the font file
- *
- ******************************************************************/
-
-#ifndef T1PARSE_H
-#define T1PARSE_H
-
-#include <freetype/internal/t1types.h>
-
-#ifdef __cplusplus
-  extern "C" {
-#endif
-
-
-  /* simple enumeration type used to identify token types */
-  typedef enum T1_Token_Type_
-  {
-    t1_token_none = 0,
-    t1_token_any,
-    t1_token_string,
-    t1_token_array,
-    
-    /* do not remove */
-    t1_token_max
-    
-  } T1_Token_Type;
-
-  /* a simple structure used to identify tokens */
-  typedef struct T1_Token_Rec_
-  {
-    FT_Byte*       start;   /* first character of token in input stream */
-    FT_Byte*       limit;   /* first character after the token          */
-    T1_Token_Type  type;    /* type of token..                          */
-  
-  } T1_Token_Rec;  
-
-  /* enumeration type used to identify object fields */
-  typedef enum T1_Field_Type_
-  {
-    t1_field_none = 0,
-    t1_field_bool,
-    t1_field_integer,
-    t1_field_fixed,
-    t1_field_string,
-    t1_field_integer_array,
-    t1_field_fixed_array,
-    
-    /* do not remove */
-    t1_field_max
-    
-  } T1_Field_Type;
-
-  /* structure type used to model object fields */
-  typedef struct T1_Field_Rec_
-  {
-    T1_Field_Type  type;          /* type of field                        */
-    FT_UInt        offset;        /* offset of field in object            */
-    FT_UInt        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            */
-   
-  } T1_Field_Rec;
-
-#define T1_FIELD_REF(s,f)  (((s*)0)->f)
-
-#define T1_FIELD_BOOL( _ftype, _fname )               \
-    { t1_field_bool,                                  \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fname),   \
-      sizeof(T1_FIELD_REF(_ftype,_fname)),            \
-      0, 0, 0 }
-
-#define T1_FIELD_NUM( _ftype, _fname )                \
-    { t1_field_integer,                               \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fname),   \
-      sizeof(T1_FIELD_REF(_ftype,_fname)),            \
-      0, 0, 0 }
-
-#define T1_FIELD_FIXED( _ftype, _fname, _power )      \
-    { t1_field_fixed,                                 \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fname),   \
-      sizeof(T1_FIELD_REF(_ftype,_fname)),            \
-      0, 0, 0 }
-
-#define T1_FIELD_STRING( _ftype, _fname )             \
-    { t1_field_string,                                \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fname),   \
-      sizeof(T1_FIELD_REF(_ftype,_fname)),            \
-      0, 0, 0 }
-
-#define T1_FIELD_NUM_ARRAY( _ftype, _fname, _fcount, _fmax ) \
-    { t1_field_integer,                                      \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fname),          \
-      sizeof(T1_FIELD_REF(_ftype,_fname)[0]),                \
-      _fmax,                                                 \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fcount),         \
-      0 }
-
-#define T1_FIELD_FIXED_ARRAY( _ftype, _fname, _fcount, _fmax ) \
-    { t1_field_fixed,                                          \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fname),            \
-      sizeof(T1_FIELD_REF(_ftype,_fname)[0]),                  \
-      _fmax,                                                   \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fcount),           \
-      0 }
-
-#define T1_FIELD_NUM_ARRAY2( _ftype, _fname, _fmax )         \
-    { t1_field_integer,                                      \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fname),          \
-      sizeof(T1_FIELD_REF(_ftype,_fname)[0]),                \
-      _fmax,                                                 \
-      0, 0 }
-
-#define T1_FIELD_FIXED_ARRAY2( _ftype, _fname, _fmax )         \
-    { t1_field_fixed,                                          \
-      (FT_UInt)(char*)&T1_FIELD_REF(_ftype,_fname),            \
-      sizeof(T1_FIELD_REF(_ftype,_fname)[0]),                  \
-      _fmax,                                                   \
-      0, 0 }
-
-
-
-/*************************************************************************
- *
- * <Struct> T1_Table
- *
- * <Description>
- *    A T1_Table is a simple object used to store an array of objects
- *    in a single memory block.
- *
- * <Fields>
- *    block     :: address in memory of the growheap's block. This
- *                 can change between two object adds, due to the use
- *                 of 'realloc'.
- *
- *    cursor    :: current top of the grow heap within its block
- *
- *    capacity  :: current size of the heap block. Increments by 1 Kb
- *
- *    init      :: boolean. set when the table has been initialized
- *                 (the table user should set this field)
- *
- *    max_elems :: maximum number of elements in table
- *    num_elems :: current number of elements in table
- *
- *    elements  :: table of element addresses within the block
- *    lengths   :: table of element sizes within the block
- *
- *    memory    :: memory object used for memory operations (alloc/realloc)
- */
-
-  typedef struct T1_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;
-
-  } T1_Table;
-
-
-/*************************************************************************
- *
- * <Struct> T1_Parser
- *
- * <Description>
- *    A T1_Parser is an object used to parse a Type 1 fonts very
- *    quickly.
- *
- * <Fields>
- *    stream        :: current input stream
- *    memory        :: current memory object
- *
- *    base_dict     :: pointer to top-level dictionary
- *    base_len      :: length in bytes of top dict
- *
- *    private_dict  :: pointer to private dictionary
- *    private_len   :: length in bytes of private dict
- *
- *    in_pfb        :: boolean. Indicates that we're in a .pfb file
- *    in_memory     :: boolean. Indicates a memory-based stream
- *    single_block  :: boolean. Indicates that the private dict
- *                     is stored in lieu of the base dict
- *
- *    cursor        :: current parser cursor
- *    limit         :: current parser limit (first byte after current
- *                     dictionary).
- *
- *    error         :: current parsing error
- */
-  typedef struct T1_Parser_
-  {
-    FT_Stream  stream;
-    FT_Memory  memory;
-
-    FT_Byte*   base_dict;
-    FT_Int     base_len;
-
-    FT_Byte*   private_dict;
-    FT_Int     private_len;
-
-    FT_Byte    in_pfb;
-    FT_Byte    in_memory;
-    FT_Byte    single_block;
-
-    FT_Byte*   cursor;
-    FT_Byte*   limit;
-    FT_Error   error;
-
-  } T1_Parser;
-
-
-  LOCAL_DEF
-  FT_Error  T1_New_Table( T1_Table*  table,
-                          FT_Int     count,
-                          FT_Memory  memory );
-
-
-  LOCAL_DEF
-  FT_Error  T1_Add_Table( T1_Table*  table,
-                          FT_Int     index,
-                          void*      object,
-                          FT_Int     length );
-
-#if 0
-  LOCAL_DEF
-  void  T1_Done_Table( T1_Table*  table );
-#endif
-
-  LOCAL_DEF
-  void  T1_Release_Table( T1_Table*  table );
-
-  LOCAL_DEF
-  FT_Long  T1_ToInt  ( T1_Parser*  parser );
-
-  LOCAL_DEF
-  FT_Long  T1_ToFixed( T1_Parser*  parser, FT_Int  power_ten );
-
-  LOCAL_DEF
-  FT_Int  T1_ToCoordArray( T1_Parser* parser,
-                           FT_Int     max_coords,
-                           FT_Short*  coords );
-
-  LOCAL_DEF
-  FT_Int  T1_ToFixedArray( T1_Parser* parser,
-                           FT_Int     max_values,
-                           FT_Fixed*  values,
-                           FT_Int     power_ten );
-
-#if 0
-  LOCAL_DEF
-  FT_String*  T1_ToString( T1_Parser* parser );
-
-  LOCAL_DEF
-  FT_Bool   T1_ToBool( T1_Parser* parser );
-#endif
-
-
-
-
-
-
-  LOCAL_DEF
-  void      T1_Skip_Spaces( T1_Parser*  parser );
-
-  LOCAL_DEF
-  void      T1_ToToken( T1_Parser*    parser,
-                        T1_Token_Rec* token );
-
-  LOCAL_FUNC
-  void  T1_ToTokenArray( T1_Parser*     parser,
-                         T1_Token_Rec*  tokens,
-                         FT_UInt        max_tokens,
-                         FT_Int*        pnum_tokens );
-
-  LOCAL_DEF
-  FT_Error  T1_Load_Field( T1_Parser*           parser,
-                           const T1_Field_Rec*  field,
-                           void**               objects,
-                           FT_UInt              max_objects,
-                           FT_ULong*            pflags );
-
-  LOCAL_DEF
-  FT_Error  T1_Load_Field_Table( T1_Parser*           parser,
-                                 const T1_Field_Rec*  field,
-                                 void**               objects,
-                                 FT_UInt              max_objects,
-                                 FT_ULong*            pflags );
-
-
-  LOCAL_DEF
-  FT_Error  T1_New_Parser( T1_Parser*  parser,
-                           FT_Stream   stream,
-                           FT_Memory   memory );
-
-  LOCAL_DEF
-  FT_Error  T1_Get_Private_Dict( T1_Parser*  parser );
-
-  LOCAL_DEF
-  void  T1_Decrypt( FT_Byte*   buffer,
-                    FT_Int     length,
-                    FT_UShort  seed );
-
-  LOCAL_DEF
-  void  T1_Done_Parser( T1_Parser*  parser );
-
-#ifdef __cplusplus
-  }
-#endif
-
-#endif /* T1PARSE_H */
-
-
-/* END */
-
--- a/src/type1z/t1tokens.h
+++ /dev/null
@@ -1,125 +1,0 @@
-/*******************************************************************
- *
- *  t1tokens.h
- *
- *  Type 1 tokens definition
- *
- *  Copyright 2000 David Turner, Robert Wilhelm and Werner Lemberg.
- *
- *  This file is part of the FreeType project, and may only be used
- *  modified and distributed under the terms of the FreeType project
- *  license, LICENSE.TXT. By continuing to use, modify or distribute
- *  this file you indicate that you have read the license and
- *  understand and accept it fully.
- *
- *  This file only contains macros that are expanded when compiling
- *  the "t1load.c" source file.
- *
- ******************************************************************/
-
-#undef  T1TYPE
-#define T1TYPE  T1_FontInfo
-
-  T1_FONTINFO_STRING( "version", version )
-  T1_FONTINFO_STRING( "Notice", notice )
-  T1_FONTINFO_STRING( "FullName", full_name )
-  T1_FONTINFO_STRING( "FamilyName", family_name )
-  T1_FONTINFO_STRING( "Weight", weight )
-
-  T1_FONTINFO_NUM( "ItalicAngle", italic_angle )
-  T1_FONTINFO_BOOL( "isFixedPitch", is_fixed_pitch )
-  T1_FONTINFO_NUM( "UnderlinePosition", underline_position )
-  T1_FONTINFO_NUM( "UnderlineThickness", underline_thickness )
-
-#undef  T1TYPE
-#define T1TYPE  T1_Private
-
-  T1_PRIVATE_NUM  ( "UniqueID", unique_id )
-  T1_PRIVATE_NUM  ( "lenIV", lenIV )
-  T1_PRIVATE_NUM  ( "LanguageGroup", language_group )
-  T1_PRIVATE_NUM  ( "password", password )
-  
-  T1_PRIVATE_FIXED( "BlueScale", blue_scale )
-  T1_PRIVATE_NUM  ( "BlueShift", blue_shift )
-  T1_PRIVATE_NUM  ( "BlueFuzz",  blue_fuzz )
-  
-  T1_PRIVATE_NUM_TABLE( "BlueValues", blue_values, 14, num_blue_values )
-  T1_PRIVATE_NUM_TABLE( "OtherBlues", other_blues, 10, num_other_blues )
-  T1_PRIVATE_NUM_TABLE( "FamilyBlues", family_blues, 14, num_family_blues )
-  T1_PRIVATE_NUM_TABLE( "FamilyOtherBlues", family_other_blues, 10, num_family_other_blues )
-
-  T1_PRIVATE_NUM_TABLE2( "StdHW", standard_width,  1 )
-  T1_PRIVATE_NUM_TABLE2( "StdVW", standard_height, 1 )
-  T1_PRIVATE_NUM_TABLE2( "MinFeature", min_feature, 2 )
-  
-  T1_PRIVATE_NUM_TABLE ( "StemSnapH", snap_widths, 12, num_snap_widths )
-  T1_PRIVATE_NUM_TABLE ( "StemSnapV", snap_heights, 12, num_snap_heights )
-
-#undef  T1TYPE
-#define T1TYPE  T1_Font
-
-  T1_TOPDICT_NUM( "PaintType", paint_type )
-  T1_TOPDICT_NUM( "FontType", font_type )
-  T1_TOPDICT_NUM( "StrokeWidth", stroke_width )
-
-#if 0
- /* define the font info dictionary parsing callbacks */
-#undef  FACE
-#define FACE  (face->type1.font_info)
-
-  PARSE_STRING("version",version)
-  PARSE_STRING("Notice",notice)
-  PARSE_STRING("FullName",full_name)
-  PARSE_STRING("FamilyName",family_name)
-  PARSE_STRING("Weight",weight)
-
-  PARSE_INT("ItalicAngle",italic_angle)
-  PARSE_BOOL("isFixedPitch",is_fixed_pitch)
-  PARSE_NUM("UnderlinePosition",underline_position,FT_Short)
-  PARSE_NUM("UnderlineThickness",underline_thickness,FT_UShort)
-
- /* define the private dict parsing callbacks */
-
-#undef  FACE
-#define FACE  (face->type1.private_dict)
-
-   PARSE_INT("UniqueID",unique_id)
-   PARSE_INT("lenIV",lenIV)
-
-   PARSE_COORDS( "BlueValues", num_blues,       14, blue_values)
-   PARSE_COORDS( "OtherBlues", num_other_blues, 10, other_blues)
-
-   PARSE_COORDS( "FamilyBlues", num_family_blues,       14, family_blues)
-   PARSE_COORDS( "FamilyOtherBlues", num_family_other_blues, 10, family_other_blues)
-
-   PARSE_FIXED( "BlueScale", blue_scale)
-   PARSE_INT( "BlueShift", blue_shift)
-
-   PARSE_INT( "BlueFuzz", blue_fuzz)
-
-   PARSE_COORDS2( "StdHW", 1, standard_width  )
-   PARSE_COORDS2( "StdVW", 1, standard_height )
-
-   PARSE_COORDS( "StemSnapH", num_snap_widths,  12, stem_snap_widths )
-   PARSE_COORDS( "StemSnapV", num_snap_heights, 12, stem_snap_heights )
-
-   PARSE_INT( "LanguageGroup", language_group )
-   PARSE_INT( "password", password )
-   PARSE_COORDS2( "MinFeature", 2, min_feature )
-
- /* define the top-level dictionary parsing callbacks */
-
-#undef  FACE
-#define FACE  (face->type1)
-
-
-/* PARSE_STRING( "FontName", font_name ) -- handled by special routine */
-   PARSE_NUM( "PaintType", paint_type, FT_Byte )
-   PARSE_NUM( "FontType", font_type, FT_Byte )
-   PARSE_FIXEDS2( "FontMatrix", 4, font_matrix )
-/*  PARSE_COORDS2( "FontBBox", 4, font_bbox ) -- handled by special func */
-   PARSE_INT( "StrokeWidth", stroke_width )
-
-#undef FACE
-#endif
-
--- a/src/type1z/type1z.c
+++ b/src/type1z/type1z.c
@@ -29,13 +29,13 @@
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
 
-#include <t1parse.c>
-#include <t1load.c>
-#include <t1objs.c>
-#include <t1driver.c>
-#include <t1gload.c>
+#include <z1parse.c>
+#include <z1load.c>
+#include <z1objs.c>
+#include <z1driver.c>
+#include <z1gload.c>
 
-#ifndef T1_CONFIG_OPTION_NO_AFM
-#include <t1afm.c>
+#ifndef Z1_CONFIG_OPTION_NO_AFM
+#include <z1afm.c>
 #endif
 
--- /dev/null
+++ b/src/type1z/z1afm.c
@@ -1,0 +1,229 @@
+/***************************************************************************
+ *
+ * t1afm.c  - support for reading Type 1 AFM files
+ *
+ *
+ ***************************************************************************/
+
+#include <z1afm.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/t1types.h>
+#include <stdlib.h>  /* for qsort */
+
+  LOCAL_FUNC
+  void  Z1_Done_AFM( FT_Memory memory, Z1_AFM*  afm )
+  {
+    FREE( afm->kern_pairs );
+    afm->num_pairs = 0;
+  }
+
+#undef  IS_KERN_PAIR
+#define IS_KERN_PAIR(p)  ( p[0] == 'K'  &&  p[1] == 'P' )
+
+#define IS_ALPHANUM(c)  ( (c >= 'A' && c <= 'Z') || \
+                          (c >= 'a' && c <= 'z') || \
+                          (c >= '0' && c <= '9') || \
+                          (c == '_' && c == '.') )
+
+ /* read a glyph name and return the equivalent glyph index */
+  static
+  FT_UInt  afm_atoindex( FT_Byte*  *start, FT_Byte*  limit, T1_Font*  type1 )
+  {
+    FT_Byte* p = *start;
+    FT_Int   len;
+    FT_UInt  result = 0;
+    char     temp[64];
+
+    /* skip whitespace */
+    while ( (*p == ' ' || *p == '\t' || *p == ':' || *p == ';') && p < limit )
+      p++;
+    *start = p;
+
+    /* now, read glyph name */
+    while ( IS_ALPHANUM(*p) && p < limit ) p++;
+    len = p - *start;
+    if (len > 0 && len < 64)
+    {
+      FT_Int  n;
+
+      /* copy glyph name to intermediate array */
+      MEM_Copy( temp, *start, len );
+      temp[len] = 0;
+
+      /* lookup glyph name in face array */
+      for ( n = 0; n < type1->num_glyphs; n++ )
+      {
+        char*  gname = (char*)type1->glyph_names[n];
+
+        if ( gname && gname[0] == temp[0] && strcmp(gname,temp) == 0 )
+        {
+          result = n;
+          break;
+        }
+      }
+    }
+    *start = p;
+    return result;
+  }
+
+
+ /* read an integer */
+  static
+  int  afm_atoi( FT_Byte** start, FT_Byte*  limit )
+  {
+    FT_Byte*  p    = *start;
+    int       sum  = 0;
+    int       sign = 1;
+
+    /* skip everything that is not a number */
+    while ( p < limit && (*p < '0' || *p > '9') )
+    {
+      sign = 1;
+      if (*p == '-')
+        sign = -1;
+
+      p++;
+    }
+
+    while ( p < limit && (*p >= '0' && *p < '9') )
+    {
+      sum = sum*10 + (*p - '0');
+      p++;
+    }
+    *start = p;
+    return sum*sign;
+  }
+
+
+#undef  KERN_INDEX
+#define KERN_INDEX(g1,g2)   (((FT_ULong)g1 << 16) | g2)
+
+ /* compare two kerning pairs */
+  static
+  int  compare_kern_pairs( const void* a, const void* b )
+  {
+    Z1_Kern_Pair*  pair1 = (Z1_Kern_Pair*)a;
+    Z1_Kern_Pair*  pair2 = (Z1_Kern_Pair*)b;
+
+    FT_ULong  index1 = KERN_INDEX(pair1->glyph1,pair1->glyph2);
+    FT_ULong  index2 = KERN_INDEX(pair2->glyph1,pair2->glyph2);
+
+    return ( index1 < index2 ? -1 :
+           ( index1 > index2 ?  1 : 0 ));
+  }
+
+
+ /* parse an AFM file - for now, only read the kerning pairs */
+  LOCAL_FUNC
+  FT_Error  Z1_Read_AFM( FT_Face   t1_face,
+                         FT_Stream stream )
+  {
+    FT_Error       error;
+    FT_Memory      memory = stream->memory;
+    FT_Byte*       start;
+    FT_Byte*       limit;
+    FT_Byte*       p;
+    FT_Int         count = 0;
+    Z1_Kern_Pair*  pair;
+    T1_Font*       type1 = &((T1_Face)t1_face)->type1;
+    Z1_AFM*        afm   = 0;
+
+    if ( ACCESS_Frame(stream->size) )
+      return error;
+
+    start = (FT_Byte*)stream->cursor;
+    limit = (FT_Byte*)stream->limit;
+    p     = start;
+
+    /* we are now going to count the occurences of "KP" or "KPX" in */
+    /* the AFM file..                                               */
+    count = 0;
+    for ( p = start; p < limit-3; p++ )
+    {
+      if ( IS_KERN_PAIR(p) )
+        count++;
+    }
+
+   /* Actually, kerning pairs are simply optional !! */
+    if (count == 0)
+      goto Exit;
+
+    /* allocate the pairs */
+    if ( ALLOC(       afm, sizeof(*afm ) )                   ||
+         ALLOC_ARRAY( afm->kern_pairs, count, Z1_Kern_Pair ) )
+      goto Exit;
+
+    /* now, read each kern pair */
+    pair           = afm->kern_pairs;
+    afm->num_pairs = count;
+
+    /* save in face object */
+    ((T1_Face)t1_face)->afm_data = afm;
+
+    for ( p = start; p < limit-3; p++ )
+    {
+      if ( IS_KERN_PAIR(p) )
+      {
+        FT_Byte*  q;
+
+        /* skip keyword (KP or KPX) */
+        q = p+2;
+        if (*q == 'X') q++;
+
+        pair->glyph1    = afm_atoindex( &q, limit, type1 );
+        pair->glyph2    = afm_atoindex( &q, limit, type1 );
+        pair->kerning.x = afm_atoi( &q, limit );
+
+        pair->kerning.y = 0;
+        if ( p[2] != 'X' )
+          pair->kerning.y = afm_atoi( &q, limit );
+
+        pair++;
+      }
+    }
+
+    /* now, sort the kern pairs according to their glyph indices */
+    qsort( afm->kern_pairs, count, sizeof(Z1_Kern_Pair), compare_kern_pairs );
+
+  Exit:
+    if (error)
+      FREE( afm );
+
+    FORGET_Frame();
+    return error;
+  }
+
+
+ /* find the kerning for a given glyph pair */
+  LOCAL_FUNC
+  void  Z1_Get_Kerning( Z1_AFM*     afm,
+                        FT_UInt     glyph1,
+                        FT_UInt     glyph2,
+                        FT_Vector*  kerning )
+  {
+    Z1_Kern_Pair  *min, *mid, *max;
+    FT_ULong       index = KERN_INDEX(glyph1,glyph2);
+
+    /* simple binary search */
+    min = afm->kern_pairs;
+    max = min + afm->num_pairs-1;
+
+    while (min <= max)
+    {
+      FT_ULong  midi;
+
+      mid = min + (max-min)/2;
+      midi = KERN_INDEX(mid->glyph1,mid->glyph2);
+      if ( midi == index )
+      {
+        *kerning = mid->kerning;
+        return;
+      }
+
+      if ( midi < index ) min = mid+1;
+                     else max = mid-1;
+    }
+    kerning->x = 0;
+    kerning->y = 0;
+  }
+
--- /dev/null
+++ b/src/type1z/z1afm.h
@@ -1,0 +1,50 @@
+/***************************************************************************
+ *
+ * t1afm.h  - support for reading Type 1 AFM files
+ *
+ *
+ ***************************************************************************/
+
+#ifndef T1AFM_H
+#define T1AFM_H
+
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/t1types.h>
+#include <freetype/internal/t1errors.h>
+
+/* In this version, we only read the kerning table from the */
+/* AFM file. We may add support for ligatures a bit later.. */
+
+typedef struct Z1_Kern_Pair_
+{
+  FT_UInt   glyph1;
+  FT_UInt   glyph2;
+  FT_Vector kerning;
+
+} Z1_Kern_Pair;
+
+
+typedef struct Z1_AFM_
+{
+  FT_Int        num_pairs;
+  Z1_Kern_Pair* kern_pairs;
+
+} Z1_AFM;
+
+
+LOCAL_DEF
+FT_Error  Z1_Read_AFM( FT_Face    face,
+                       FT_Stream  stream );
+
+LOCAL_DEF
+void  Z1_Done_AFM( FT_Memory  memory,
+                   Z1_AFM*    afm );
+
+LOCAL_DEF
+void  Z1_Get_Kerning( Z1_AFM*     afm,
+                      FT_UInt     glyph1,
+                      FT_UInt     glyph2,
+                      FT_Vector*  kerning );
+
+#endif /* T1AFM_H */
--- /dev/null
+++ b/src/type1z/z1driver.c
@@ -1,0 +1,300 @@
+/*******************************************************************
+ *
+ *  t1driver.c
+ *
+ *    High-level Type1 driver interface for FreeType 2.0
+ *
+ *  Copyright 1996-1998 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used,
+ *  modified, and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ ******************************************************************/
+
+#include <z1driver.h>
+#include <z1gload.h>
+#include <z1load.h>
+#include <z1afm.h>
+
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/psnames.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_t1driver
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Get_Interface                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Each driver can provide one or more extensions to the base         */
+  /*    FreeType API.  These can be used to access format specific         */
+  /*    features (e.g., all TrueType/OpenType resources share a common     */
+  /*    file structure and common tables which can be accessed through the */
+  /*    `sfnt' interface), or more simply generic ones (e.g., the          */
+  /*    `postscript names' interface which can be used to retrieve the     */
+  /*     PostScript name of a given glyph index).                          */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    driver    :: A handle to a driver object.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    interface :: A string designing the interface.  Examples are       */
+  /*                 `sfnt', `post_names', `charmaps', etc.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    A typeless pointer to the extension's interface (normally a table  */
+  /*    of function pointers).  Returns NULL if the requested extension    */
+  /*    isn't available (i.e., wasn't compiled in the driver at build      */
+  /*    time).                                                             */
+  /*                                                                       */
+  static
+  FT_Module_Interface  Get_Interface( FT_Driver         driver,
+                                      const FT_String*  interface )
+  {
+    UNUSED(driver);
+    UNUSED(interface);
+    
+#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT
+    if ( strcmp( (const char*)interface, "get_mm" ) == 0 )
+      return (FT_Module_Interface)Z1_Get_Multi_Master;
+      
+    if ( strcmp( (const char*)interface, "set_mm_design") == 0 )
+      return (FT_Module_Interface)Z1_Set_MM_Design;      
+
+    if ( strcmp( (const char*)interface, "set_mm_blend") == 0 )
+      return (FT_Module_Interface)Z1_Set_MM_Blend;      
+#endif
+    return 0;
+  }
+
+
+#ifndef Z1_CONFIG_OPTION_NO_AFM
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Get_Kerning                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to return the kerning vector between two      */
+  /*    glyphs of the same face.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: A handle to the source face object.                 */
+  /*                                                                       */
+  /*    left_glyph  :: The index of the left glyph in the kern pair.       */
+  /*                                                                       */
+  /*    right_glyph :: The index of the right glyph in the kern pair.      */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    kerning     :: The kerning vector.  This is in font units for      */
+  /*                   scalable formats, and in pixels for fixed-sizes     */
+  /*                   formats.                                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only horizontal layouts (left-to-right & right-to-left) are        */
+  /*    supported by this function.  Other layouts, or more sophisticated  */
+  /*    kernings are out of scope of this method (the basic driver         */
+  /*    interface is meant to be simple).                                  */
+  /*                                                                       */
+  /*    They can be implemented by format-specific interfaces.             */
+  /*                                                                       */
+  static
+  FT_Error  Get_Kerning( T1_Face     face,
+                         FT_UInt     left_glyph,
+                         FT_UInt     right_glyph,
+                         FT_Vector*  kerning )
+  {
+    Z1_AFM*  afm;
+
+    kerning->x = 0;
+    kerning->y = 0;
+
+    afm = (Z1_AFM*)face->afm_data;
+    if (afm)
+      Z1_Get_Kerning( afm, left_glyph, right_glyph, kerning );
+
+    return T1_Err_Ok;
+  }
+#endif
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Get_Char_Index                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Uses a charmap to return a given character code's glyph index.     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    charmap  :: A handle to the source charmap object.                 */
+  /*    charcode :: The character code.                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Glyph index.  0 means `undefined character code'.                  */
+  /*                                                                       */
+  static
+  FT_UInt  Get_Char_Index( FT_CharMap  charmap,
+                           FT_Long     charcode )
+  {
+    T1_Face             face;
+    FT_UInt             result = 0;
+    PSNames_Interface*  psnames;
+
+    face = (T1_Face)charmap->face;
+    psnames = (PSNames_Interface*)face->psnames;
+    if (psnames)
+      switch (charmap->encoding)
+      {
+       /********************************************************************/
+       /*                                                                  */
+       /* Unicode encoding support                                         */
+       /*                                                                  */
+        case ft_encoding_unicode:
+          {
+            /* use the "psnames" module to synthetize the Unicode charmap */
+            result = psnames->lookup_unicode( &face->unicode_map,
+                                              (FT_ULong)charcode );
+
+            /* the function returns 0xFFFF when the Unicode charcode has */
+            /* no corresponding glyph..                                  */
+            if (result == 0xFFFF)
+              result = 0;
+            goto Exit;
+          }
+
+       /********************************************************************/
+       /*                                                                  */
+       /* Custom Type 1 encoding                                           */
+       /*                                                                  */
+        case ft_encoding_adobe_custom:
+          {
+            T1_Encoding*  encoding = &face->type1.encoding;
+            if (charcode >= encoding->code_first &&
+                charcode <= encoding->code_last)
+            {
+              result = encoding->char_index[charcode];
+            }
+            goto Exit;
+          }
+
+       /********************************************************************/
+       /*                                                                  */
+       /* Adobe Standard & Expert encoding support                         */
+       /*                                                                  */
+       default:
+         if (charcode < 256)
+         {
+           FT_UInt      code;
+           FT_Int       n;
+           const char*  glyph_name;
+
+           code = psnames->adobe_std_encoding[charcode];
+           if (charmap->encoding == ft_encoding_adobe_expert)
+             code = psnames->adobe_expert_encoding[charcode];
+
+           glyph_name = psnames->adobe_std_strings(code);
+           if (!glyph_name) break;
+
+           for ( n = 0; n < face->type1.num_glyphs; n++ )
+           {
+             const char*  gname = face->type1.glyph_names[n];
+
+             if ( gname && gname[0] == glyph_name[0] &&
+                  strcmp( gname, glyph_name ) == 0 )
+             {
+               result = n;
+               break;
+             }
+           }
+         }
+      }
+  Exit:
+    return result;
+  }
+
+
+  const  FT_Driver_Class  t1z_driver_class =
+  {
+    {
+      ft_module_font_driver | ft_module_driver_scalable,
+      sizeof( FT_DriverRec ),
+      
+      "type1z",
+      0x10000,
+      0x20000,
+  
+      0,   /* format interface */
+  
+      (FT_Module_Constructor)           Z1_Init_Driver,
+      (FT_Module_Destructor)            Z1_Done_Driver,
+      (FT_Module_Requester)             Get_Interface,
+    },
+
+    sizeof( T1_FaceRec ),
+    sizeof( Z1_SizeRec ),
+    sizeof( Z1_GlyphSlotRec ),
+
+    (FTDriver_initFace)             Z1_Init_Face,
+    (FTDriver_doneFace)             Z1_Done_Face,
+    (FTDriver_initSize)             0,
+    (FTDriver_doneSize)             0,
+    (FTDriver_initGlyphSlot)        0,
+    (FTDriver_doneGlyphSlot)        0,
+
+    (FTDriver_setCharSizes)         0,
+    (FTDriver_setPixelSizes)        0,
+    (FTDriver_loadGlyph)            Z1_Load_Glyph,
+    (FTDriver_getCharIndex)         Get_Char_Index,
+
+#ifdef Z1_CONFIG_OPTION_NO_AFM
+    (FTDriver_getKerning)           0,
+    (FTDriver_attachFile)           0,
+#else
+    (FTDriver_getKerning)           Get_Kerning,
+    (FTDriver_attachFile)           Z1_Read_AFM,
+#endif
+    (FTDriver_getAdvances)          0
+
+  };
+
+
+  /******************************************************************/
+  /*                                                                */
+  /*  <Function> Get_FreeType_Driver_Interface                      */
+  /*                                                                */
+  /*  <Description>                                                 */
+  /*     This function is used when compiling the TrueType driver   */
+  /*     as a shared library (.DLL or .so). It will be used by the  */
+  /*     high-level library of FreeType to retrieve the address of  */
+  /*     the driver's generic interface.                            */
+  /*                                                                */
+  /*     It shouldn't be implemented in a static build, as each     */
+  /*     driver must have the same function as an exported entry    */
+  /*     point.                                                     */
+  /*                                                                */
+  /*  <Return>                                                      */
+  /*     address of TrueType's driver generic interface. The        */
+  /*     forma-specific interface can then be retrieved through     */
+  /*     the method interface->get_format_interface..               */
+  /*                                                                */
+
+#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
+
+  EXPORT_FUNC(const FT_Driver_Class*)  getDriverClass( void )
+  {
+    return &t1z_driver_class;
+  }
+
+#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
+
+
--- /dev/null
+++ b/src/type1z/z1driver.h
@@ -1,0 +1,26 @@
+/*******************************************************************
+ *
+ *  t1driver.h
+ *
+ *    High-level Type1 driver interface for FreeType 2.0
+ *
+ *  Copyright 1996-1998 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used,
+ *  modified, and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef T1DRIVER_H
+#define T1DRIVER_H
+
+#include <freetype/internal/ftdriver.h>
+
+  FT_EXPORT_VAR(const  FT_Driver_Class)  t1z_driver_class;
+
+#endif /* T1DRIVER_H */
+
--- /dev/null
+++ b/src/type1z/z1gload.c
@@ -1,0 +1,1382 @@
+/*******************************************************************
+ *
+ *  t1gload.c                                                   1.0
+ *
+ *    Type1 Glyph Loader.
+ *
+ *  Copyright 1996-1999 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ ******************************************************************/
+
+#include <z1gload.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_t1gload
+
+  typedef enum Z1_Operator_
+  {
+    op_none = 0,
+    op_endchar,
+    op_hsbw,
+    op_seac,
+    op_sbw,
+    op_closepath,
+    op_hlineto,
+    op_hmoveto,
+    op_hvcurveto,
+    op_rlineto,
+    op_rmoveto,
+    op_rrcurveto,
+    op_vhcurveto,
+    op_vlineto,
+    op_vmoveto,
+    op_dotsection,
+    op_hstem,
+    op_hstem3,
+    op_vstem,
+    op_vstem3,
+    op_div,
+    op_callothersubr,
+    op_callsubr,
+    op_pop,
+    op_return,
+    op_setcurrentpoint,
+
+    op_max    /* never remove this one */
+
+  } Z1_Operator;
+
+  static const FT_Int  t1_args_count[ op_max ] =
+  {
+    0, /* none */
+    0, /* endchar */
+    2, /* hsbw */
+    5, /* seac */
+    4, /* sbw */
+    0, /* closepath */
+    1, /* hlineto */
+    1, /* hmoveto */
+    4, /* hvcurveto */
+    2, /* rlineto */
+    2, /* rmoveto */
+    6, /* rrcurveto */
+    4, /* vhcurveto */
+    1, /* vlineto */
+    1, /* vmoveto */
+    0, /* dotsection */
+    2, /* hstem */
+    6, /* hstem3 */
+    2, /* vstem */
+    6, /* vstem3 */
+    2, /* div */
+   -1, /* callothersubr */
+    1, /* callsubr */
+    0, /* pop */
+    0, /* return */
+    2  /* setcurrentpoint */
+  };
+
+
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********           GENERIC CHARSTRINGS PARSING             *********/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+
+/*********************************************************************
+ *
+ * <Function>
+ *    Z1_Init_Builder
+ *
+ * <Description>
+ *    Initialise a given glyph builder.
+ *
+ * <Input>
+ *    builder :: glyph builder to initialise
+ *    face    :: current face object
+ *    size    :: current size object
+ *    glyph   :: current glyph object
+ *
+ *********************************************************************/
+
+  LOCAL_FUNC
+  void  Z1_Init_Builder( Z1_Builder*   builder,
+                         T1_Face       face,
+                         Z1_Size       size,
+                         Z1_GlyphSlot  glyph )
+  {
+    builder->path_begun  = 0;
+    builder->load_points = 1;
+
+    builder->face   = face;
+    builder->glyph  = glyph;
+    builder->memory = face->root.memory;
+
+    if (glyph)
+    {
+      FT_GlyphLoader*  loader = glyph->root.loader;
+      
+      builder->loader = loader;
+      builder->current = &loader->current.outline;
+      builder->base    = &loader->base.outline;
+
+      FT_GlyphLoader_Rewind(loader);
+    }
+
+    if (size)
+    {
+      builder->scale_x = size->root.metrics.x_scale;
+      builder->scale_y = size->root.metrics.y_scale;
+    }
+
+    builder->pos_x = 0;
+    builder->pos_y = 0;
+
+    builder->left_bearing.x = 0;
+    builder->left_bearing.y = 0;
+    builder->advance.x      = 0;
+    builder->advance.y      = 0;
+  }
+
+
+/*********************************************************************
+ *
+ * <Function>
+ *    Z1_Done_Builder
+ *
+ * <Description>
+ *    Finalise a given glyph builder. Its content can still be
+ *    used after the call, but the function saves important information
+ *    within the corresponding glyph slot.
+ *
+ * <Input>
+ *    builder :: glyph builder to initialise
+ *
+ *********************************************************************/
+
+  LOCAL_FUNC
+  void Z1_Done_Builder( Z1_Builder*  builder )
+  {
+    Z1_GlyphSlot  glyph = builder->glyph;
+
+    if (glyph)
+      glyph->root.outline = *builder->base;
+  }
+
+
+
+/*********************************************************************
+ *
+ * <Function>
+ *    Z1_Init_Decoder
+ *
+ * <Description>
+ *    Initialise a given Type 1 decoder for parsing
+ *
+ * <Input>
+ *    decoder :: Type 1 decoder to initialise
+ *    funcs   :: hinter functions interface
+ *
+ *********************************************************************/
+
+  LOCAL_FUNC
+  void  Z1_Init_Decoder( Z1_Decoder* decoder )
+  {
+    decoder->top              = 0;
+    decoder->zone             = 0;
+    decoder->flex_state       = 0;
+    decoder->num_flex_vectors = 0;
+    decoder->blend            = 0;
+
+    /* Clear loader */
+    MEM_Set( &decoder->builder, 0, sizeof(decoder->builder) );
+  }
+
+
+  /* check that there is enough room for "count" more points */
+  static
+  FT_Error  check_points( Z1_Builder*  builder,
+                          FT_Int       count )
+  {
+    return FT_GlyphLoader_Check_Points( builder->loader, count, 0 );
+  }
+
+
+  /* add a new point, do not check room */
+  static
+  void  add_point( Z1_Builder*  builder,
+                   FT_Pos       x,
+                   FT_Pos       y,
+                   FT_Byte      flag )
+  {
+    FT_Outline*  outline = builder->current;
+
+    if (builder->load_points)
+    {
+      FT_Vector*  point   = outline->points + outline->n_points;
+      FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;
+
+      point->x = x;
+      point->y = y;
+      *control = ( flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic );
+
+      builder->last = *point;
+    }
+
+    outline->n_points++;
+  }
+
+
+  /* check room for a new on-curve point, then add it */
+  static
+  FT_Error  add_point1( Z1_Builder*  builder,
+                        FT_Pos       x,
+                        FT_Pos       y )
+  {
+    FT_Error  error;
+
+    error = check_points(builder,1);
+    if (!error)
+      add_point( builder, x, y, 1 );
+
+    return error;
+  }
+
+
+  /* check room for a new contour, then add it */
+  static
+  FT_Error  add_contour( Z1_Builder*  builder )
+  {
+    FT_Outline*  outline = builder->current;
+    FT_Error     error;
+
+    if (!builder->load_points)
+    {
+      outline->n_contours++;
+      return FT_Err_Ok;
+    }
+
+    /* realloc contours array if necessary */
+    error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 );
+    if (!error)
+    {
+      if (outline->n_contours > 0)
+        outline->contours[ outline->n_contours-1 ] = outline->n_points-1;
+        
+      outline->n_contours++;
+    }
+    return error;
+  }
+
+  /* if a path was begun, add its first on-curve point */
+  static
+  FT_Error  start_point( Z1_Builder*  builder,
+                         FT_Pos       x,
+                         FT_Pos       y )
+  {
+    /* test wether we're building a new contour */
+    if (!builder->path_begun)
+    {
+      FT_Error  error;
+
+      builder->path_begun = 1;
+      error = add_contour( builder );
+      if (error) return error;
+    }
+    return add_point1( builder, x, y );
+  }
+
+
+  /* close the current contour */
+  static
+  void  close_contour( Z1_Builder*  builder )
+  {
+    FT_Outline*  outline = builder->current;
+
+    if ( outline->n_contours > 0 )
+      outline->contours[outline->n_contours-1] = outline->n_points-1;
+  }
+
+
+/*********************************************************************
+ *
+ * <Function>
+ *    lookup_glyph_by_stdcharcode
+ *
+ * <Description>
+ *    Lookup a given glyph by its StandardEncoding charcode. Used
+ *    to implement the SEAC Type 1 operator.
+ *
+ * <Input>
+ *    face     :: current face object
+ *    charcode :: charcode to look for
+ *
+ * <Return>
+ *    glyph index in font face. Returns -1 if the corresponding
+ *    glyph wasn't found.
+ *
+ *********************************************************************/
+
+  static
+  FT_Int    lookup_glyph_by_stdcharcode( T1_Face  face,
+                                         FT_Int   charcode )
+  {
+    FT_Int              n;
+    const FT_String*    glyph_name;
+    PSNames_Interface*  psnames = (PSNames_Interface*)face->psnames;
+
+    /* check range of standard char code */
+    if (charcode < 0 || charcode > 255)
+      return -1;
+
+    glyph_name = psnames->adobe_std_strings(
+                    psnames->adobe_std_encoding[charcode]);
+
+    for ( n = 0; n < face->type1.num_glyphs; n++ )
+    {
+      FT_String*  name = (FT_String*)face->type1.glyph_names[n];
+
+      if ( name && strcmp(name,glyph_name) == 0 )
+        return n;
+    }
+
+    return -1;
+  }
+
+
+
+/*********************************************************************
+ *
+ * <Function>
+ *    t1operator_seac
+ *
+ * <Description>
+ *    Implements the "seac" Type 1 operator for a Type 1 decoder
+ *
+ * <Input>
+ *    decoder  :: current Type 1 decoder
+ *    asb      :: accent's side bearing
+ *    adx      :: horizontal position of accent
+ *    ady      :: vertical position of accent
+ *    bchar    :: base character's StandardEncoding charcode
+ *    achar    :: accent character's StandardEncoding charcode
+ *
+ * <Return>
+ *    Error code. 0 means success.
+ *
+ *********************************************************************/
+
+  static
+  FT_Error  t1operator_seac( Z1_Decoder*  decoder,
+                             FT_Pos       asb,
+                             FT_Pos       adx,
+                             FT_Pos       ady,
+                             FT_Int       bchar,
+                             FT_Int       achar )
+  {
+    FT_Error     error;
+    FT_Int       bchar_index, achar_index, n_base_points;
+    FT_Outline*  cur  = decoder->builder.current;
+    FT_Outline*  base = decoder->builder.base;
+    FT_Vector    left_bearing, advance;
+    T1_Face      face  = decoder->builder.face;
+    T1_Font*     type1 = &face->type1;
+
+    bchar_index = lookup_glyph_by_stdcharcode( face, bchar );
+    achar_index = lookup_glyph_by_stdcharcode( face, achar );
+
+    if ( bchar_index < 0 || achar_index < 0 )
+    {
+      FT_ERROR(( "t1operator_seac: invalid seac character code arguments\n" ));
+      return T1_Err_Syntax_Error;
+    }
+
+    /* if we are trying to load a composite glyph, do not load the */
+    /* accent character and return the array of subglyphs.         */
+    if ( decoder->builder.no_recurse )
+    {
+
+      FT_GlyphSlot     glyph = (FT_GlyphSlot)decoder->builder.glyph;
+      FT_GlyphLoader*  loader = glyph->loader;
+      FT_SubGlyph*     subg;
+
+      /* reallocate subglyph array if necessary */
+      error = FT_GlyphLoader_Check_Subglyphs( loader, 2 );
+      if (error) goto Exit;
+      
+      subg = loader->current.subglyphs;
+
+      /* subglyph 0 = base character */
+      subg->index = bchar_index;
+      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
+                    FT_SUBGLYPH_FLAG_USE_MY_METRICS;
+      subg->arg1  = 0;
+      subg->arg2  = 0;
+      subg++;
+
+      /* subglyph 1 = accent character */
+      subg->index = achar_index;
+      subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
+      subg->arg1  = adx - asb;
+      subg->arg2  = ady;
+
+      /* set up remaining glyph fields */
+      glyph->num_subglyphs = 2;
+      glyph->format        = ft_glyph_format_composite;
+      
+      loader->current.num_subglyphs = 2;
+    }
+
+    /* First load `bchar' in builder */
+    /* now load the unscaled outline */
+    
+    FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
+
+    error = Z1_Parse_CharStrings( decoder,
+                                  type1->charstrings    [bchar_index],
+                                  type1->charstrings_len[bchar_index],
+                                  type1->num_subrs,
+                                  type1->subrs,
+                                  type1->subrs_len );
+    if ( error ) goto Exit;
+
+    n_base_points = cur->n_points;
+
+    {
+      /* save the left bearing and width of the base character */
+      /* as they will be erased by the next load.              */
+
+      left_bearing = decoder->builder.left_bearing;
+      advance      = decoder->builder.advance;
+
+      decoder->builder.left_bearing.x = 0;
+      decoder->builder.left_bearing.y = 0;
+
+      /* Now load `achar' on top of */
+      /* the base outline           */
+      error = Z1_Parse_CharStrings( decoder,
+                                    type1->charstrings    [achar_index],
+                                    type1->charstrings_len[achar_index],
+                                    type1->num_subrs,
+                                    type1->subrs,
+                                    type1->subrs_len );
+      if ( error ) return error;
+
+      /* restore the left side bearing and   */
+      /* advance width of the base character */
+
+      decoder->builder.left_bearing = left_bearing;
+      decoder->builder.advance      = advance;
+
+      /* Finally, move the accent */
+      if ( decoder->builder.load_points )
+      {
+        FT_Outline  dummy;
+        
+        dummy.n_points = base->n_points - n_base_points;
+        dummy.points   = base->points   + n_base_points;
+        FT_Outline_Translate( &dummy, adx - asb, ady );
+      }
+    }
+  Exit:
+    return error;
+  }
+
+
+/*********************************************************************
+ *
+ * <Function>
+ *    Z1_Parse_CharStrings
+ *
+ * <Description>
+ *    Parses a given Type 1 charstrings program
+ *
+ * <Input>
+ *    decoder          :: current Type 1 decoder
+ *    charstring_base  :: base of the charstring stream
+ *    charstring_len   :: length in bytes of the charstring stream
+ *    num_subrs        :: number of sub-routines
+ *    subrs_base       :: array of sub-routines addresses
+ *    subrs_len        :: array of sub-routines lengths
+ *
+ * <Return>
+ *    Error code. 0 means success.
+ *
+ *********************************************************************/
+
+#define USE_ARGS(n)  top -= n; if (top < decoder->stack) goto Stack_Underflow
+
+  LOCAL_FUNC
+  FT_Error   Z1_Parse_CharStrings( Z1_Decoder*  decoder,
+                                   FT_Byte*     charstring_base,
+                                   FT_Int       charstring_len,
+                                   FT_Int       num_subrs,
+                                   FT_Byte**    subrs_base,
+                                   FT_Int*      subrs_len )
+  {
+    FT_Error            error;
+    Z1_Decoder_Zone*    zone;
+    FT_Byte*            ip;
+    FT_Byte*            limit;
+    Z1_Builder*         builder = &decoder->builder;
+    FT_Outline*         outline;
+    FT_Pos              x, y;
+
+    /* First of all, initialise the decoder */
+    decoder->top  = decoder->stack;
+    decoder->zone = decoder->zones;
+    zone          = decoder->zones;
+
+    builder->path_begun  = 0;
+
+    zone->base           = charstring_base;
+    limit = zone->limit  = charstring_base + charstring_len;
+    ip    = zone->cursor = zone->base;
+
+    error   = T1_Err_Ok;
+    outline = builder->current;
+
+    x = builder->pos_x;
+    y = builder->pos_y;
+
+    /* now, execute loop */
+    while ( ip < limit )
+    {
+      FT_Int*      top      = decoder->top;
+      Z1_Operator  op       = op_none;
+      FT_Long      value    = 0;
+
+      /********************************************************************/
+      /*                                                                  */
+      /* Decode operator or operand                                       */
+      /*                                                                  */
+      /*                                                                  */
+
+      /* First of all, decompress operator or value */
+      switch (*ip++)
+      {
+        case 1:  op = op_hstem;     break;
+
+        case 3:  op = op_vstem;     break;
+        case 4:  op = op_vmoveto;   break;
+        case 5:  op = op_rlineto;   break;
+        case 6:  op = op_hlineto;   break;
+        case 7:  op = op_vlineto;   break;
+        case 8:  op = op_rrcurveto; break;
+        case 9:  op = op_closepath; break;
+        case 10: op = op_callsubr;  break;
+        case 11: op = op_return;    break;
+
+        case 13: op = op_hsbw;      break;
+        case 14: op = op_endchar;   break;
+
+        case 21: op = op_rmoveto;   break;
+        case 22: op = op_hmoveto;   break;
+
+        case 30: op = op_vhcurveto; break;
+        case 31: op = op_hvcurveto; break;
+
+        case 12:
+          {
+            if (ip > limit)
+            {
+              FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+EOF)\n" ));
+              goto Syntax_Error;
+            }
+
+            switch (*ip++)
+            {
+              case 0:  op = op_dotsection;      break;
+              case 1:  op = op_vstem3;          break;
+              case 2:  op = op_hstem3;          break;
+              case 6:  op = op_seac;            break;
+              case 7:  op = op_sbw;             break;
+              case 12: op = op_div;             break;
+              case 16: op = op_callothersubr;   break;
+              case 17: op = op_pop;             break;
+              case 33: op = op_setcurrentpoint; break;
+
+              default:
+                FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+%d)\n",
+                         ip[-1] ));
+                goto Syntax_Error;
+            }
+          }
+          break;
+
+        case 255:    /* four bytes integer */
+          {
+            if (ip+4 > limit)
+            {
+              FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
+              goto Syntax_Error;
+            }
+
+            value = ((long)ip[0] << 24) |
+                    ((long)ip[1] << 16) |
+                    ((long)ip[2] << 8)  |
+                           ip[3];
+            ip += 4;
+          }
+          break;
+
+        default:
+          if (ip[-1] >= 32)
+          {
+            if (ip[-1] < 247)
+              value = (long)ip[-1] - 139;
+            else
+            {
+              if (++ip > limit)
+              {
+                FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
+                goto Syntax_Error;
+              }
+
+              if (ip[-2] < 251)
+                value =  ((long)(ip[-2]-247) << 8) + ip[-1] + 108;
+              else
+                value = -((((long)ip[-2]-251) << 8) + ip[-1] + 108 );
+            }
+          }
+          else
+          {
+            FT_ERROR(( "T1.Parse_CharStrings : invalid byte (%d)\n",
+                     ip[-1] ));
+            goto Syntax_Error;
+          }
+      }
+
+      /********************************************************************/
+      /*                                                                  */
+      /*  Push value on stack, or process operator                        */
+      /*                                                                  */
+      /*                                                                  */
+      if ( op == op_none )
+      {
+        if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
+        {
+          FT_ERROR(( "T1.Parse_CharStrings : Stack overflow !!\n" ));
+          goto Syntax_Error;
+        }
+
+        FT_TRACE4(( " %ld", value ));
+        *top++       = value;
+        decoder->top = top;
+      }
+      else if ( op == op_callothersubr )  /* callothersubr */
+      {
+        FT_TRACE4(( " callothersubr" ));
+        if ( top - decoder->stack < 2 )
+          goto Stack_Underflow;
+
+        top -= 2;
+        switch ( top[1] )
+        {
+          case 1: /* start flex feature ---------------------- */
+            {
+              if ( top[0] != 0 ) goto Unexpected_OtherSubr;
+
+              decoder->flex_state        = 1;
+              decoder->num_flex_vectors  = 0;
+              if ( start_point(builder, x, y) ||
+                   check_points(builder,6) ) goto Memory_Error;
+            }
+            break;
+
+          case 2: /* add flex vectors ------------------------ */
+            {
+              FT_Int      index;
+
+              if ( top[0] != 0 ) goto Unexpected_OtherSubr;
+
+              /* note that we should not add a point for index 0 */
+              /* this will move our current position to the flex */
+              /* point without adding any point to the outline   */
+              index = decoder->num_flex_vectors++;
+              if (index > 0 && index < 7)
+                add_point( builder,
+                           x,
+                           y,
+                           (FT_Byte)( index==3 || index==6 ) );
+            }
+            break;
+
+          case 0: /* end flex feature ------------------------- */
+            {
+              if ( top[0] != 3 ) goto Unexpected_OtherSubr;
+
+              if ( decoder->flex_state       == 0 ||
+                   decoder->num_flex_vectors != 7 )
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: unexpected flex end\n" ));
+                goto Syntax_Error;
+              }
+
+              /* now consume the remaining "pop pop setcurpoint" */
+              if ( ip+6 > limit ||
+                   ip[0] != 12  || ip[1] != 17 || /* pop */
+                   ip[2] != 12  || ip[3] != 17 || /* pop */
+                   ip[4] != 12  || ip[5] != 33 )  /* setcurpoint */
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: invalid flex charstring\n" ));
+                goto Syntax_Error;
+              }
+
+              ip += 6;
+              decoder->flex_state = 0;
+              break;
+            }
+
+          case 3:  /* change hints ---------------------------- */
+            {
+              if ( top[0] != 1 ) goto Unexpected_OtherSubr;
+
+              /* eat the following "pop" */
+              if (ip+2 > limit)
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: invalid escape (12+%d)\n",
+                         ip[-1] ));
+                goto Syntax_Error;
+              }
+
+              if (ip[0] != 12 || ip[1] != 17)
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: 'pop' expected, found (%d %d)\n",
+                         ip[0], ip[1] ));
+                goto Syntax_Error;
+              }
+              ip += 2;
+              break;;
+            }
+
+          case 12:
+          case 13:
+            {
+              /* counter control hints, clear stack */
+              top = decoder->stack;
+              break;
+            }
+          
+          case 14:
+          case 15:
+          case 16:
+          case 17:
+          case 18: /* multiple masters */
+            {
+              T1_Blend*  blend = decoder->blend;
+              FT_UInt    num_points, nn, mm;
+              FT_Int*    delta;
+              FT_Int*    values;
+              
+              if (!blend)
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: unexpected multiple masters operator !!\n" ));
+                goto Syntax_Error;
+              }
+              
+              num_points = top[1] - 13 + (top[1] == 18);
+              if (top[0] != (FT_Int)(num_points*blend->num_designs))
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: incorrect number of mm arguments\n" ));
+                goto Syntax_Error;
+              }
+              
+              top       -= blend->num_designs*num_points;
+              if (top < decoder->stack)
+                goto Stack_Underflow;
+
+              /* we want to compute:                                   */
+              /*                                                       */
+              /*  a0*w0 + a1*w1 + ... + ak*wk                          */
+              /*                                                       */
+              /* but we only have the a0, a1-a0, a2-a0, .. ak-a0       */
+              /* however, given that w0 + w1 + ... + wk == 1, we can   */
+              /* rewrite it easily as:                                 */
+              /*                                                       */
+              /*  a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk       */
+              /*                                                       */
+              /* where k == num_designs-1                              */
+              /*                                                       */
+              /* I guess that's why it's written in this "compact"     */
+              /* form..                                                */
+              /*                                                       */
+              /*                                                       */
+              delta  = top + num_points;
+              values = top;
+              for ( nn = 0; nn < num_points; nn++ )
+              {
+                FT_Int  x = values[0];
+                for ( mm = 1; mm < blend->num_designs; mm++ )
+                  x += FT_MulFix( *delta++, blend->weight_vector[mm] );
+
+                *values++ = x;
+              }
+              /* note that "top" will be incremented later by calls to "pop" */
+              break;
+            }
+          
+          default:
+          Unexpected_OtherSubr:
+            FT_ERROR(( "T1.Parse_CharStrings: invalid othersubr [%d %d]!!\n",
+                       top[0], top[1] ));
+            goto Syntax_Error;
+        }
+        decoder->top = top;
+      }
+      else  /* general operator */
+      {
+        FT_Int  num_args = t1_args_count[op];
+
+        if ( top - decoder->stack < num_args )
+          goto Stack_Underflow;
+
+        top -= num_args;
+
+        switch (op)
+        {
+          case op_endchar: /*************************************************/
+          {
+            FT_TRACE4(( " endchar" ));
+            close_contour( builder );
+
+            /* add current outline to the glyph slot */
+            FT_GlyphLoader_Add( builder->loader );
+
+            /* return now !! */
+            FT_TRACE4(( "\n\n" ));
+            return T1_Err_Ok;
+          }
+
+
+          case op_hsbw: /****************************************************/
+          {
+            FT_TRACE4(( " hsbw" ));
+            builder->left_bearing.x += top[0];
+            builder->advance.x       = top[1];
+            builder->advance.y       = 0;
+
+            builder->last.x = x = top[0];
+            builder->last.y = y = 0;
+
+            /* the "metrics_only" indicates that we only want to compute */
+            /* the glyph's metrics (lsb + advance width), not load the   */
+            /* rest of it.. so exit immediately                          */
+            if (builder->metrics_only)
+              return T1_Err_Ok;
+
+            break;
+          }
+
+
+          case op_seac: /****************************************************/
+            /* return immediately after the processing */
+            return t1operator_seac( decoder, top[0], top[1],
+                                             top[2], top[3], top[4] );
+
+          case op_sbw:  /****************************************************/
+          {
+            FT_TRACE4(( " sbw" ));
+            builder->left_bearing.x += top[0];
+            builder->left_bearing.y += top[1];
+            builder->advance.x       = top[2];
+            builder->advance.y       = top[3];
+
+            builder->last.x = x = top[0];
+            builder->last.y = y = top[1];
+
+            /* the "metrics_only" indicates that we only want to compute */
+            /* the glyph's metrics (lsb + advance width), not load the   */
+            /* rest of it.. so exit immediately                          */
+            if (builder->metrics_only)
+              return T1_Err_Ok;
+
+            break;
+          }
+
+
+          case op_closepath:  /**********************************************/
+          {
+            FT_TRACE4(( " closepath" ));
+            close_contour( builder );
+            builder->path_begun = 0;
+          }
+          break;
+
+
+          case op_hlineto:  /************************************************/
+          {
+            FT_TRACE4(( " hlineto" ));
+            if ( start_point( builder, x, y ) ) goto Memory_Error;
+
+            x += top[0];
+            goto Add_Line;
+          }
+
+
+          case op_hmoveto:  /************************************************/
+          {
+            FT_TRACE4(( " hmoveto" ));
+            x += top[0];
+            break;
+          }
+
+
+          case op_hvcurveto:  /**********************************************/
+          {
+            FT_TRACE4(( " hvcurveto" ));
+            if ( start_point( builder, x, y ) ||
+                 check_points( builder, 3 )   ) goto Memory_Error;
+
+            x += top[0];
+            add_point( builder, x, y, 0 );
+            x += top[1];
+            y += top[2];
+            add_point( builder, x, y, 0 );
+            y += top[3];
+            add_point( builder, x, y, 1 );
+            break;
+          }
+
+
+          case op_rlineto: /*************************************************/
+          {
+            FT_TRACE4(( " rlineto" ));
+            if ( start_point( builder, x, y ) ) goto Memory_Error;
+
+            x += top[0];
+            y += top[1];
+   Add_Line:
+            if (add_point1( builder, x, y )) goto Memory_Error;
+            break;
+          }
+
+
+          case op_rmoveto: /*************************************************/
+          {
+            FT_TRACE4(( " rmoveto" ));
+            x += top[0];
+            y += top[1];
+            break;
+          }
+
+          case op_rrcurveto: /***********************************************/
+          {
+            FT_TRACE4(( " rcurveto" ));
+            if ( start_point( builder, x, y ) ||
+                 check_points( builder, 3 )   ) goto Memory_Error;
+
+            x += top[0];
+            y += top[1];
+            add_point( builder, x, y, 0 );
+
+            x += top[2];
+            y += top[3];
+            add_point( builder, x, y, 0 );
+
+            x += top[4];
+            y += top[5];
+            add_point( builder, x, y, 1 );
+            break;
+          }
+
+
+          case op_vhcurveto:  /**********************************************/
+          {
+            FT_TRACE4(( " vhcurveto" ));
+            if ( start_point( builder, x, y ) ||
+                 check_points( builder, 3 )   ) goto Memory_Error;
+
+            y += top[0];
+            add_point( builder, x, y, 0 );
+            x += top[1];
+            y += top[2];
+            add_point( builder, x, y, 0 );
+            x += top[3];
+            add_point( builder, x, y, 1 );
+            break;
+          }
+
+
+          case op_vlineto:  /************************************************/
+            {
+              FT_TRACE4(( " vlineto" ));
+              if ( start_point( builder, x, y ) ) goto Memory_Error;
+
+              y += top[0];
+              goto Add_Line;
+            }
+
+
+          case op_vmoveto:  /************************************************/
+            {
+              FT_TRACE4(( " vmoveto" ));
+              y += top[0];
+              break;
+            }
+
+
+          case op_div:  /****************************************************/
+          {
+            FT_TRACE4(( " div" ));
+            if (top[1])
+            {
+              *top = top[0] / top[1];
+              ++top;
+            }
+            else
+            {
+              FT_ERROR(( "T1.Parse_CharStrings : division by 0\n" ));
+              goto Syntax_Error;
+            }
+            break;
+          }
+
+
+          case op_callsubr:  /***********************************************/
+          {
+            FT_Int  index;
+
+            FT_TRACE4(( " callsubr" ));
+            index = top[0];
+            if ( index < 0 || index >= num_subrs )
+            {
+              FT_ERROR(( "T1.Parse_CharStrings : invalid subrs index\n" ));
+              goto Syntax_Error;
+            }
+
+            if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
+            {
+              FT_ERROR(( "T1.Parse_CharStrings : too many nested subrs\n" ));
+              goto Syntax_Error;
+            }
+
+            zone->cursor = ip;  /* save current instruction pointer */
+
+            zone++;
+            zone->base    = subrs_base[index];
+            zone->limit   = zone->base + subrs_len[index];
+            zone->cursor  = zone->base;
+
+            if (!zone->base)
+            {
+              FT_ERROR(( "T1.Parse_CharStrings : invoking empty subrs !!\n" ));
+              goto Syntax_Error;
+            }
+
+            decoder->zone = zone;
+            ip            = zone->base;
+            limit         = zone->limit;
+            break;
+          }
+
+
+          case op_pop:  /****************************************************/
+          {
+            FT_TRACE4(( " pop" ));
+            /* theorically, the arguments are already on the stack */
+            top++;
+            break;
+          }
+
+
+          case op_return:  /************************************************/
+          {
+            FT_TRACE4(( " return" ));
+            if ( zone <= decoder->zones )
+            {
+              FT_ERROR(( "T1.Parse_CharStrings : unexpected return\n" ));
+              goto Syntax_Error;
+            }
+
+            zone--;
+            ip            = zone->cursor;
+            limit         = zone->limit;
+            decoder->zone = zone;
+            break;
+          }
+
+          case op_dotsection:  /*********************************************/
+          {
+            FT_TRACE4(( " dotsection" ));
+            break;
+          }
+
+          case op_hstem:  /**************************************************/
+          {
+            FT_TRACE4(( " hstem" ));
+            break;
+          }
+
+          case op_hstem3:  /*************************************************/
+          {
+            FT_TRACE4(( " hstem3" ));
+            break;
+          }
+
+          case op_vstem:  /**************************************************/
+          {
+            FT_TRACE4(( " vstem" ));
+            break;
+          }
+
+          case op_vstem3:  /*************************************************/
+          {
+            FT_TRACE4(( " vstem3" ));
+            break;
+          }
+
+          case op_setcurrentpoint:  /*****************************************/
+          {
+            FT_TRACE4(( " setcurrentpoint" ));
+            FT_ERROR(( "T1.Parse_CharStrings : unexpected SETCURRENTPOINT\n" ));
+            goto Syntax_Error;
+          }
+
+          default:
+            FT_ERROR(( "T1.Parse_CharStrings : unhandled opcode %d\n", op ));
+            goto Syntax_Error;
+        }
+
+        decoder->top = top;
+
+      } /* general operator processing */
+
+
+    } /* while ip < limit */
+    FT_TRACE4(( "..end..\n\n" ));
+    return error;
+
+  Syntax_Error:
+    return T1_Err_Syntax_Error;
+
+  Stack_Underflow:
+    return T1_Err_Stack_Underflow;
+
+  Memory_Error:
+    return builder->error;
+  }
+
+
+
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********           COMPUTE THE MAXIMUM ADVANCE WIDTH       *********/
+  /**********                                                   *********/
+  /**********   The following code is in charge of computing    *********/
+  /**********   the maximum advance width of the font. It       *********/
+  /**********   quickly process each glyph charstring to        *********/
+  /**********   extract the value from either a "sbw" or "seac" *********/
+  /**********   operator.                                       *********/
+  /**********                                                   *********/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+
+  LOCAL_FUNC
+  FT_Error  Z1_Compute_Max_Advance( T1_Face  face,
+                                    FT_Int  *max_advance )
+  {
+    FT_Error    error;
+    Z1_Decoder  decoder;
+    FT_Int      glyph_index;
+    T1_Font*    type1 = &face->type1;
+
+    *max_advance = 0;
+
+    /* Initialise load decoder */
+    Z1_Init_Decoder( &decoder );
+    Z1_Init_Builder( &decoder.builder, face, 0, 0 );
+
+    decoder.blend                = face->blend;
+    decoder.builder.metrics_only = 1;
+    decoder.builder.load_points  = 0;
+
+    /* For each glyph, parse the glyph charstring and extract */
+    /* the advance width..                                    */
+    for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
+    {
+      /* now get load the unscaled outline */
+      error = Z1_Parse_CharStrings( &decoder,
+                                    type1->charstrings    [glyph_index],
+                                    type1->charstrings_len[glyph_index],
+                                    type1->num_subrs,
+                                    type1->subrs,
+                                    type1->subrs_len );
+      /* ignore the error if one occured - skip to next glyph */
+    }
+
+    *max_advance = decoder.builder.advance.x;
+    return T1_Err_Ok;
+  }
+
+
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********              UNHINTED GLYPH LOADER                *********/
+  /**********                                                   *********/
+  /**********   The following code is in charge of loading a    *********/
+  /**********   single outline. It completely ignores hinting   *********/
+  /**********   and is used when FT_LOAD_NO_HINTING is set.     *********/
+  /**********                                                   *********/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+
+
+  LOCAL_FUNC
+  FT_Error  Z1_Load_Glyph( Z1_GlyphSlot  glyph,
+                           Z1_Size       size,
+                           FT_Int        glyph_index,
+                           FT_Int        load_flags )
+  {
+    FT_Error        error;
+    Z1_Decoder      decoder;
+    T1_Face         face = (T1_Face)glyph->root.face;
+    FT_Bool         hinting;
+    T1_Font*        type1 = &face->type1;
+
+    if (load_flags & FT_LOAD_NO_RECURSE)
+      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
+
+    glyph->x_scale = size->root.metrics.x_scale;
+    glyph->y_scale = size->root.metrics.y_scale;
+
+    glyph->root.outline.n_points   = 0;
+    glyph->root.outline.n_contours = 0;
+
+    hinting = ( load_flags & FT_LOAD_NO_SCALE   ) == 0 &&
+              ( load_flags & FT_LOAD_NO_HINTING ) == 0;
+
+    glyph->root.format = ft_glyph_format_outline;
+
+    {
+      Z1_Init_Decoder( &decoder );
+      Z1_Init_Builder( &decoder.builder, face, size, glyph );
+
+      decoder.blend              = ((T1_Face)glyph->root.face)->blend;
+      decoder.builder.no_recurse = (FT_Bool)!!(load_flags & FT_LOAD_NO_RECURSE);
+
+      /* now load the unscaled outline */
+      error = Z1_Parse_CharStrings( &decoder,
+                                    type1->charstrings    [glyph_index],
+                                    type1->charstrings_len[glyph_index],
+                                    type1->num_subrs,
+                                    type1->subrs,
+                                    type1->subrs_len );
+
+      /* save new glyph tables */
+      Z1_Done_Builder( &decoder.builder );
+    }
+
+    /* Now, set the metrics.. - this is rather simple, as : */
+    /* the left side bearing is the xMin, and the top side  */
+    /* bearing the yMax..                                   */
+    if (!error)
+    {
+      /* for composite glyphs, return only the left side bearing and the */
+      /* advance width..                                                 */
+      if ( load_flags & FT_LOAD_NO_RECURSE )
+      {
+        glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
+        glyph->root.metrics.horiAdvance  = decoder.builder.advance.x;
+      }
+      else
+      {
+        FT_BBox           cbox;
+        FT_Glyph_Metrics* metrics = &glyph->root.metrics;
+
+        /* copy the _unscaled_ advance width */
+        metrics->horiAdvance  = decoder.builder.advance.x;
+
+        /* make up vertical metrics */
+        metrics->vertBearingX = 0;
+        metrics->vertBearingY = 0;
+        metrics->vertAdvance  = 0;
+
+        glyph->root.format = ft_glyph_format_outline;
+
+        glyph->root.outline.flags &= ft_outline_owner;
+        if ( size && size->root.metrics.y_ppem < 24 )
+          glyph->root.outline.flags |= ft_outline_high_precision;
+
+        glyph->root.outline.flags |= ft_outline_reverse_fill;
+
+        /*
+        glyph->root.outline.second_pass    = TRUE;
+        glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+        glyph->root.outline.dropout_mode   = 2;
+        */
+
+        if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
+        {
+          /* scale the outline and the metrics */
+          FT_Int       n;
+          FT_Outline*  cur = decoder.builder.base;
+          FT_Vector*   vec = cur->points;
+          FT_Fixed     x_scale = glyph->x_scale;
+          FT_Fixed     y_scale = glyph->y_scale;
+
+          /* First of all, scale the points */
+          for ( n = cur->n_points; n > 0; n--, vec++ )
+          {
+            vec->x = FT_MulFix( vec->x, x_scale );
+            vec->y = FT_MulFix( vec->y, y_scale );
+          }
+
+          FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
+
+          /* Then scale the metrics */
+          metrics->horiAdvance  = FT_MulFix( metrics->horiAdvance,  x_scale );
+
+          metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
+          metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
+          metrics->vertAdvance  = FT_MulFix( metrics->vertAdvance,  x_scale );
+        }
+
+        /* apply the font matrix */
+        FT_Outline_Transform( &glyph->root.outline, &face->type1.font_matrix );
+
+        /* compute the other metrics */
+        FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
+
+        /* grid fit the bounding box if necessary */
+        if (hinting)
+        {
+          cbox.xMin &= -64;
+          cbox.yMin &= -64;
+          cbox.xMax = ( cbox.xMax+63 ) & -64;
+          cbox.yMax = ( cbox.yMax+63 ) & -64;
+        }
+
+        metrics->width  = cbox.xMax - cbox.xMin;
+        metrics->height = cbox.yMax - cbox.yMin;
+
+        metrics->horiBearingX = cbox.xMin;
+        metrics->horiBearingY = cbox.yMax;
+      }
+    }
+    return error;
+  }
+
--- /dev/null
+++ b/src/type1z/z1gload.h
@@ -1,0 +1,188 @@
+/*******************************************************************
+ *
+ *  t1gload.h                                                   1.0
+ *
+ *    Type1 Glyph Loader.
+ *
+ *  Copyright 1996-1998 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ *
+ *  The Type 1 glyph loader uses three distinct objects to build
+ *  scaled and hinted outlines from a charstrings program. These are :
+ *
+ *  - a glyph builder, Z1_Builder, used to store the built outline
+ *
+ *  - a glyph hinter, Z1_Hinter, used to record and apply the stem
+ *    hints
+ *
+ *  - a charstrings interpreter, Z1_Decoder, used to parse the
+ *    Type 1 charstrings stream, manage a stack and call the builder
+ *    and/or hinter depending on the opcodes.
+ *
+ *  Ideally, a Type 2 glyph loader would only need to have its own
+ *  T2_Decoder object (assuming the hinter is able to manage all
+ *  kinds of hints).
+ *
+ ******************************************************************/
+
+#ifndef T1GLOAD_H
+#define T1GLOAD_H
+
+#include <z1objs.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Structure> Z1_Builder                                                */
+/*                                                                       */
+/* <Description>                                                         */
+/*     a structure used during glyph loading to store its outline.       */
+/*                                                                       */
+/* <Fields>                                                              */
+/*    system :: current system object                                    */
+/*    face   :: current face object                                      */
+/*    glyph  :: current glyph slot                                       */
+/*                                                                       */
+/*    current :: current glyph outline                                   */
+/*    base    :: base glyph outline                                      */
+/*                                                                       */
+/*    max_points   :: maximum points in builder outline                  */
+/*    max_contours :: maximum contours in builder outline                */
+/*                                                                       */
+/*    last     :: last point position                                    */
+/*                                                                       */
+/*    scale_x  :: horizontal scale ( FUnits to sub-pixels )              */
+/*    scale_y  :: vertical scale   ( FUnits to sub-pixels )              */
+/*    pos_x    :: horizontal translation (composite glyphs)              */
+/*    pos_y    :: vertical translation   (composite glyph)               */
+/*                                                                       */
+/*    left_bearing  :: left side bearing point                           */
+/*    advance       :: horizontal advance vector                         */
+/*                                                                       */
+/*    path_begun    :: flag, indicates that a new path has begun         */
+/*    load_points   :: flag, if not set, no points are loaded            */
+/*                                                                       */
+/*    error         :: an error code that is only used to report         */
+/*                     memory allocation problems..                      */
+/*                                                                       */
+/*    metrics_only  :: a boolean indicating that we only want to         */
+/*                     compute the metrics of a given glyph, not load    */
+/*                     all of its points..                               */
+/*                                                                       */
+
+  typedef struct Z1_Builder_
+  {
+    FT_Memory        memory;
+    T1_Face          face;
+    Z1_GlyphSlot     glyph;
+    FT_GlyphLoader*  loader;
+
+    FT_Outline*      current;       /* the current glyph outline   */
+    FT_Outline*      base;          /* the composite glyph outline */
+
+    FT_Vector        last;
+
+    FT_Fixed         scale_x;
+    FT_Fixed         scale_y;
+
+    FT_Pos           pos_x;
+    FT_Pos           pos_y;
+
+    FT_Vector        left_bearing;
+    FT_Vector        advance;
+
+    FT_BBox          bbox;          /* bounding box */
+    FT_Bool          path_begun;
+    FT_Bool          load_points;
+    FT_Bool          no_recurse;
+
+    FT_Error         error;         /* only used for memory errors */
+    FT_Bool          metrics_only;
+
+  } Z1_Builder;
+
+
+  /* execution context charstring zone */
+  typedef struct Z1_Decoder_Zone_
+  {
+    FT_Byte*  base;
+    FT_Byte*  limit;
+    FT_Byte*  cursor;
+
+  } Z1_Decoder_Zone;
+
+
+  typedef struct Z1_Decoder_
+  {
+    Z1_Builder         builder;
+
+    FT_Int             stack[ T1_MAX_CHARSTRINGS_OPERANDS ];
+    FT_Int*            top;
+
+    Z1_Decoder_Zone    zones[ T1_MAX_SUBRS_CALLS+1 ];
+    Z1_Decoder_Zone*   zone;
+
+    FT_Int             flex_state;
+    FT_Int             num_flex_vectors;
+    FT_Vector          flex_vectors[7];
+
+    T1_Blend*          blend;  /* for multiple masters */
+
+  } Z1_Decoder;
+
+
+
+  LOCAL_DEF
+  void  Z1_Init_Builder( Z1_Builder*             builder,
+                         T1_Face                 face,
+                         Z1_Size                 size,
+                         Z1_GlyphSlot            glyph );
+
+  LOCAL_DEF
+  void Z1_Done_Builder( Z1_Builder*  builder );
+
+
+  LOCAL_DEF
+  void  Z1_Init_Decoder( Z1_Decoder* decoder );
+
+
+  /* Compute the maximum advance width of a font through quick parsing */
+  LOCAL_DEF
+  FT_Error  Z1_Compute_Max_Advance( T1_Face  face,
+                                    FT_Int  *max_advance );
+
+
+  /* This function is exported, because it is used by the T1Dump utility */
+  LOCAL_DEF
+  FT_Error   Z1_Parse_CharStrings( Z1_Decoder*  decoder,
+                                   FT_Byte*     charstring_base,
+                                   FT_Int       charstring_len,
+                                   FT_Int       num_subrs,
+                                   FT_Byte**    subrs_base,
+                                   FT_Int*      subrs_len );
+
+
+
+  LOCAL_DEF
+  FT_Error  Z1_Load_Glyph( Z1_GlyphSlot  glyph,
+                           Z1_Size       size,
+                           FT_Int        glyph_index,
+                           FT_Int        load_flags );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* T1GLOAD_H */
--- /dev/null
+++ b/src/type1z/z1load.c
@@ -1,0 +1,1473 @@
+/*******************************************************************
+ *
+ *  t1load.h                                                    2.0
+ *
+ *    Type1 Loader.
+ *
+ *  Copyright 1996-2000 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ *
+ *  This is the new and improved Type 1 data loader for FreeType 2.
+ *  The old loader has several problems: it is slow, complex, difficult
+ *  to maintain, and contains incredible hacks to make it accept some
+ *  ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5%
+ *  of the Type 1 fonts on my machine still aren't loaded correctly
+ *  by it.
+ *
+ *  This version is much simpler, much faster and also easier to
+ *  read and maintain by a great order of magnitude. The idea behind
+ *  it is to _not_ try to read the Type 1 token stream with a state
+ *  machine (i.e. a Postscript-like interpreter) but rather to perform
+ *  simple pattern-matching.
+ *
+ *  Indeed, nearly all data definitions follow a simple pattern
+ *  like :
+ *
+ *      ..... /Field <data> ....
+ *
+ *  where <data> can be a number, a boolean, a string, or an
+ *  array of numbers. There are a few exceptions, namely the
+ *  encoding, font name, charstrings and subrs and they are
+ *  handled with a special pattern-matching routine.
+ *
+ *  All other common cases are handled very simply. The matching
+ *  rules are defined in the file "t1tokens.h" through the use
+ *  of several macros calls PARSE_XXXX
+ *
+ *  This file is included twice here, the first time to generate
+ *  parsing callback functions, the second to generate a table
+ *  of keywords (with pointers to the associated callback).
+ *
+ *  The function "parse_dict" simply scans *linearly* a given
+ *  dictionary (either the top-level or private one) and calls
+ *  the appropriate callback when it encounters an immediate
+ *  keyword.
+ *
+ *  This is by far the fastest way one can find to parse and read
+ *  all data :-)
+ *
+ *  This led to tremendous code size reduction. Note that later,
+ *  the glyph loader will also be _greatly_ simplified, and the
+ *  automatic hinter will replace the clumsy "t1hinter"..
+ *
+ ******************************************************************/
+
+#include <freetype/internal/ftdebug.h>
+#include <freetype/config/ftconfig.h>
+#include <freetype/ftmm.h>
+
+#include <freetype/internal/t1types.h>
+#include <freetype/internal/t1errors.h>
+#include <z1load.h>
+#include <stdio.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_t1load
+
+#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT
+ /***************************************************************************/
+ /***************************************************************************/
+ /*****                                                                 *****/
+ /*****                    MULTIPLE MASTERS SUPPORT                     *****/
+ /*****                                                                 *****/
+ /***************************************************************************/
+ /***************************************************************************/
+
+ static  FT_Error  t1_allocate_blend( T1_Face   face,
+                                      FT_UInt   num_designs,
+                                      FT_UInt   num_axis )
+ {
+   T1_Blend*  blend;
+   FT_Memory  memory = face->root.memory;
+   FT_Error   error  = 0;
+   
+   blend = face->blend;
+   if (!blend)
+   {
+     if ( ALLOC( blend, sizeof(*blend) ) )
+       goto Exit;
+       
+     face->blend = blend;
+   }
+   
+   /* allocate design data if needed */
+   if (num_designs > 0)
+   {
+     if (blend->num_designs == 0)
+     {
+       /* allocate the blend "private" and "font_info" dictionaries */
+       if ( ALLOC_ARRAY( blend->font_infos[1], num_designs, T1_FontInfo ) ||
+            ALLOC_ARRAY( blend->privates[1], num_designs, T1_Private )    ||
+            ALLOC_ARRAY( blend->weight_vector, num_designs*2, FT_Fixed )  )
+         goto Exit;
+  
+       blend->default_weight_vector = blend->weight_vector + num_designs;
+
+       blend->font_infos[0] = &face->type1.font_info;
+       blend->privates  [0] = &face->type1.private_dict;
+       blend->num_designs   = num_designs;
+     }
+     else if (blend->num_designs != num_designs)
+       goto Fail;
+   }
+   
+   /* allocate axis data if needed */
+   if (num_axis > 0)
+   {
+     if (blend->num_axis != 0 && blend->num_axis != num_axis)
+       goto Fail;
+       
+     blend->num_axis = num_axis;
+   }
+   
+   /* allocate the blend design pos table if needed */
+   num_designs = blend->num_designs;
+   num_axis    = blend->num_axis;
+   if ( num_designs && num_axis && blend->design_pos[0] == 0)
+   {
+     FT_UInt  n;
+     
+     if ( ALLOC_ARRAY( blend->design_pos[0], num_designs*num_axis, FT_Fixed ) )
+       goto Exit;
+       
+     for ( n = 1; n < num_designs; n++ )
+       blend->design_pos[n] = blend->design_pos[0] + num_axis*n;       
+   }
+   
+ Exit:
+   return error;
+ Fail:
+   error = -1;
+   goto Exit;
+ }                                  
+
+ LOCAL_FUNC  FT_Error  Z1_Get_Multi_Master( T1_Face          face,
+                                            FT_Multi_Master* master )
+ {
+   T1_Blend*  blend = face->blend;
+   FT_UInt    n;
+   FT_Error   error;
+   
+   error = T1_Err_Invalid_Argument;
+   if (blend)
+   {
+     master->num_axis    = blend->num_axis;
+     master->num_designs = blend->num_designs;
+     for ( n = 0; n < blend->num_axis; n++ )
+     {
+       FT_MM_Axis*    axis = master->axis + n;
+       T1_DesignMap*  map = blend->design_map + n;
+       
+       axis->name    = blend->axis_names[n];
+       axis->minimum = map->design_points[0];
+       axis->maximum = map->design_points[map->num_points-1];
+     }
+     error = 0;
+   }
+   return error;
+ }                                            
+
+
+ LOCAL_FUNC  FT_Error  Z1_Set_MM_Blend( T1_Face    face,
+                                        FT_UInt    num_coords,
+                                        FT_Fixed*  coords )
+ {
+   T1_Blend*  blend = face->blend;
+   FT_Error   error;
+   FT_UInt    n, m;
+   
+   error = T1_Err_Invalid_Argument;
+   if (blend && blend->num_axis == num_coords)
+   {
+     /* recompute the weight vector from the blend coordinates */
+     error = 0;
+     for ( n = 0; n < blend->num_designs; n++ )
+     {
+       FT_Fixed  result = 0x10000L;  /* 1.0 fixed */
+       for ( m = 0; m < blend->num_axis; m++ )
+       {
+         FT_Fixed  factor;
+
+         /* get current blend axis position */
+         factor = coords[m];
+         if (factor < 0) factor = 0;
+         if (factor > 0x10000L) factor = 0x10000L;
+         
+         if ((n & (1 << m)) == 0)
+           factor = 0x10000L - factor;
+           
+         result = FT_MulFix( result, factor );
+       }
+       blend->weight_vector[n] = result;
+     }
+     error = 0;
+   }
+   return error;
+ }
+ 
+
+ LOCAL_FUNC  FT_Error  Z1_Set_MM_Design( T1_Face   face,
+                                         FT_UInt   num_coords,
+                                         FT_Long*  coords )
+ {
+   T1_Blend*  blend = face->blend;
+   FT_Error   error;
+   FT_UInt    n, p;
+   
+   error = T1_Err_Invalid_Argument;
+   if (blend && blend->num_axis == num_coords)
+   {
+     /* compute the blend coordinates through the blend design map */
+     FT_Fixed  final_blends[ T1_MAX_MM_DESIGNS ];
+     
+     for ( n = 0; n < blend->num_axis; n++ )
+     {
+       FT_Long        design = coords[n];
+       FT_Fixed       the_blend;
+       T1_DesignMap*  map     = blend->design_map + n;
+       FT_Fixed*      designs = map->design_points;
+       FT_Fixed*      blends  = map->blend_points;
+       FT_Int         before = -1, after = -1;
+       
+       for ( p = 0; p < map->num_points; p++ )
+       {
+         FT_Fixed  p_design = designs[p];
+         
+         /* exact match ? */
+         if (design == p_design)
+         {
+           the_blend = blends[p];
+           goto Found;
+         }
+         
+         if (design < p_design)
+         {
+           after = p;
+           break;
+         }
+         
+         before = p;
+       }
+       
+       /* now, interpolate if needed */
+       if (before < 0)
+         the_blend = blends[0];
+         
+       else if (after < 0)
+         the_blend = blends[map->num_points-1];
+         
+       else
+         the_blend = FT_MulDiv( design         - designs[before],
+                                blends [after] - blends [before],
+                                designs[after] - designs[before] );
+     Found:
+       final_blends[n] = the_blend;
+     }
+
+     error = Z1_Set_MM_Blend( face, num_coords, final_blends );     
+   }
+   return error;
+ }
+
+ 
+ LOCAL_FUNC  void Z1_Done_Blend( T1_Face  face )
+ {
+   FT_Memory  memory = face->root.memory;
+   T1_Blend*  blend  = face->blend;
+   
+   if (blend)
+   {
+     FT_UInt  num_designs = blend->num_designs;
+     FT_UInt  num_axis    = blend->num_axis;
+     FT_UInt  n;
+          
+     /* release design pos table */
+     FREE( blend->design_pos[0] );
+     for ( n = 1; n < num_designs; n++ )
+       blend->design_pos[n] = 0;
+
+     /* release blend "private" and "font info" dictionaries */
+     FREE( blend->privates[1] );
+     FREE( blend->font_infos[1] );
+     for ( n = 0; n < num_designs; n++ )
+     {
+       blend->privates  [n] = 0;
+       blend->font_infos[n] = 0;
+     }
+
+     /* release weight vectors */
+     FREE( blend->weight_vector );
+     blend->default_weight_vector = 0;
+
+     /* release axis names */
+     for ( n = 0; n < num_axis; n++ )
+       FREE( blend->axis_names[n] );
+     
+     /* release design map */
+     for ( n = 0; n < num_axis; n++ )
+     {
+       T1_DesignMap*  dmap = blend->design_map + n;
+       FREE( dmap->design_points );
+       dmap->num_points = 0;
+     }
+     
+     FREE( face->blend );
+   }
+ }
+
+
+
+ static  void  parse_blend_axis_types( T1_Face  face, Z1_Loader*  loader )
+ {
+   Z1_Token_Rec  axis_tokens[ T1_MAX_MM_AXIS ];
+   FT_Int        n, num_axis;
+   FT_Error      error = 0;
+   T1_Blend*     blend;
+   FT_Memory     memory;
+
+   /* take an array of objects */
+   Z1_ToTokenArray( &loader->parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis );
+   if (num_axis <= 0 || num_axis > T1_MAX_MM_AXIS)
+   {
+     FT_ERROR(( "T1.parse_blend_axis_types: incorrect number of axis: %d\n",
+                num_axis ));
+     error = T1_Err_Invalid_File_Format;
+     goto Exit;
+   }
+   
+   /* allocate blend if necessary */
+   error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
+   if (error) goto Exit;
+   
+   blend  = face->blend;
+   memory = face->root.memory;
+   
+   /* 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;
+     FT_Byte*       name;
+     FT_Int         len;
+     
+     /* skip first slash, if any */
+     if (token->start[0] == '/')
+       token->start++;
+       
+     len = token->limit - token->start;
+     if (len <= 0)
+     {
+       error = T1_Err_Invalid_File_Format;
+       goto Exit;
+     }
+       
+     if ( ALLOC( blend->axis_names[n], len+1 ) )
+       goto Exit;
+     
+     name = (FT_Byte*)blend->axis_names[n];
+     MEM_Copy( name, token->start, len );
+     name[len] = 0;
+   }
+
+ Exit:   
+   loader->parser.error = error;
+ }
+ 
+ 
+ static void  parse_blend_design_positions( T1_Face  face, Z1_Loader*  loader )
+ {
+   Z1_Token_Rec  design_tokens[ T1_MAX_MM_DESIGNS ];
+   FT_Int        num_designs;
+   FT_Int        num_axis;
+   Z1_Parser*    parser = &loader->parser;
+   
+   FT_Error      error = 0;
+   T1_Blend*     blend;
+
+   /* get the array of design tokens - compute number of designs */   
+   Z1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs );
+   if (num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS)
+   {
+     FT_ERROR(( "T1.design positions: incorrect number of designs: %d\n",
+                num_designs ));
+     error = T1_Err_Invalid_File_Format;
+     goto Exit;
+   }
+   
+   {
+     FT_Byte*  old_cursor = parser->cursor;
+     FT_Byte*  old_limit  = parser->limit;
+     FT_UInt   n;
+
+     blend    = face->blend;
+     num_axis = 0;  /* make compiler happy */
+     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;
+
+       /* read axis/coordinates tokens */
+       token = design_tokens + n;
+       parser->cursor = token->start - 1;
+       parser->limit  = token->limit + 1;
+       Z1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
+       
+       if (n == 0)
+       {
+         num_axis = n_axis;
+         error = t1_allocate_blend( face, num_designs, num_axis );
+         if (error) goto Exit;
+         blend = face->blend;
+       }
+       else if (n_axis != num_axis)
+       {
+         FT_ERROR(( "T1.design_positions: incorrect table\n" ));
+         error = T1_Err_Invalid_File_Format;
+         goto Exit;
+       }
+       
+       /* now, read each axis token into the design position */
+       for (axis = 0; axis < n_axis; axis++ )
+       {
+         Z1_Token_Rec*  token2 = axis_tokens + axis;
+         parser->cursor = token2->start;
+         parser->limit  = token2->limit;
+         blend->design_pos[n][axis] = Z1_ToFixed( parser, 0 );
+       }
+     }
+     
+     loader->parser.cursor = old_cursor;
+     loader->parser.limit  = old_limit;
+   }
+   
+ Exit:
+   loader->parser.error = error;
+ }
+
+ static void  parse_blend_design_map( T1_Face  face, Z1_Loader*  loader )
+ {
+   FT_Error      error  = 0;
+   Z1_Parser*    parser = &loader->parser;
+   T1_Blend*     blend;
+   Z1_Token_Rec  axis_tokens[ T1_MAX_MM_AXIS ];
+   FT_Int        n, num_axis;
+   FT_Byte*      old_cursor;
+   FT_Byte*      old_limit;
+   FT_Memory     memory = face->root.memory;
+   
+   Z1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis );
+   if (num_axis <= 0 || num_axis > T1_MAX_MM_AXIS)
+   {
+     FT_ERROR(( "T1.design map: incorrect number of axis: %d\n",
+                num_axis ));
+     error = T1_Err_Invalid_File_Format;
+     goto Exit;
+   }
+   old_cursor = parser->cursor;
+   old_limit  = parser->limit;
+
+   error = t1_allocate_blend( face, 0, num_axis );
+   if (error) goto Exit;
+   blend = face->blend;
+
+   /* now, read each axis design map */
+   for ( n = 0; n < num_axis; n++ )
+   {
+     T1_DesignMap*   map = blend->design_map + n;
+     Z1_Token_Rec*   token;
+     FT_Int          p, num_points;
+     
+     token = axis_tokens + n;
+     parser->cursor = token->start;
+     parser->limit  = token->limit;
+     
+     /* count the number of map points */
+     {
+       FT_Byte*  p     = token->start;
+       FT_Byte*  limit = token->limit;
+       
+       num_points = 0;
+       for ( ; p < limit; p++ )
+         if (p[0] == '[')
+           num_points++;
+     }
+     if (num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS)
+     {
+       FT_ERROR(( "T1.design map: incorrect table\n" ));
+       error = T1_Err_Invalid_File_Format;
+       goto Exit;
+     }
+     
+     /* allocate design map data */
+     if ( ALLOC_ARRAY( map->design_points, num_points*2, FT_Fixed ) )
+       goto Exit;
+     map->blend_points = map->design_points + num_points;
+     map->num_points   = (FT_Byte)num_points;
+     
+     for ( p = 0; p < num_points; p++ )
+     {
+       map->design_points[p] = Z1_ToInt( parser );
+       map->blend_points [p] = Z1_ToFixed( parser, 0 );
+     }
+   }   
+   
+   parser->cursor = old_cursor;
+   parser->limit  = old_limit;
+ Exit:
+   parser->error = error;
+ }
+
+ static void parse_weight_vector( T1_Face   face, Z1_Loader*  loader )
+ {
+   FT_Error      error  = 0;
+   Z1_Parser*    parser = &loader->parser;
+   T1_Blend*     blend  = face->blend;
+   Z1_Token_Rec  master;
+   FT_UInt       n;
+   FT_Byte*      old_cursor;
+   FT_Byte*      old_limit;
+   
+   if (!blend || blend->num_designs == 0)
+   {
+     FT_ERROR(( "t1.weight_vector: too early !!\n" ));
+     error = T1_Err_Invalid_File_Format;
+     goto Exit;
+   }
+   
+   Z1_ToToken( parser, &master );
+   if (master.type != t1_token_array)
+   {
+     FT_ERROR(( "t1.weight_vector: incorrect format !!\n" ));
+     error = T1_Err_Invalid_File_Format;
+     goto Exit;
+   }
+   
+   old_cursor = parser->cursor;
+   old_limit  = parser->limit;
+
+   parser->cursor = master.start;
+   parser->limit  = master.limit;
+   for ( n = 0; n < blend->num_designs; n++ )
+   {
+     blend->default_weight_vector[n] =
+     blend->weight_vector[n]         = Z1_ToFixed( parser, 0 );
+   }
+   
+   parser->cursor = old_cursor;
+   parser->limit  = old_limit;
+ Exit:
+   parser->error = error;
+ }
+
+ /* the keyword /shareddict appears in some multiple master fonts with a lot */
+ /* of Postscript garbage behind it (that's completely out of spec !!), we   */
+ /* detect it and terminate the parsing                                      */
+ static  void parse_shared_dict( T1_Face  face, Z1_Loader*  loader )
+ {
+   Z1_Parser*  parser = &loader->parser;
+   
+   UNUSED(face);
+   
+   parser->cursor = parser->limit;
+   parser->error  = 0;
+ }
+#endif
+ 
+ /***************************************************************************/
+ /***************************************************************************/
+ /*****                                                                 *****/
+ /*****                      TYPE 1 SYMBOL PARSING                      *****/
+ /*****                                                                 *****/
+ /***************************************************************************/
+ /***************************************************************************/
+
+ /*********************************************************************
+  *
+  *  First of all, define the token field static variables. This is
+  *  a set of Z1_Field_Rec variables used later..
+  *
+  *********************************************************************/
+
+#define Z1_NEW_STRING( _name, _field ) \
+   static const  Z1_Field_Rec  t1_field_ ## _field = Z1_FIELD_STRING( T1TYPE, _field );
+
+#define Z1_NEW_BOOL( _name, _field )   \
+   static const  Z1_Field_Rec  t1_field_ ## _field = Z1_FIELD_BOOL( T1TYPE, _field );
+   
+#define Z1_NEW_NUM( _name, _field )    \
+   static const  Z1_Field_Rec  t1_field_ ## _field = Z1_FIELD_NUM( T1TYPE, _field );
+   
+#define Z1_NEW_FIXED( _name, _field )  \
+   static const  Z1_Field_Rec  t1_field_ ## _field = Z1_FIELD_FIXED( T1TYPE, _field, _power );
+
+#define Z1_NEW_NUM_TABLE( _name, _field, _max, _count ) \
+   static const  Z1_Field_Rec  t1_field_ ## _field = Z1_FIELD_NUM_ARRAY( T1TYPE, _field, _count, _max );
+   
+#define Z1_NEW_FIXED_TABLE( _name, _field, _max, _count ) \
+   static const  Z1_Field_Rec  t1_field_ ## _field = Z1_FIELD_FIXED_ARRAY( T1TYPE, _field, _count, _max );
+
+#define Z1_NEW_NUM_TABLE2( _name, _field, _max ) \
+   static const  Z1_Field_Rec  t1_field_ ## _field = Z1_FIELD_NUM_ARRAY2( T1TYPE, _field, _max );
+   
+#define Z1_NEW_FIXED_TABLE2( _name, _field, _max ) \
+   static const  Z1_Field_Rec  t1_field_ ## _field = Z1_FIELD_FIXED_ARRAY2( T1TYPE, _field, _max );
+
+
+#define Z1_FONTINFO_STRING(n,f)        Z1_NEW_STRING(n,f)
+#define Z1_FONTINFO_NUM(n,f)           Z1_NEW_NUM(n,f)
+#define Z1_FONTINFO_BOOL(n,f)          Z1_NEW_BOOL(n,f)
+#define Z1_PRIVATE_NUM(n,f)            Z1_NEW_NUM(n,f)
+#define Z1_PRIVATE_FIXED(n,f)          Z1_NEW_FIXED(n,f)
+#define Z1_PRIVATE_NUM_TABLE(n,f,m,c)  Z1_NEW_NUM_TABLE(n,f,m,c)
+#define Z1_PRIVATE_NUM_TABLE2(n,f,m)   Z1_NEW_NUM_TABLE2(n,f,m)
+#define Z1_TOPDICT_NUM(n,f)            Z1_NEW_NUM(n,f)
+#define Z1_TOPDICT_NUM_FIXED2(n,f,m)   Z1_NEW_FIXED_TABLE2(n,f,m)
+
+/* including this file defines all field variables */
+#include <z1tokens.h>
+
+ /*********************************************************************
+  *
+  *  Second, define the keyword variables. This is a set of Z1_KeyWord
+  *  structures used to model the way each keyword is "loaded"..
+  *
+  *********************************************************************/
+
+  typedef  void  (*Z1_Parse_Func)( T1_Face   face, Z1_Loader*  loader );
+
+  typedef enum Z1_KeyWord_Type_
+  {
+    t1_keyword_callback = 0,
+    t1_keyword_field,
+    t1_keyword_field_table
+    
+  } Z1_KeyWord_Type;
+  
+  typedef enum Z1_KeyWord_Location_
+  {
+    t1_keyword_type1 = 0,
+    t1_keyword_font_info,
+    t1_keyword_private
+  
+  } Z1_KeyWord_Location;
+  
+  typedef  struct Z1_KeyWord_
+  {
+    const char*          name;
+    Z1_KeyWord_Type      type;
+    Z1_KeyWord_Location  location;
+    Z1_Parse_Func        parsing;
+    const Z1_Field_Rec*  field;
+
+  } Z1_KeyWord;
+
+
+#define Z1_KEYWORD_CALLBACK( name, callback )  \
+         { name, t1_keyword_callback, t1_keyword_type1, callback, 0 }
+
+#define Z1_KEYWORD_TYPE1( name, f ) \
+         { name, t1_keyword_field, t1_keyword_type1, 0, &t1_field_ ## f }
+         
+#define Z1_KEYWORD_FONTINFO( name, f ) \
+         { name, t1_keyword_field, t1_keyword_font_info, 0, &t1_field_ ## f }
+
+#define Z1_KEYWORD_PRIVATE( name, f ) \
+         { name, t1_keyword_field, t1_keyword_private, 0, &t1_field_ ## f }
+
+#define Z1_KEYWORD_FONTINFO_TABLE( name, f ) \
+         { name, t1_keyword_field_table, t1_keyword_font_info, 0, &t1_field_ ## f }
+
+#define Z1_KEYWORD_PRIVATE_TABLE( name, f ) \
+         { name, t1_keyword_field_table, t1_keyword_private, 0, &t1_field_ ## f }
+
+#undef  Z1_FONTINFO_STRING
+#undef  Z1_FONTINFO_NUM
+#undef  Z1_FONTINFO_BOOL
+#undef  Z1_PRIVATE_NUM
+#undef  Z1_PRIVATE_FIXED
+#undef  Z1_PRIVATE_NUM_TABLE
+#undef  Z1_PRIVATE_NUM_TABLE2
+#undef  Z1_TOPDICT_NUM
+#undef  Z1_TOPDICT_NUM_FIXED2
+
+#define Z1_FONTINFO_STRING(n,f)        Z1_KEYWORD_FONTINFO(n,f),
+#define Z1_FONTINFO_NUM(n,f)           Z1_KEYWORD_FONTINFO(n,f),
+#define Z1_FONTINFO_BOOL(n,f)          Z1_KEYWORD_FONTINFO(n,f),
+#define Z1_PRIVATE_NUM(n,f)            Z1_KEYWORD_PRIVATE(n,f),
+#define Z1_PRIVATE_FIXED(n,f)          Z1_KEYWORD_PRIVATE(n,f),
+#define Z1_PRIVATE_NUM_TABLE(n,f,m,c)  Z1_KEYWORD_PRIVATE_TABLE(n,f),
+#define Z1_PRIVATE_NUM_TABLE2(n,f,m)   Z1_KEYWORD_PRIVATE_TABLE(n,f),
+#define Z1_TOPDICT_NUM(n,f)            Z1_KEYWORD_TYPE1(n,f),
+#define Z1_TOPDICT_NUM_FIXED2(n,f,m)   Z1_KEYWORD_TYPE1(n,f),
+
+
+  static  FT_Error   t1_load_keyword( T1_Face     face,
+                                      Z1_Loader*  loader,
+                                      Z1_KeyWord* keyword )
+  {
+    FT_Error  error;
+    void*     dummy_object;
+    void**    objects;
+    FT_UInt   max_objects;
+    T1_Blend* blend = face->blend;
+    
+    /* if the keyword has a dedicated callback, call it */
+    if (keyword->type == t1_keyword_callback)
+    {
+      keyword->parsing( face, loader );
+      error = loader->parser.error;
+      goto Exit;
+    }
+    
+    /* now, the keyword is either a simple field, or a table of fields */
+    /* we are now going to take care of it..                           */
+    switch (keyword->location)
+    {
+      case t1_keyword_font_info:
+        {
+          dummy_object = &face->type1.font_info;
+          objects      = &dummy_object;
+          max_objects  = 0;
+          if (blend)
+          {
+            objects     = (void**)blend->font_infos;
+            max_objects = blend->num_designs;
+          }
+        }
+        break;
+        
+      case t1_keyword_private:
+        {
+          dummy_object = &face->type1.private_dict;
+          objects      = &dummy_object;
+          max_objects  = 0;
+          if (blend)
+          {
+            objects     = (void**)blend->privates;
+            max_objects = blend->num_designs;
+          }
+        }
+        break;
+      
+      default:
+        dummy_object = &face->type1;
+        objects      = &dummy_object;
+        max_objects  = 0;
+    }
+    
+    if (keyword->type == t1_keyword_field_table)
+      error = Z1_Load_Field_Table( &loader->parser, keyword->field, objects, max_objects, 0 );
+    else
+      error = Z1_Load_Field( &loader->parser, keyword->field, objects, max_objects, 0 );
+    
+  Exit:
+    return error;
+  }                                
+
+
+  static
+  int  is_space( char c )
+  {
+    return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' );
+  }
+
+  static
+  int  is_alpha( char c )
+  {
+    return ( (c >= 'A' && c <= 'Z') ||
+             (c >= 'a' && c <= 'z') ||
+             (c >= '0' && c <= '9') ||
+             (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;
+
+    /* the binary data has the following format */
+    /*                                          */
+    /* "size" [white*] RD white ....... ND      */
+    /*                                          */
+
+    skip_whitespace(parser);
+    cur = parser->cursor;
+
+    if ( cur < limit && (FT_Byte)(*cur-'0') < 10 )
+    {
+      *size = Z1_ToInt(parser);
+
+      skip_whitespace(parser);
+      skip_blackspace(parser);  /* "RD" or "-|" or something else */
+
+      /* there is only one whitespace char after the */
+      /* "RD" or "-|" token                          */
+      *base = parser->cursor + 1;
+
+      parser->cursor += *size+1;
+      return 1;
+    }
+
+    FT_ERROR(( "type1.read_binary_data: invalid size field\n" ));
+    parser->error = T1_Err_Invalid_File_Format;
+    return 0;
+  }
+
+
+  /* we will now define the routines used to handle */
+  /* the /Encoding, /Subrs and /CharStrings         */
+  /* dictionaries..                                 */
+
+  static
+  void  parse_font_name( T1_Face  face, Z1_Loader*  loader )
+  {
+    Z1_Parser*  parser = &loader->parser;
+    FT_Error    error;
+    FT_Memory   memory = parser->memory;
+    FT_Int      len;
+    FT_Byte*    cur;
+    FT_Byte*    cur2;
+    FT_Byte*    limit;
+
+    skip_whitespace(parser);
+    cur   = parser->cursor;
+    limit = parser->limit;
+    if ( cur >= limit-1 || *cur != '/' ) return;
+
+    cur++;
+    cur2 = cur;
+    while (cur2 < limit && is_alpha(*cur2)) cur2++;
+    len = cur2-cur;
+    if (len > 0)
+    {
+      if ( ALLOC( face->type1.font_name, len+1 ) )
+      {
+        parser->error = error;
+        return;
+      }
+
+      MEM_Copy( face->type1.font_name, cur, len );
+      face->type1.font_name[len] = '\0';
+    }
+    parser->cursor = cur2;
+  }
+
+  static
+  void  parse_font_bbox( T1_Face  face, Z1_Loader*  loader )
+  {
+    Z1_Parser*  parser = &loader->parser;
+    FT_Short    temp[4];
+    FT_BBox*    bbox = &face->type1.font_bbox;
+
+    (void)Z1_ToCoordArray( parser, 4, temp );
+    bbox->xMin = temp[0];
+    bbox->yMin = temp[1];
+    bbox->xMax = temp[2];
+    bbox->yMax = temp[3];
+  }
+
+  static
+  void  parse_font_matrix( T1_Face  face, Z1_Loader*  loader )
+  {
+    Z1_Parser*  parser = &loader->parser;
+    FT_Matrix*  matrix = &face->type1.font_matrix;
+    FT_Fixed    temp[4];
+
+    (void)Z1_ToFixedArray( parser, 4, temp, 3 );
+    matrix->xx = temp[0];
+    matrix->yx = temp[1];
+    matrix->xy = temp[2];
+    matrix->yy = temp[3];
+  }
+
+
+
+  static
+  void  parse_encoding( T1_Face  face, Z1_Loader*  loader )
+  {
+    Z1_Parser*  parser = &loader->parser;
+    FT_Byte*    cur   = parser->cursor;
+    FT_Byte*    limit = parser->limit;
+
+    /* skip whitespace */
+    while (is_space(*cur))
+    {
+      cur++;
+      if (cur >= limit)
+      {
+        FT_ERROR(( "type1.parse_encoding: out of bounds !!\n" ));
+        parser->error = T1_Err_Invalid_File_Format;
+        return;
+      }
+    }
+
+    /* if we have a number, then the encoding is an array, */
+    /* and we must load it now                             */
+    if ((FT_Byte)(*cur - '0') < 10)
+    {
+      T1_Encoding*  encode     = &face->type1.encoding;
+      FT_Int        count, n;
+      Z1_Table*     char_table = &loader->encoding_table;
+      FT_Memory     memory     = parser->memory;
+      FT_Error      error;
+
+      /* read the number of entries in the encoding, should be 256 */
+      count = Z1_ToInt( parser );
+      if (parser->error) return;
+
+      /* we use a Z1_Table to store our charnames */
+      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     )
+      {
+        parser->error = error;
+        return;
+      }
+
+      /* now, we will need to read a record of the form         */
+      /* ... charcode /charname ... for each entry in our table */
+      /*                                                        */
+      /* we simply look for a number followed by an immediate   */
+      /* name. Note that this ignores correctly the sequence    */
+      /* that is often seen in type1 fonts :                    */
+      /*                                                        */
+      /*   0 1 255 { 1 index exch /.notdef put } for dup        */
+      /*                                                        */
+      /* used to clean the encoding array before anything else  */
+      /*                                                        */
+      /* we stop when we encounter a "def"                      */
+      /*                                                        */
+
+      cur   = parser->cursor;
+      limit = parser->limit;
+      n     = 0;
+
+      for ( ; cur < limit; )
+      {
+        FT_Byte  c;
+
+        c = *cur;
+
+        /* we stop when we encounter a 'def' */
+        if ( c == 'd' && cur+3 < limit )
+        {
+          if ( cur[1] == 'e' &&
+               cur[2] == 'f' &&
+               is_space(cur[-1]) &&
+               is_space(cur[3]) )
+          {
+              FT_TRACE6(( "encoding end\n" ));
+              break;
+          }
+        }
+
+        /* otherwise, we must find a number before anything else */
+        if ( (FT_Byte)(c-'0') < 10 )
+        {
+          FT_Int  charcode;
+
+          parser->cursor = cur;
+          charcode = Z1_ToInt(parser);
+          cur = parser->cursor;
+
+          /* skip whitespace */
+          while (cur < limit && is_space(*cur)) cur++;
+
+          if (cur < limit && *cur == '/')
+          {
+            /* bingo, we have an immediate name - it must be a */
+            /* character name                                  */
+            FT_Byte*  cur2 = cur+1;
+            FT_Int    len;
+
+            while (cur2 < limit && is_alpha(*cur2)) cur2++;
+            len = cur2-cur-1;
+            parser->error = Z1_Add_Table( char_table, charcode, cur+1, len+1 );
+            char_table->elements[charcode][len] = '\0';
+            if (parser->error) return;
+
+            cur = cur2;
+          }
+        }
+        else
+          cur++;
+      }
+
+      face->type1.encoding_type = t1_encoding_array;
+      parser->cursor            = cur;
+    }
+    /* Otherwise, we should have either "StandardEncoding" or */
+    /* "ExpertEncoding"                                       */
+    else
+    {
+      if ( cur+17 < limit &&
+           strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
+        face->type1.encoding_type = t1_encoding_standard;
+
+      else if ( cur+15 < limit &&
+                strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
+        face->type1.encoding_type = t1_encoding_expert;
+
+      else
+      {
+        FT_ERROR(( "type1.parse_encoding: invalid token !!\n" ));
+        parser->error = T1_Err_Invalid_File_Format;
+      }
+    }
+  }
+
+
+  static
+  void  parse_subrs( T1_Face  face, Z1_Loader*  loader )
+  {
+    Z1_Parser*  parser = &loader->parser;
+    Z1_Table*   table  = &loader->subrs;
+    FT_Memory   memory = parser->memory;
+    FT_Error    error;
+    FT_Int      n;
+
+    loader->num_subrs = Z1_ToInt( parser );
+    if (parser->error) return;
+
+    /* initialise subrs array */
+    error = Z1_New_Table( table, loader->num_subrs, memory );
+    if (error) goto Fail;
+
+    /* the format is simple :                                */
+    /*                                                       */
+    /*   "index" + binary data                               */
+    /*                                                       */
+
+    for ( n = 0; n < loader->num_subrs; n++ )
+    {
+      FT_Int    index, size;
+      FT_Byte*  base;
+
+      index = Z1_ToInt(parser);
+      if (!read_binary_data(parser,&size,&base)) return;
+
+      /* some fonts use a value of -1 for lenIV to indicate that */
+      /* the charstrings are unencoded..                         */
+      /*                                                         */
+      /* thanks to Tom Kacvinsky for pointing this out..         */
+      /*                                                         */
+      if (face->type1.private_dict.lenIV >= 0)
+      {
+        Z1_Decrypt( base, size, 4330 );
+        size -= face->type1.private_dict.lenIV;
+        base += face->type1.private_dict.lenIV;
+      }
+
+      error = Z1_Add_Table( table, index, base, size );
+      if (error) goto Fail;
+    }
+    return;
+
+  Fail:
+    parser->error = error;
+  }
+
+
+
+
+  static
+  void  parse_charstrings( T1_Face  face, 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;
+    FT_Error    error;
+
+    FT_Byte*    cur;
+    FT_Byte*    limit = parser->limit;
+    FT_Int      n;
+
+    loader->num_glyphs = Z1_ToInt( parser );
+    if (parser->error) return;
+
+    /* initialise tables */
+    error = Z1_New_Table( code_table, loader->num_glyphs, memory ) ||
+            Z1_New_Table( name_table, loader->num_glyphs, memory );
+    if (error) goto Fail;
+
+    n = 0;
+    for ( ;; )
+    {
+      FT_Int    size;
+      FT_Byte*  base;
+
+      /* the format is simple :                   */
+      /*   "/glyphname" + binary data             */
+      /*                                          */
+      /* note that we stop when we find a "def"   */
+      /*                                          */
+      skip_whitespace(parser);
+      cur = parser->cursor;
+      if (cur >= limit) break;
+
+      /* we stop when we find a "def" or "end" keyword */
+      if (*cur    == 'd' &&
+           cur+3 < limit &&
+           cur[1] == 'e' &&
+           cur[2] == 'f' )
+        break;
+
+      if (*cur == 'e'   &&
+          cur+3 < limit &&
+          cur[1] == 'n' &&
+          cur[2] == 'd' )
+        break;
+
+      if (*cur != '/')
+        skip_blackspace(parser);
+      else
+      {
+        FT_Byte*  cur2 = cur+1;
+        FT_Int    len;
+
+        while (cur2 < limit && is_alpha(*cur2)) cur2++;
+        len = cur2-cur-1;
+
+        error = Z1_Add_Table( name_table, n, cur+1, len+1 );
+        if (error) goto Fail;
+
+        /* add a trailing zero to the name table */
+        name_table->elements[n][len] = '\0';
+
+        parser->cursor = cur2;
+        if (!read_binary_data(parser,&size,&base)) return;
+
+        /* some fonts use a value of -1 for lenIV to indicate that */
+        /* the charstrings are unencoded..                         */
+        /*                                                         */
+        /* thanks to Tom Kacvinsky for pointing this out..         */
+        /*                                                         */
+        if (face->type1.private_dict.lenIV >= 0)
+        {
+          Z1_Decrypt( base, size, 4330 );
+          size -= face->type1.private_dict.lenIV;
+          base += face->type1.private_dict.lenIV;
+        }
+
+        error = Z1_Add_Table( code_table, n, base, size );
+        if (error) goto Fail;
+
+        n++;
+        if (n >= loader->num_glyphs)
+          break;
+      }
+    }
+    loader->num_glyphs = n;
+    return;
+
+  Fail:
+    parser->error = error;
+  }
+
+
+
+
+  static
+  const Z1_KeyWord  t1_keywords[] =
+  {
+#include <z1tokens.h>  
+    
+    /* now add the special functions... */
+    Z1_KEYWORD_CALLBACK( "FontName", parse_font_name ),
+    Z1_KEYWORD_CALLBACK( "FontBBox", parse_font_bbox ),
+    Z1_KEYWORD_CALLBACK( "FontMatrix", parse_font_matrix ),
+    Z1_KEYWORD_CALLBACK( "Encoding", parse_encoding  ),
+    Z1_KEYWORD_CALLBACK( "Subrs",    parse_subrs     ),
+    Z1_KEYWORD_CALLBACK( "CharStrings", parse_charstrings ),
+#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT
+    Z1_KEYWORD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions ),
+    Z1_KEYWORD_CALLBACK( "BlendDesignMap", parse_blend_design_map ),
+    Z1_KEYWORD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ),
+    Z1_KEYWORD_CALLBACK( "WeightVector", parse_weight_vector ),
+    Z1_KEYWORD_CALLBACK( "shareddict",   parse_shared_dict ),
+#endif    
+    Z1_KEYWORD_CALLBACK( 0, 0 )
+  };
+
+
+  static
+  FT_Error  parse_dict( T1_Face     face,
+                        Z1_Loader*  loader,
+                        FT_Byte*    base,
+                        FT_Long     size )
+  {
+    Z1_Parser*  parser   = &loader->parser;
+
+    parser->cursor = base;
+    parser->limit  = base + size;
+    parser->error  = 0;
+
+    {
+      FT_Byte*  cur     = base;
+      FT_Byte*  limit   = cur + size;
+
+      for ( ;cur < limit; cur++ )
+      {
+        /* look for "FontDirectory", which causes problems on some fonts */
+        if ( *cur == 'F' && cur+25 < limit &&
+             strncmp( (char*)cur, "FontDirectory", 13 ) == 0 )
+        {
+          FT_Byte*  cur2;
+          
+          /* skip the "FontDirectory" keyword */
+          cur += 13;
+          cur2 = cur;
+          
+          /* lookup the 'known' keyword */
+          while (cur < limit && *cur != 'k' && strncmp( (char*)cur, "known", 5 ) )
+            cur++;
+          
+          if (cur < limit)
+          {
+            Z1_Token_Rec  token;
+            
+            /* skip the "known" keyword and the token following it */
+            cur += 5;
+            loader->parser.cursor = cur;
+            Z1_ToToken( &loader->parser, &token );
+            
+            /* if the last token was an array, skip it !! */
+            if (token.type == t1_token_array)
+              cur2 = parser->cursor;
+          }
+          cur = cur2;
+        }
+        /* look for immediates */
+        else if (*cur == '/' && cur+2 < limit)
+        {
+          FT_Byte* cur2;
+          FT_Int   len;
+
+          cur  ++;
+          cur2 = cur;
+          while (cur2 < limit && is_alpha(*cur2)) cur2++;
+          len  = cur2-cur;
+
+          if (len > 0 && len < 22)
+          {
+            if (!loader->fontdata)
+            {
+              if ( strncmp( (char*)cur, "FontInfo", 8 ) == 0 )
+                loader->fontdata = 1;
+            }
+            else
+            {
+              /* now, compare the immediate name to the keyword table */
+              Z1_KeyWord*  keyword = (Z1_KeyWord*)t1_keywords;
+  
+              for (;;)
+              {
+                FT_Byte*  name;
+  
+                name = (FT_Byte*)keyword->name;
+                if (!name) break;
+  
+                if ( cur[0] == name[0] &&
+                     len == (FT_Int)strlen((const char*)name) )
+                {
+                  FT_Int  n;
+                  for ( n = 1; n < len; n++ )
+                    if (cur[n] != name[n])
+                      break;
+  
+                  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;
+  
+                    cur = parser->cursor;
+                    break;
+                  }
+                }
+                keyword++;
+              }
+            }
+          }
+        }
+      }
+    }
+    return parser->error;
+  }
+
+  static
+  void t1_init_loader( Z1_Loader* loader, T1_Face  face )
+  {
+    UNUSED(face);
+
+    MEM_Set( loader, 0, sizeof(*loader) );
+    loader->num_glyphs = 0;
+    loader->num_chars  = 0;
+
+    /* initialize the tables - simply set their 'init' field to 0 */
+    loader->encoding_table.init = 0;
+    loader->charstrings.init    = 0;
+    loader->glyph_names.init    = 0;
+    loader->subrs.init          = 0;
+    loader->fontdata            = 0;
+  }
+
+  static
+  void t1_done_loader( Z1_Loader* loader )
+  {
+    Z1_Parser*  parser = &loader->parser;
+
+    /* finalize tables */
+    Z1_Release_Table( &loader->encoding_table );
+    Z1_Release_Table( &loader->charstrings );
+    Z1_Release_Table( &loader->glyph_names );
+    Z1_Release_Table( &loader->subrs );
+
+    /* finalize parser */
+    Z1_Done_Parser( parser );
+  }
+
+  LOCAL_FUNC
+  FT_Error  Z1_Open_Face( T1_Face  face )
+  {
+    Z1_Loader  loader;
+    Z1_Parser* parser;
+    T1_Font*   type1 = &face->type1;
+    FT_Error   error;
+
+    t1_init_loader( &loader, face );
+
+    /* default lenIV */
+    type1->private_dict.lenIV = 4;
+
+    parser = &loader.parser;
+    error = Z1_New_Parser( parser, face->root.stream, face->root.memory );
+    if (error) goto Exit;
+
+    error = parse_dict( face, &loader, parser->base_dict, parser->base_len );
+    if (error) goto Exit;
+
+    error = Z1_Get_Private_Dict( parser );
+    if (error) goto Exit;
+
+    error = parse_dict( face, &loader, parser->private_dict, parser->private_len );
+    if (error) goto Exit;
+
+    /* now, propagate the subrs, charstrings and glyphnames tables */
+    /* to the Type1 data                                           */
+    type1->num_glyphs = loader.num_glyphs;
+
+    if ( !loader.subrs.init )
+    {
+      FT_ERROR(( "T1.Open_Face: no subrs array in face !!\n" ));
+      error = T1_Err_Invalid_File_Format;
+    }
+
+    if ( !loader.charstrings.init )
+    {
+      FT_ERROR(( "T1.Open_Face: no charstrings array in face !!\n" ));
+      error = T1_Err_Invalid_File_Format;
+    }
+
+    loader.subrs.init  = 0;
+    type1->num_subrs   = loader.num_subrs;
+    type1->subrs_block = loader.subrs.block;
+    type1->subrs       = loader.subrs.elements;
+    type1->subrs_len   = loader.subrs.lengths;
+
+    loader.charstrings.init  = 0;
+    type1->charstrings_block = loader.charstrings.block;
+    type1->charstrings       = loader.charstrings.elements;
+    type1->charstrings_len   = loader.charstrings.lengths;
+
+    /* we copy the glyph names "block" and "elements" fields */
+    /* but the "lengths" field must be released later..      */
+    type1->glyph_names_block    = loader.glyph_names.block;
+    type1->glyph_names          = (FT_String**)loader.glyph_names.elements;
+    loader.glyph_names.block    = 0;
+    loader.glyph_names.elements = 0;
+
+    /* we must now build type1.encoding when we have a custom */
+    /* array..                                                */
+    if ( type1->encoding_type == t1_encoding_array )
+    {
+      FT_Int    charcode, index, min_char, max_char;
+      FT_Byte*  char_name;
+      FT_Byte*  glyph_name;
+
+      /* OK, we do the following : for each element in the encoding */
+      /* table, lookup the index of the glyph having the same name  */
+      /* the index is then stored in type1.encoding.char_index, and */
+      /* a the name to type1.encoding.char_name                     */
+
+      min_char = +32000;
+      max_char = -32000;
+
+      charcode = 0;
+      for ( ; charcode < loader.encoding_table.num_elems; charcode++ )
+      {
+        type1->encoding.char_index[charcode] = 0;
+        type1->encoding.char_name [charcode] = ".notdef";
+
+        char_name = loader.encoding_table.elements[charcode];
+        if (char_name)
+          for ( index = 0; index < type1->num_glyphs; index++ )
+          {
+            glyph_name = (FT_Byte*)type1->glyph_names[index];
+            if ( strcmp( (const char*)char_name,
+                         (const char*)glyph_name ) == 0 )
+            {
+              type1->encoding.char_index[charcode] = index;
+              type1->encoding.char_name [charcode] = (char*)glyph_name;
+
+              if (charcode < min_char) min_char = charcode;
+              if (charcode > max_char) max_char = charcode;
+              break;
+            }
+          }
+      }
+      type1->encoding.code_first = min_char;
+      type1->encoding.code_last  = max_char;
+      type1->encoding.num_chars  = loader.num_chars;
+   }
+
+  Exit:
+    t1_done_loader( &loader );
+    return error;
+  }
--- /dev/null
+++ b/src/type1z/z1load.h
@@ -1,0 +1,77 @@
+/*******************************************************************
+ *
+ *  t1load.h                                                    2.0
+ *
+ *    Type1 Loader.
+ *
+ *  Copyright 1996-2000 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef T1LOAD_H
+#define T1LOAD_H
+
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/t1types.h>
+#include <freetype/ftmm.h>
+#include <z1parse.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+  typedef struct Z1_Loader_
+  {
+    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       */
+                                /* encoding character names         */
+
+    FT_Int           num_glyphs;
+    Z1_Table         glyph_names;
+    Z1_Table         charstrings;
+
+    FT_Int           num_subrs;
+    Z1_Table         subrs;
+    FT_Bool          fontdata;
+
+  } Z1_Loader;
+
+  LOCAL_DEF
+  FT_Error  Z1_Open_Face( T1_Face  face );
+
+#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT
+  LOCAL_DEF
+  FT_Error  Z1_Get_Multi_Master( T1_Face           face,
+                                 FT_Multi_Master*  master );
+
+  LOCAL_DEF
+  FT_Error  Z1_Set_MM_Blend( T1_Face    face,
+                             FT_UInt    num_coords,
+                             FT_Fixed*  coords );
+
+  LOCAL_DEF
+  FT_Error  Z1_Set_MM_Design( T1_Face   face,
+                              FT_UInt   num_coords,
+                              FT_Long*  coords );
+
+  LOCAL_DEF
+  void  Z1_Done_Blend( T1_Face  face );
+#endif
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* T1LOAD_H */
+
+
+/* END */
--- /dev/null
+++ b/src/type1z/z1objs.c
@@ -1,0 +1,361 @@
+/*******************************************************************
+ *
+ *  t1objs.c                                                     1.0
+ *
+ *    Type1 Objects manager.
+ *
+ *  Copyright 1996-1998 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ ******************************************************************/
+
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftstream.h>
+
+#include <z1gload.h>
+#include <z1load.h>
+#include <freetype/internal/psnames.h>
+#include <z1afm.h>
+
+/* Required by tracing mode */
+#undef   FT_COMPONENT
+#define  FT_COMPONENT  trace_t1objs
+
+/*******************************************************************
+ *                                                                 *
+ *                         FACE  FUNCTIONS                         *
+ *                                                                 *
+ *                                                                 *
+ *******************************************************************/
+
+/*******************************************************************
+ *
+ *  <Function> Z1_Done_Face
+ *
+ *  <Description>
+ *     The face object destructor.
+ *
+ *  <Input>
+ *     face  :: typeless pointer to the face object to destroy
+ *
+ *  <Return>
+ *     Error code.
+ *
+ ******************************************************************/
+
+  LOCAL_FUNC
+  void  Z1_Done_Face( T1_Face  face )
+  {
+    FT_Memory  memory;
+    T1_Font*   type1 = &face->type1;
+
+    if (face)
+    {
+      memory = face->root.memory;
+
+#ifndef Z1_CONFIG_OPTION_NO_MM_SUPPORT
+      /* release multiple masters information */
+      Z1_Done_Blend( face );
+      face->blend = 0;
+#endif
+
+      /* release font info strings */
+      {
+        T1_FontInfo*  info = &type1->font_info;
+
+        FREE( info->version );
+        FREE( info->notice );
+        FREE( info->full_name );
+        FREE( info->family_name );
+        FREE( info->weight );
+      }
+
+      /* release top dictionary */
+      FREE( type1->charstrings_len );
+      FREE( type1->charstrings );
+      FREE( type1->glyph_names );
+
+      FREE( type1->subrs );
+      FREE( type1->subrs_len );
+
+      FREE( type1->subrs_block );
+      FREE( type1->charstrings_block );
+      FREE( type1->glyph_names_block );
+
+      FREE( type1->encoding.char_index );
+      FREE( type1->font_name );
+
+#ifndef Z1_CONFIG_OPTION_NO_AFM
+      /* release afm data if present */
+      if ( face->afm_data)
+        Z1_Done_AFM( memory, (Z1_AFM*)face->afm_data );
+#endif
+
+      /* release unicode map, if any */
+      FREE( face->unicode_map.maps );
+      face->unicode_map.num_maps = 0;
+
+      face->root.family_name = 0;
+      face->root.style_name  = 0;
+    }
+  }
+
+/*******************************************************************
+ *
+ *  <Function>  Z1_Init_Face
+ *
+ *  <Description>
+ *     The face object constructor.
+ *
+ *  <Input>
+ *     face  ::  face record to build
+ *     Input ::  input stream where to load font data
+ *
+ *  <Return>
+ *     Error code.
+ *
+ ******************************************************************/
+
+  LOCAL_FUNC
+  FT_Error  Z1_Init_Face( FT_Stream      stream,
+                          T1_Face        face,
+                          FT_Int         face_index,
+                          FT_Int         num_params,
+                          FT_Parameter*  params )
+  {
+    FT_Error      error;
+    PSNames_Interface*  psnames;
+
+    UNUSED(num_params);
+    UNUSED(params);
+    UNUSED(face_index);
+    UNUSED(stream);
+
+    face->root.num_faces = 1;
+
+    psnames = (PSNames_Interface*)face->psnames;
+    if (!psnames)
+    {
+      psnames = (PSNames_Interface*)
+                 FT_Get_Module_Interface( FT_FACE_LIBRARY(face), "psnames" );
+
+      face->psnames = psnames;
+    }
+
+    /* open the tokenizer, this will also check the font format */
+    error = Z1_Open_Face( face );
+    if (error) goto Exit;
+
+    /* if we just wanted to check the format, leave successfully now */
+    if (face_index < 0)
+      goto Exit;
+
+    /* check the face index */
+    if ( face_index != 0 )
+    {
+      FT_ERROR(( "T1.Init_Face : invalid face index\n" ));
+      error = T1_Err_Invalid_Argument;
+      goto Exit;
+    }
+
+    /* Now, load the font program into the face object */
+    {
+      /* Init the face object fields */
+      /* Now set up root face fields */
+      {
+        FT_Face  root = (FT_Face)&face->root;
+
+        root->num_glyphs   = face->type1.num_glyphs;
+        root->num_charmaps = 1;
+
+        root->face_index = face_index;
+        root->face_flags = FT_FACE_FLAG_SCALABLE;
+
+        root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
+
+        if ( face->type1.font_info.is_fixed_pitch )
+          root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
+
+        if ( face->blend )
+          root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
+
+        /* XXX : TO DO - add kerning with .afm support */
+
+        /* get style name - be careful, some broken fonts only */
+        /* have a /FontName dictionary entry .. !!             */
+        root->family_name = face->type1.font_info.family_name;
+        if (root->family_name)
+        {
+          char*  full   = face->type1.font_info.full_name;
+          char*  family = root->family_name;
+
+          while ( *family && *full == *family )
+          {
+            family++;
+            full++;
+          }
+
+          root->style_name = ( *full == ' ' ? full+1 : "Regular" );
+        }
+        else
+        {
+          /* do we have a /FontName ?? */
+          if (face->type1.font_name)
+          {
+            root->family_name = face->type1.font_name;
+            root->style_name  = "Regular";
+          }
+        }
+
+        /* no embedded bitmap support */
+        root->num_fixed_sizes = 0;
+        root->available_sizes = 0;
+
+        root->bbox         = face->type1.font_bbox;
+        root->units_per_EM = 1000;
+        root->ascender     =  (FT_Short)face->type1.font_bbox.yMax;
+        root->descender    = -(FT_Short)face->type1.font_bbox.yMin;
+        root->height       = ((root->ascender + root->descender)*12)/10;
+
+        /* now compute the maximum advance width */
+
+        root->max_advance_width = face->type1.private_dict.standard_width[0];
+
+        /* compute max advance width for proportional fonts */
+        if (!face->type1.font_info.is_fixed_pitch)
+        {
+          FT_Int  max_advance;
+
+          error = Z1_Compute_Max_Advance( face, &max_advance );
+
+          /* in case of error, keep the standard width */
+          if (!error)
+            root->max_advance_width = max_advance;
+          else
+            error = 0;   /* clear error */
+        }
+
+        root->max_advance_height = root->height;
+
+        root->underline_position  = face->type1.font_info.underline_position;
+        root->underline_thickness = face->type1.font_info.underline_thickness;
+
+        root->max_points   = 0;
+        root->max_contours = 0;
+      }
+    }
+
+    /* charmap support - synthetize unicode charmap when possible */
+    {
+      FT_Face      root    = &face->root;
+      FT_CharMap   charmap = face->charmaprecs;
+
+      /* synthesize a Unicode charmap if there is support in the "psnames" */
+      /* module..                                                          */
+      if (face->psnames)
+      {
+        PSNames_Interface*  psnames = (PSNames_Interface*)face->psnames;
+        if (psnames->unicode_value)
+        {
+          error = psnames->build_unicodes( root->memory,
+                                           face->type1.num_glyphs,
+                                           (const char**)face->type1.glyph_names,
+                                           &face->unicode_map );
+          if (!error)
+          {
+            root->charmap        = charmap;
+            charmap->face        = (FT_Face)face;
+            charmap->encoding    = ft_encoding_unicode;
+            charmap->platform_id = 3;
+            charmap->encoding_id = 1;
+            charmap++;
+          }
+
+          /* simply clear the error in case of failure (which really) */
+          /* means that out of memory or no unicode glyph names       */
+          error = 0;
+        }
+      }
+
+      /* now, support either the standard, expert, or custom encodings */
+      charmap->face        = (FT_Face)face;
+      charmap->platform_id = 7;  /* a new platform id for Adobe fonts ?? */
+
+      switch (face->type1.encoding_type)
+      {
+        case t1_encoding_standard:
+          charmap->encoding    = ft_encoding_adobe_standard;
+          charmap->encoding_id = 0;
+          break;
+
+        case t1_encoding_expert:
+          charmap->encoding    = ft_encoding_adobe_expert;
+          charmap->encoding_id = 1;
+          break;
+
+        default:
+          charmap->encoding    = ft_encoding_adobe_custom;
+          charmap->encoding_id = 2;
+          break;
+      }
+
+      root->charmaps = face->charmaps;
+      root->num_charmaps = charmap - face->charmaprecs + 1;
+      face->charmaps[0] = &face->charmaprecs[0];
+      face->charmaps[1] = &face->charmaprecs[1];
+    }
+  Exit:
+    return error;
+  }
+
+
+/*******************************************************************
+ *
+ *  <Function>  Z1_Init_Driver
+ *
+ *  <Description>
+ *     Initialise a given Type 1 driver object
+ *
+ *  <Input>
+ *     driver ::  handle to target driver object
+ *
+ *  <Return>
+ *     Error code.
+ *
+ ******************************************************************/
+
+  LOCAL_FUNC
+  FT_Error  Z1_Init_Driver( Z1_Driver  driver )
+  {
+    UNUSED(driver);
+    return T1_Err_Ok;
+  }
+
+
+
+/*******************************************************************
+ *
+ *  <Function> Z1_Done_Driver
+ *
+ *  <Description>
+ *     finalise a given Type 1 driver
+ *
+ *  <Input>
+ *     driver  :: handle to target Type 1 driver
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  void  Z1_Done_Driver( Z1_Driver  driver )
+  {
+    UNUSED(driver);
+  }
+
+
+/* END */
--- /dev/null
+++ b/src/type1z/z1objs.h
@@ -1,0 +1,215 @@
+/*******************************************************************
+ *
+ *  t1objs.h                                                    1.0
+ *
+ *    Type1 objects definition.
+ *
+ *  Copyright 1996-1999 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef T1OBJS_H
+#define T1OBJS_H
+
+#include <freetype/internal/ftobjs.h>
+#include <freetype/config/ftconfig.h>
+#include <freetype/internal/t1errors.h>
+#include <freetype/internal/t1types.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+  /* The following structures must be defined by the hinter */
+  typedef struct Z1_Size_Hints_   Z1_Size_Hints;
+  typedef struct Z1_Glyph_Hints_  Z1_Glyph_Hints;
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Type> Z1_Driver                                                    */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    A handle to a Type 1 driver object.                              */
+  /*                                                                     */
+  typedef struct Z1_DriverRec_   *Z1_Driver;
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Type> Z1_Size                                                      */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    A handle to a Type 1 size object.                                */
+  /*                                                                     */
+  typedef struct Z1_SizeRec_*  Z1_Size;
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Type> Z1_GlyphSlot                                                 */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    A handle to a Type 1 glyph slot object.                          */
+  /*                                                                     */
+  typedef struct Z1_GlyphSlotRec_*  Z1_GlyphSlot;
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Type> Z1_CharMap                                                   */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    A handle to a Type 1 character mapping object.                   */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    The Type 1 format doesn't use a charmap but an encoding table.   */
+  /*    The driver is responsible for making up charmap objects          */
+  /*    corresponding to these tables..                                  */
+  /*                                                                     */
+  typedef struct Z1_CharMapRec_*   Z1_CharMap;
+
+
+
+ /**************************************************************************/
+ /*                                                                        */
+ /*    NOW BEGINS THE TYPE1 SPECIFIC STUFF ..............................  */
+ /*                                                                        */
+ /**************************************************************************/
+
+
+  /***************************************************/
+  /*                                                 */
+  /*  Z1_Size :                                      */
+  /*                                                 */
+  /*    Type 1 size record..                         */
+  /*                                                 */
+
+  typedef struct Z1_SizeRec_
+  {
+    FT_SizeRec      root;
+    FT_Bool         valid;
+    Z1_Size_Hints*  hints;  /* defined in the hinter. This allows */
+                            /* us to experiment with different    */
+                            /* hinting schemes without having to  */
+                            /* change 't1objs' each time..        */
+  } Z1_SizeRec;
+
+
+
+  /***************************************************/
+  /*                                                 */
+  /*  Z1_GlyphSlot :                                 */
+  /*                                                 */
+  /*    TrueDoc glyph record..                       */
+  /*                                                 */
+
+  typedef struct Z1_GlyphSlotRec_
+  {
+    FT_GlyphSlotRec  root;
+
+    FT_Bool          hint;
+    FT_Bool          scaled;
+
+    FT_Int           max_points;
+    FT_Int           max_contours;
+
+    FT_Fixed         x_scale;
+    FT_Fixed         y_scale;
+
+    Z1_Glyph_Hints*  hints;  /* defined in the hinter */
+
+  } Z1_GlyphSlotRec;
+
+
+/*******************************************************************
+ *
+ *  <Function>  Z1_Init_Face
+ *
+ *  <Description>
+ *     Initialise a given Type 1 face object
+ *
+ *  <Input>
+ *     face_index :: index of font face in resource
+ *     resource   :: source font resource
+ *     face       ::  face record to build
+ *
+ *  <Return>
+ *     Error code.
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  FT_Error  Z1_Init_Face( FT_Stream     stream,
+                          T1_Face       face,
+                          FT_Int        face_index,
+                          FT_Int        num_params,
+                          FT_Parameter* params );
+
+
+
+/*******************************************************************
+ *
+ *  <Function> Z1_Done_Face
+ *
+ *  <Description>
+ *     Finalise a given face object
+ *
+ *  <Input>
+ *     face  :: handle  to the face object to destroy
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  void  Z1_Done_Face( T1_Face  face );
+
+
+/*******************************************************************
+ *
+ *  <Function>  Z1_Init_Driver
+ *
+ *  <Description>
+ *     Initialise a given Type 1 driver object
+ *
+ *  <Input>
+ *     driver ::  handle to target driver object
+ *
+ *  <Return>
+ *     Error code.
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  FT_Error  Z1_Init_Driver( Z1_Driver  driver );
+
+
+
+/*******************************************************************
+ *
+ *  <Function> Z1_Done_Driver
+ *
+ *  <Description>
+ *     finalise a given Type 1 driver
+ *
+ *  <Input>
+ *     driver  :: handle to target Type 1 driver
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  void  Z1_Done_Driver( Z1_Driver  driver );
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* T1OBJS_H */
+
+
+/* END */
--- /dev/null
+++ b/src/type1z/z1parse.c
@@ -1,0 +1,1269 @@
+/*******************************************************************
+ *
+ *  t1parse.c                                                   2.0
+ *
+ *    Type1 parser.
+ *
+ *  Copyright 1996-1998 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ *  The Type 1 parser is in charge of the following:
+ *
+ *   - provide an implementation of a growing sequence of
+ *     objects called a Z1_Table (used to build various tables
+ *     needed by the loader).
+ *
+ *   - opening .pfb and .pfa files to extract their top-level
+ *     and private dictionaries
+ *
+ *   - read numbers, arrays & strings from any dictionary
+ *
+ *  See "t1load.c" to see how data is loaded from the font file
+ *
+ ******************************************************************/
+
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftcalc.h>
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/t1errors.h>
+#include <z1parse.h>
+
+#undef FT_COMPONENT
+#define FT_COMPONENT  trace_t1load
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/*****                                                               *****/
+/*****           IMPLEMENTATION OF Z1_TABLE OBJECT                   *****/
+/*****                                                               *****/
+/*****                                                               *****/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> Z1_New_Table                                               */
+/*                                                                       */
+/* <Description>                                                         */
+/*    Initialise a Z1_Table.                                             */
+/*                                                                       */
+/* <Input>                                                               */
+/*    table  :: address of target table                                  */
+/*    count  :: table size = maximum number of elements                  */
+/*    memory :: memory object to use for all subsequent reallocations    */
+/*                                                                       */
+/* <Return>                                                              */
+/*    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;
+  }
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> Z1_Add_Table                                               */
+/*                                                                       */
+/* <Description>                                                         */
+/*    Adds an object to a Z1_Table, possibly growing its memory block    */
+/*                                                                       */
+/* <Input>                                                               */
+/*    table  :: target table                                             */
+/*    index  :: index of object in table                                 */
+/*    object :: address of object to copy in memory                      */
+/*    length :: length in bytes of source object                         */
+/*                                                                       */
+/* <Return>                                                              */
+/*    Error code. 0 means success. An error is returned when a           */
+/*    realloc failed..                                                   */
+/*                                                                       */
+
+
+      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;
+
+        /* realloc the base block */
+        if ( REALLOC( table->block, table->capacity, new_size ) )
+          return error;
+
+        table->capacity = new_size;
+
+        /* shift all offsets when needed */
+        if (old_base)
+          shift_elements( table, old_base );
+
+        return T1_Err_Ok;
+      }
+
+
+
+  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(( "T1.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;
+  }
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> Z1_Done_Table                                              */
+/*                                                                       */
+/* <Description>                                                         */
+/*    Finalise a Z1_Table. (realloc it to its current cursor).           */
+/*                                                                       */
+/* <Input>                                                               */
+/*    table :: 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.  */
+/*                                                                       */
+#if 0
+  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
+
+  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                             *****/
+/*****                                                               *****/
+/*****                                                               *****/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+  #define IS_Z1_WHITESPACE(c)  ( (c) == ' '  || (c) == '\t' )
+  #define IS_Z1_LINESPACE(c)   ( (c) == '\r' || (c) == '\n' )
+
+  #define IS_Z1_SPACE(c)  ( IS_Z1_WHITESPACE(c) || IS_Z1_LINESPACE(c) )
+
+  LOCAL_FUNC
+  void     Z1_Skip_Spaces( Z1_Parser*  parser )
+  {
+    FT_Byte* cur   = parser->cursor;
+    FT_Byte* limit = parser->limit;
+
+    while (cur < limit)
+    {
+      FT_Byte  c = *cur;
+      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  = t1_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 = t1_token_string;
+          ender = ')';
+          goto Lookup_Ender;
+
+        /************* check for programs/array ****************/
+        case '{':
+          token->type = t1_token_array;
+          ender = '}';
+          goto Lookup_Ender;
+
+        /************* check for table/array ******************/
+        case '[':
+          token->type = t1_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  = t1_token_any;
+          while (cur < limit && !IS_Z1_SPACE(*cur))
+            cur++;
+
+          token->limit = cur;
+      }
+
+      if (!token->limit)
+      {
+        token->start = 0;
+        token->type  = t1_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 == t1_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 )
+  {
+    FT_Long  result = 0;
+    FT_Byte* cur    = *cursor;
+    FT_Byte  c, d;
+
+    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, read the integer part */
+    result  = t1_toint( &cur, limit ) << 16;
+    num     = 0;
+    divider = 1;
+
+    if (result < 0)
+    {
+      sign   = 1;
+      result = -result;
+    }
+    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
+
+  static
+  int  t1_tobool( FT_Byte* *cursor, FT_Byte* limit )
+  {
+    FT_Byte*  cur    = *cursor;
+    FT_Bool   result = 0;
+
+    /* return 1 if we find a "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;
+  }
+
+
+
+ /* Loads 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 == t1_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 t1_field_bool:
+          {
+            val = t1_tobool( &cur, limit );
+            goto Store_Integer;
+          }
+
+        case t1_field_fixed:
+          {
+            val = t1_tofixed( &cur, limit, 3 );
+            goto Store_Integer;
+          }
+
+        case t1_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;
+              default: *(FT_Long*)q   = val;
+            }
+          }
+          break;
+
+        case t1_field_string:
+          {
+            FT_Memory  memory = parser->memory;
+            FT_UInt    len    = limit-cur;
+            
+            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    = 0;
+
+  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
+
+
+  static
+  FT_Error  read_pfb_tag( FT_Stream  stream, FT_UShort *tag, FT_Long*  size )
+  {
+    FT_Error  error;
+
+    if (READ_UShort(*tag)) goto Exit;
+    if (*tag == 0x8001 || *tag == 0x8002)
+    {
+      FT_Long  asize;
+
+      if (READ_ULong(asize)) goto Exit;
+
+      /* swap between big and little endianness */
+      *size  = ((asize & 0xFF000000) >> 24) |
+               ((asize & 0x00FF0000) >> 8 ) |
+               ((asize & 0x0000FF00) << 8 ) |
+               ((asize & 0x000000FF) << 24);
+    }
+
+  Exit:
+    return error;
+  }
+
+
+
+  LOCAL_FUNC
+  FT_Error  Z1_New_Parser( Z1_Parser*  parser,
+                           FT_Stream   stream,
+                           FT_Memory   memory )
+  {
+    FT_Error  error;
+    FT_UShort tag;
+    FT_Long   size;
+
+    parser->stream       = stream;
+    parser->memory       = memory;
+    parser->base_len     = 0;
+    parser->base_dict    = 0;
+    parser->private_len  = 0;
+    parser->private_dict = 0;
+    parser->in_pfb       = 0;
+    parser->in_memory    = 0;
+    parser->single_block = 0;
+
+    parser->cursor       = 0;
+    parser->limit        = 0;
+
+    /******************************************************************/
+    /*                                                                */
+    /* Here's a short summary of what is going on :                   */
+    /*                                                                */
+    /*   When creating a new Type 1 parser, we try to locate and      */
+    /*   load the base dictionary when this is possible (i.e. for     */
+    /*   .pfb files). Otherwise, we load the whole font in memory.    */
+    /*                                                                */
+    /*   When "loading" the base dictionary, we only setup pointers   */
+    /*   in the case of a memory-based stream. Otherwise, we allocate */
+    /*   and load the base dict in it.                                */
+    /*                                                                */
+    /*   parser->in_pfb is set when we are in a binary (".pfb") font  */
+    /*   parser->in_memory is set when we have a memory stream.       */
+    /*                                                                */
+
+    /* try to compute the size of the base dictionary    */
+    /* look for a Postscript binary file tag, i.e 0x8001 */
+    if ( FILE_Seek(0L) )
+      goto Exit;
+
+    error = read_pfb_tag( stream, &tag, &size );
+    if (error) goto Exit;
+
+    if (tag != 0x8001)
+    {
+      /* assume that this is a PFA file for now, an error will */
+      /* be produced later when more things are checked        */
+      (void)FILE_Seek(0L);
+      size = stream->size;
+    }
+    else
+      parser->in_pfb = 1;
+
+    /* now, try to load the "size" bytes of the "base" dictionary we */
+    /* found previously                                              */
+
+    /* if it's a memory-based resource, set up pointers */
+    if ( !stream->read )
+    {
+      parser->base_dict = (FT_Byte*)stream->base + stream->pos;
+      parser->base_len  = size;
+      parser->in_memory = 1;
+
+      /* check that the "size" field is valid */
+      if ( FILE_Skip(size) ) goto Exit;
+    }
+    else
+    {
+      /* read segment in memory */
+      if ( ALLOC( parser->base_dict, size )     ||
+           FILE_Read( parser->base_dict, size ) )
+        goto Exit;
+      parser->base_len = size;
+    }
+
+    /* Now check font format, we must see a '%!PS-AdobeFont-1' */
+    /* or a '%!FontType'                                       */
+    {
+      if ( size <= 16 ||
+           ( strncmp( (const char*)parser->base_dict, "%!PS-AdobeFont-1", 16 ) &&
+             strncmp( (const char*)parser->base_dict, "%!FontType", 10 )       ) )
+      {
+        FT_TRACE2(( "Not a Type1 font\n" ));
+        error = FT_Err_Unknown_File_Format;
+      }
+      else
+      {
+        parser->cursor = parser->base_dict;
+        parser->limit  = parser->cursor + parser->base_len;
+      }
+    }
+
+  Exit:
+    if (error && !parser->in_memory)
+      FREE( parser->base_dict );
+
+    return error;
+  }
+
+
+  LOCAL_FUNC
+  void  Z1_Done_Parser( Z1_Parser*  parser )
+  {
+    FT_Memory   memory = parser->memory;
+
+    /* always free the private dictionary */
+    FREE( parser->private_dict );
+
+    /* free the base dictionary only when we have a disk stream */
+    if (!parser->in_memory)
+      FREE( parser->base_dict );
+  }
+
+
+ /* return the value of an hexadecimal digit */
+ static
+ int  hexa_value( char c )
+ {
+   unsigned int  d;
+
+   d = (unsigned int)(c-'0');
+   if ( d <= 9 ) return (int)d;
+
+   d = (unsigned int)(c-'a');
+   if ( d <= 5 ) return (int)(d+10);
+
+   d = (unsigned int)(c-'A');
+   if ( d <= 5 ) return (int)(d+10);
+
+   return -1;
+ }
+
+
+  LOCAL_FUNC
+  void  Z1_Decrypt( FT_Byte*   buffer,
+                    FT_Int     length,
+                    FT_UShort  seed )
+  {
+    while ( length > 0 )
+    {
+      FT_Byte  plain;
+
+      plain     = (*buffer ^ (seed >> 8));
+      seed      = (*buffer+seed)*52845+22719;
+      *buffer++ = plain;
+      length--;
+    }
+  }
+
+
+  LOCAL_FUNC
+  FT_Error  Z1_Get_Private_Dict( Z1_Parser*  parser )
+  {
+    FT_Stream  stream = parser->stream;
+    FT_Memory  memory = parser->memory;
+    FT_Error   error  = 0;
+    FT_Long    size;
+
+    if (parser->in_pfb)
+    {
+      /* in the case of the PFB format, the private dictionary can be  */
+      /* made of several segments. We thus first read the number of    */
+      /* segments to compute the total size of the private dictionary  */
+      /* then re-read them into memory..                               */
+      FT_Long    start_pos    = FILE_Pos();
+      FT_UShort  tag;
+      FT_Long    size;
+
+      parser->private_len = 0;
+      for (;;)
+      {
+        error = read_pfb_tag(stream, &tag, &size);
+        if (error) goto Fail;
+
+        if (tag != 0x8002)
+          break;
+
+        parser->private_len += size;
+
+        if ( FILE_Skip(size) )
+          goto Fail;
+      }
+
+      /* Check that we have a private dictionary there */
+      /* and allocate private dictionary buffer        */
+      if ( parser->private_len == 0 )
+      {
+        FT_ERROR(( "T1.Open_Private: invalid private dictionary section\n" ));
+        error = T1_Err_Invalid_File_Format;
+        goto Fail;
+      }
+
+      if ( FILE_Seek( start_pos )                             ||
+           ALLOC( parser->private_dict, parser->private_len ) )
+        goto Fail;
+
+      parser->private_len = 0;
+      for (;;)
+      {
+        error = read_pfb_tag( stream, &tag, &size );
+        if (error || tag != 0x8002) { error = 0; break; }
+
+        if ( FILE_Read( parser->private_dict + parser->private_len, size ) )
+          goto Fail;
+
+        parser->private_len += size;
+      }
+    }
+    else
+    {
+      /* we have already "loaded" the whole PFA font file in memory */
+      /* if this is a memory resource, allocate a new block to hold */
+      /* the private dict. Otherwise, simply overwrite into the     */
+      /* base dict block in the heap..                              */
+
+      /* first of all, look at the "eexec" keyword */
+      FT_Byte*  cur   = parser->base_dict;
+      FT_Byte*  limit = cur + parser->base_len;
+      FT_Byte   c;
+
+      for (;;)
+      {
+        c = cur[0];
+        if (c == 'e' && cur+9 < limit)  /* 9 = 5 letters for 'eexec' + newline + 4 chars */
+        {
+          if ( cur[1] == 'e' && cur[2] == 'x' &&
+               cur[3] == 'e' && cur[4] == 'c' )
+          {
+            cur += 6; /* we skip the newling after the "eexec" */
+
+            /* XXX: Some fonts use DOS-linefeeds, i.e. \r\n, we need to skip */
+            /*      the extra \n when we find it..                           */
+            if (cur[0] == '\n')
+              cur++;
+
+            break;
+          }
+        }
+        cur++;
+        if (cur >= limit)
+        {
+          FT_ERROR(("T1.Open_Private: could not find 'eexec' keyword\n"));
+          error = T1_Err_Invalid_File_Format;
+          goto Exit;
+        }
+      }
+
+      /* now determine wether where to write the _encrypted_ binary private    */
+      /* dictionary. We overwrite the base dictionary for disk-based resources */
+      /* and allocate a new block otherwise                                    */
+
+      size = parser->base_len - (cur-parser->base_dict);
+
+      if ( parser->in_memory )
+      {
+        /* note that we allocate one more byte to put a terminating '0' */
+        if (ALLOC( parser->private_dict, size+1 )) goto Fail;
+        parser->private_len = size;
+      }
+      else
+      {
+        parser->single_block = 1;
+        parser->private_dict = parser->base_dict;
+        parser->private_len  = size;
+        parser->base_dict    = 0;
+        parser->base_len     = 0;
+      }
+
+      /* now determine wether the private dictionary is encoded in binary */
+      /* or hexadecimal ASCII format..                                    */
+      /* and decode it accordingly                                        */
+
+      /* we need to access the next 4 bytes (after the final \r following */
+      /* the 'eexec' keyword..) if they all are hexadecimal digits, then  */
+      /*we have a case of ASCII storage..                                 */
+
+      if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) |
+             hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 )
+      {
+       /* binary encoding - "simply" copy the private dict */
+       MEM_Copy( parser->private_dict, cur, size );
+      }
+      else
+      {
+        /* ASCII hexadecimal encoding.. This blows goats !!.. */
+
+        FT_Byte*  write;
+        FT_Int    count;
+
+        write = parser->private_dict;
+        count = 0;
+
+        for ( ;cur < limit; cur++)
+        {
+          int  hex1;
+
+          /* check for newline */
+          if (cur[0] == '\r' || cur[0] == '\n')
+            continue;
+
+          /* exit if we have a non-hexadecimal digit that isn't a newline */
+          hex1 = hexa_value(cur[0]);
+          if (hex1 < 0 || cur+1 >= limit)
+            break;
+
+          /* otherwise, store byte */
+          *write++ = (hex1 << 4) | hexa_value(cur[1]);
+          count++;
+          cur++;
+        }
+
+        /* put a safeguard */
+        parser->private_len = write - parser->private_dict;
+        *write++ = 0;
+      }
+    }
+
+    /* 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;
+
+  Fail:
+  Exit:
+    return error;
+  }
+
--- /dev/null
+++ b/src/type1z/z1parse.h
@@ -1,0 +1,348 @@
+/*******************************************************************
+ *
+ *  t1parse.h                                                   2.0
+ *
+ *    Type1 parser.
+ *
+ *  Copyright 1996-1998 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ *  The Type 1 parser is in charge of the following:
+ *
+ *   - provide an implementation of a growing sequence of
+ *     objects called a Z1_Table (used to build various tables
+ *     needed by the loader).
+ *
+ *   - opening .pfb and .pfa files to extract their top-level
+ *     and private dictionaries
+ *
+ *   - read numbers, arrays & strings from any dictionary
+ *
+ *  See "t1load.c" to see how data is loaded from the font file
+ *
+ ******************************************************************/
+
+#ifndef T1PARSE_H
+#define T1PARSE_H
+
+#include <freetype/internal/t1types.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /* simple enumeration type used to identify token types */
+  typedef enum Z1_Token_Type_
+  {
+    t1_token_none = 0,
+    t1_token_any,
+    t1_token_string,
+    t1_token_array,
+    
+    /* do not remove */
+    t1_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_
+  {
+    t1_field_none = 0,
+    t1_field_bool,
+    t1_field_integer,
+    t1_field_fixed,
+    t1_field_string,
+    t1_field_integer_array,
+    t1_field_fixed_array,
+    
+    /* do not remove */
+    t1_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_UInt        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_REF(s,f)  (((s*)0)->f)
+
+#define Z1_FIELD_BOOL( _ftype, _fname )               \
+    { t1_field_bool,                                  \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fname),   \
+      sizeof(Z1_FIELD_REF(_ftype,_fname)),            \
+      0, 0, 0 }
+
+#define Z1_FIELD_NUM( _ftype, _fname )                \
+    { t1_field_integer,                               \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fname),   \
+      sizeof(Z1_FIELD_REF(_ftype,_fname)),            \
+      0, 0, 0 }
+
+#define Z1_FIELD_FIXED( _ftype, _fname, _power )      \
+    { t1_field_fixed,                                 \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fname),   \
+      sizeof(Z1_FIELD_REF(_ftype,_fname)),            \
+      0, 0, 0 }
+
+#define Z1_FIELD_STRING( _ftype, _fname )             \
+    { t1_field_string,                                \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fname),   \
+      sizeof(Z1_FIELD_REF(_ftype,_fname)),            \
+      0, 0, 0 }
+
+#define Z1_FIELD_NUM_ARRAY( _ftype, _fname, _fcount, _fmax ) \
+    { t1_field_integer,                                      \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fname),          \
+      sizeof(Z1_FIELD_REF(_ftype,_fname)[0]),                \
+      _fmax,                                                 \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fcount),         \
+      0 }
+
+#define Z1_FIELD_FIXED_ARRAY( _ftype, _fname, _fcount, _fmax ) \
+    { t1_field_fixed,                                          \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fname),            \
+      sizeof(Z1_FIELD_REF(_ftype,_fname)[0]),                  \
+      _fmax,                                                   \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fcount),           \
+      0 }
+
+#define Z1_FIELD_NUM_ARRAY2( _ftype, _fname, _fmax )         \
+    { t1_field_integer,                                      \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fname),          \
+      sizeof(Z1_FIELD_REF(_ftype,_fname)[0]),                \
+      _fmax,                                                 \
+      0, 0 }
+
+#define Z1_FIELD_FIXED_ARRAY2( _ftype, _fname, _fmax )         \
+    { t1_field_fixed,                                          \
+      (FT_UInt)(char*)&Z1_FIELD_REF(_ftype,_fname),            \
+      sizeof(Z1_FIELD_REF(_ftype,_fname)[0]),                  \
+      _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     :: address in memory of the growheap's block. This
+ *                 can change between two object adds, due to the use
+ *                 of 'realloc'.
+ *
+ *    cursor    :: current top of the grow heap within its block
+ *
+ *    capacity  :: current size of the heap block. Increments by 1 Kb
+ *
+ *    init      :: boolean. set when the table has been initialized
+ *                 (the table user should set this field)
+ *
+ *    max_elems :: maximum number of elements in table
+ *    num_elems :: current number of elements in table
+ *
+ *    elements  :: table of element addresses within the block
+ *    lengths   :: table of element sizes within the block
+ *
+ *    memory    :: memory object used for memory operations (alloc/realloc)
+ */
+
+  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>
+ *    A Z1_Parser is an object used to parse a Type 1 fonts very
+ *    quickly.
+ *
+ * <Fields>
+ *    stream        :: current input stream
+ *    memory        :: current memory object
+ *
+ *    base_dict     :: pointer to top-level dictionary
+ *    base_len      :: length in bytes of top dict
+ *
+ *    private_dict  :: pointer to private dictionary
+ *    private_len   :: length in bytes of private dict
+ *
+ *    in_pfb        :: boolean. Indicates that we're in a .pfb file
+ *    in_memory     :: boolean. Indicates a memory-based stream
+ *    single_block  :: boolean. Indicates that the private dict
+ *                     is stored in lieu of the base dict
+ *
+ *    cursor        :: current parser cursor
+ *    limit         :: current parser limit (first byte after current
+ *                     dictionary).
+ *
+ *    error         :: current parsing error
+ */
+  typedef struct Z1_Parser_
+  {
+    FT_Stream  stream;
+    FT_Memory  memory;
+
+    FT_Byte*   base_dict;
+    FT_Int     base_len;
+
+    FT_Byte*   private_dict;
+    FT_Int     private_len;
+
+    FT_Byte    in_pfb;
+    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 );
+
+
+  LOCAL_DEF
+  FT_Error  Z1_Add_Table( Z1_Table*  table,
+                          FT_Int     index,
+                          void*      object,
+                          FT_Int     length );
+
+#if 0
+  LOCAL_DEF
+  void  Z1_Done_Table( Z1_Table*  table );
+#endif
+
+  LOCAL_DEF
+  void  Z1_Release_Table( Z1_Table*  table );
+
+  LOCAL_DEF
+  FT_Long  Z1_ToInt  ( Z1_Parser*  parser );
+
+  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 );
+
+  LOCAL_DEF
+  FT_Error  Z1_Get_Private_Dict( Z1_Parser*  parser );
+
+  LOCAL_DEF
+  void  Z1_Decrypt( FT_Byte*   buffer,
+                    FT_Int     length,
+                    FT_UShort  seed );
+
+  LOCAL_DEF
+  void  Z1_Done_Parser( Z1_Parser*  parser );
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* T1PARSE_H */
+
+
+/* END */
+
--- /dev/null
+++ b/src/type1z/z1tokens.h
@@ -1,0 +1,125 @@
+/*******************************************************************
+ *
+ *  t1tokens.h
+ *
+ *  Type 1 tokens definition
+ *
+ *  Copyright 2000 David Turner, Robert Wilhelm and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT. By continuing to use, modify or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ *  This file only contains macros that are expanded when compiling
+ *  the "t1load.c" source file.
+ *
+ ******************************************************************/
+
+#undef  T1TYPE
+#define T1TYPE  T1_FontInfo
+
+  Z1_FONTINFO_STRING( "version", version )
+  Z1_FONTINFO_STRING( "Notice", notice )
+  Z1_FONTINFO_STRING( "FullName", full_name )
+  Z1_FONTINFO_STRING( "FamilyName", family_name )
+  Z1_FONTINFO_STRING( "Weight", weight )
+
+  Z1_FONTINFO_NUM( "ItalicAngle", italic_angle )
+  Z1_FONTINFO_BOOL( "isFixedPitch", is_fixed_pitch )
+  Z1_FONTINFO_NUM( "UnderlinePosition", underline_position )
+  Z1_FONTINFO_NUM( "UnderlineThickness", underline_thickness )
+
+#undef  T1TYPE
+#define T1TYPE  T1_Private
+
+  Z1_PRIVATE_NUM  ( "UniqueID", unique_id )
+  Z1_PRIVATE_NUM  ( "lenIV", lenIV )
+  Z1_PRIVATE_NUM  ( "LanguageGroup", language_group )
+  Z1_PRIVATE_NUM  ( "password", password )
+  
+  Z1_PRIVATE_FIXED( "BlueScale", blue_scale )
+  Z1_PRIVATE_NUM  ( "BlueShift", blue_shift )
+  Z1_PRIVATE_NUM  ( "BlueFuzz",  blue_fuzz )
+  
+  Z1_PRIVATE_NUM_TABLE( "BlueValues", blue_values, 14, num_blue_values )
+  Z1_PRIVATE_NUM_TABLE( "OtherBlues", other_blues, 10, num_other_blues )
+  Z1_PRIVATE_NUM_TABLE( "FamilyBlues", family_blues, 14, num_family_blues )
+  Z1_PRIVATE_NUM_TABLE( "FamilyOtherBlues", family_other_blues, 10, num_family_other_blues )
+
+  Z1_PRIVATE_NUM_TABLE2( "StdHW", standard_width,  1 )
+  Z1_PRIVATE_NUM_TABLE2( "StdVW", standard_height, 1 )
+  Z1_PRIVATE_NUM_TABLE2( "MinFeature", min_feature, 2 )
+  
+  Z1_PRIVATE_NUM_TABLE ( "StemSnapH", snap_widths, 12, num_snap_widths )
+  Z1_PRIVATE_NUM_TABLE ( "StemSnapV", snap_heights, 12, num_snap_heights )
+
+#undef  T1TYPE
+#define T1TYPE  T1_Font
+
+  Z1_TOPDICT_NUM( "PaintType", paint_type )
+  Z1_TOPDICT_NUM( "FontType", font_type )
+  Z1_TOPDICT_NUM( "StrokeWidth", stroke_width )
+
+#if 0
+ /* define the font info dictionary parsing callbacks */
+#undef  FACE
+#define FACE  (face->type1.font_info)
+
+  PARSE_STRING("version",version)
+  PARSE_STRING("Notice",notice)
+  PARSE_STRING("FullName",full_name)
+  PARSE_STRING("FamilyName",family_name)
+  PARSE_STRING("Weight",weight)
+
+  PARSE_INT("ItalicAngle",italic_angle)
+  PARSE_BOOL("isFixedPitch",is_fixed_pitch)
+  PARSE_NUM("UnderlinePosition",underline_position,FT_Short)
+  PARSE_NUM("UnderlineThickness",underline_thickness,FT_UShort)
+
+ /* define the private dict parsing callbacks */
+
+#undef  FACE
+#define FACE  (face->type1.private_dict)
+
+   PARSE_INT("UniqueID",unique_id)
+   PARSE_INT("lenIV",lenIV)
+
+   PARSE_COORDS( "BlueValues", num_blues,       14, blue_values)
+   PARSE_COORDS( "OtherBlues", num_other_blues, 10, other_blues)
+
+   PARSE_COORDS( "FamilyBlues", num_family_blues,       14, family_blues)
+   PARSE_COORDS( "FamilyOtherBlues", num_family_other_blues, 10, family_other_blues)
+
+   PARSE_FIXED( "BlueScale", blue_scale)
+   PARSE_INT( "BlueShift", blue_shift)
+
+   PARSE_INT( "BlueFuzz", blue_fuzz)
+
+   PARSE_COORDS2( "StdHW", 1, standard_width  )
+   PARSE_COORDS2( "StdVW", 1, standard_height )
+
+   PARSE_COORDS( "StemSnapH", num_snap_widths,  12, stem_snap_widths )
+   PARSE_COORDS( "StemSnapV", num_snap_heights, 12, stem_snap_heights )
+
+   PARSE_INT( "LanguageGroup", language_group )
+   PARSE_INT( "password", password )
+   PARSE_COORDS2( "MinFeature", 2, min_feature )
+
+ /* define the top-level dictionary parsing callbacks */
+
+#undef  FACE
+#define FACE  (face->type1)
+
+
+/* PARSE_STRING( "FontName", font_name ) -- handled by special routine */
+   PARSE_NUM( "PaintType", paint_type, FT_Byte )
+   PARSE_NUM( "FontType", font_type, FT_Byte )
+   PARSE_FIXEDS2( "FontMatrix", 4, font_matrix )
+/*  PARSE_COORDS2( "FontBBox", 4, font_bbox ) -- handled by special func */
+   PARSE_INT( "StrokeWidth", stroke_width )
+
+#undef FACE
+#endif
+