shithub: freetype+ttf2subf

Download patch

ref: 24d7024c4468b526996ec9f4ad83c08bb3347566
parent: 710354b8e9f7c7c44bdf1cb087625f7a16e3922a
author: David Turner <[email protected]>
date: Wed Aug 16 21:09:06 EDT 2000

added draft "psaux" code

the t1 driver now reads the complete font matrix

and applies it (some fonts do not work properly without
hinting though...)

git/fs: mount .git/fs: mount/attach disallowed
--- /dev/null
+++ b/include/freetype/internal/psaux.h
@@ -1,0 +1,459 @@
+#ifndef PSAUX_H
+#define PSAUX_H
+
+#include <freetype/internal/ftobjs.h>
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                             T1_TABLE                          *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <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     :: The address in memory of the growheap's block.  This  */
+  /*                 can change between two object adds, due to            */
+  /*                 reallocation.                                         */
+  /*                                                                       */
+  /*    cursor    :: The current top of the grow heap within its block.    */
+  /*                                                                       */
+  /*    capacity  :: The current size of the heap block.  Increments by    */
+  /*                 1kByte chunks.                                        */
+  /*                                                                       */
+  /*    max_elems :: The maximum number of elements in table.              */
+  /*                                                                       */
+  /*    num_elems :: The current number of elements in table.              */
+  /*                                                                       */
+  /*    elements  :: A table of element addresses within the block.        */
+  /*                                                                       */
+  /*    lengths   :: A table of element sizes within the block.            */
+  /*                                                                       */
+  /*    memory    :: The 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_Table_Funcs                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A set of function pointers used to manage T1_Table objects..       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    table_init    :: used to initialise a a table                      */
+  /*    table_done    :: finalize/destroy a given table                    */
+  /*    table_add     :: add one new object to a table                     */
+  /*    table_release :: release table data, then finalize it              */
+  /*                                                                       */
+  typedef  struct T1_Table_Funcs_
+  {
+    FT_Error   (*init)   ( T1_Table*   table,
+                           FT_Int     count,
+                           FT_Memory  memory );
+  
+    void       (*done)   ( T1_Table*  table );                              
+  
+    FT_Error   (*add)    ( T1_Table*   table,
+                           FT_Int      index,
+                           void*       object,
+                           FT_Int      length );
+
+    void       (*release)( T1_Table*  table );                              
+  
+  } T1_Table_Funcs;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                       T1 FIELDS & TOKENS                      *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /* 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_
+  {
+    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;
+
+
+  /* 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_
+  {
+    T1_Field_Type  type;          /* type of field                        */
+    FT_UInt        offset;        /* offset of field in object            */
+    FT_Byte        size;          /* size of field in bytes               */
+    FT_UInt        array_max;     /* maximum number of elements for array */
+    FT_UInt        count_offset;  /* offset of element count for arrays   */
+    FT_Int         flag_bit;      /* bit number for field flag            */
+
+  } T1_Field;
+
+
+#define T1_FIELD_BOOL( _fname )        \
+          {                            \
+            t1_field_bool,             \
+            FT_FIELD_OFFSET( _fname ), \
+            FT_FIELD_SIZE( _fname ),   \
+            0, 0, 0                    \
+          }
+
+#define T1_FIELD_NUM( _fname )         \
+          {                            \
+            t1_field_integer,          \
+            FT_FIELD_OFFSET( _fname ), \
+            FT_FIELD_SIZE( _fname ),   \
+            0, 0, 0                    \
+          }
+
+#define T1_FIELD_FIXED( _fname, _power ) \
+          {                              \
+            t1_field_fixed,              \
+            FT_FIELD_OFFSET( _fname ),   \
+            FT_FIELD_SIZE( _fname ),     \
+            0, 0, 0                      \
+          }
+
+#define T1_FIELD_STRING( _fname )      \
+          {                            \
+            t1_field_string,           \
+            FT_FIELD_OFFSET( _fname ), \
+            FT_FIELD_SIZE( _fname ),   \
+            0, 0, 0                    \
+          }
+
+#define T1_FIELD_NUM_ARRAY( _fname, _fcount, _fmax )  \
+          {                                           \
+            t1_field_integer,                         \
+            FT_FIELD_OFFSET( _fname ),                \
+            FT_FIELD_SIZE_DELTA( _fname ),            \
+            _fmax,                                    \
+            FT_FIELD_OFFSET( _fcount ),               \
+            0                                         \
+          }
+
+#define T1_FIELD_FIXED_ARRAY( _fname, _fcount, _fmax ) \
+          {                                            \
+            t1_field_fixed,                            \
+            FT_FIELD_OFFSET( _fname ),                 \
+            FT_FIELD_SIZE_DELTA( _fname ),             \
+            _fmax,                                     \
+            FT_FIELD_OFFSET( _fcount ),                \
+            0                                          \
+          }
+
+#define T1_FIELD_NUM_ARRAY2( _fname, _fmax ) \
+          {                                  \
+            t1_field_integer,                \
+            FT_FIELD_OFFSET( _fname ),       \
+            FT_FIELD_SIZE_DELTA( _fname ),   \
+            _fmax,                           \
+            0, 0                             \
+          }
+
+#define T1_FIELD_FIXED_ARRAY2( _fname, _fmax ) \
+          {                                    \
+            t1_field_fixed,                    \
+            FT_FIELD_OFFSTE( _fname ),         \
+            FT_FIELD_SIZE_DELTA( _fname ),     \
+            _fmax,                             \
+            0, 0                               \
+          }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                            T1 PARSER                          *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    T1_Parser                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A T1_Parser is an object used to parse a Type 1 font very          */
+  /*    quickly.                                                           */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    cursor       :: current position in text.                          */
+  /*    base         :: start of processed text.                           */
+  /*    limit        :: end of processed text.                             */
+  /*    error        :: last error returned.                               */
+  /*                                                                       */
+
+  typedef struct T1_Parser_
+  {
+    FT_Byte*   cursor;
+    FT_Byte*   base;
+    FT_Byte*   limit;
+    FT_Error   error;
+    FT_Memory  memory;
+  
+  } T1_Parser;
+
+
+  typedef struct T1_Parser_Funcs_
+  {
+    void      (*init)          ( T1_Parser*  parser,
+                                 FT_Byte*    base,
+                                 FT_Byte*    limit,
+                                 FT_Memory   memory );
+                       
+    void      (*done)          ( T1_Parser*  parser );
+
+    void      (*skip_spaces)   ( T1_Parser*  parser );
+    void      (*skip_alpha)    ( T1_Parser*  parser );
+  
+    FT_Long   (*to_int)        ( T1_Parser*  parser );
+    FT_Fixed  (*to_fixed)      ( T1_Parser*  parser,
+                                 FT_Int      power_ten );
+    FT_Int    (*to_coord_array)( T1_Parser*  parser,
+                                 FT_Int      max_coords,
+                                 FT_Short*   coords );
+    FT_Int    (*to_fixed_array)( T1_Parser*  parser,
+                                 FT_Int      max_values,
+                                 FT_Fixed*   values,
+                                 FT_Int      power_ten );    
+  
+    void      (*to_token)      ( T1_Parser*  parser,
+                                 T1_Token   *token );
+    void      (*to_token_array)( T1_Parser*  parser,
+                                 T1_Token*   tokens,
+                                 FT_UInt     max_tokens,
+                                 FT_Int     *pnum_tokens );
+                                 
+    FT_Error  (*load_field)    ( T1_Parser*       parser,
+                                 const T1_Field*  field,
+                                 void**           objects,
+                                 FT_UInt          max_objects,
+                                 FT_ULong*        pflags );
+    
+    FT_Error  (*load_field_table)( T1_Parser*       parser,
+                                   const T1_Field*  field,
+                                   void**           objects,
+                                   FT_UInt          max_objects,
+                                   FT_ULong*        pflags );
+
+  } T1_Parser_Funcs;
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                            T1 BUILDER                         *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Structure>                                                           */
+  /*    T1_Builder                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*     A structure used during glyph loading to store its outline.       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    memory       :: The current memory object.                         */
+  /*                                                                       */
+  /*    face         :: The current face object.                           */
+  /*                                                                       */
+  /*    glyph        :: The current glyph slot.                            */
+  /*                                                                       */
+  /*    current      :: The current glyph outline.                         */
+  /*                                                                       */
+  /*    base         :: The base glyph outline.                            */
+  /*                                                                       */
+  /*    max_points   :: maximum points in builder outline                  */
+  /*                                                                       */
+  /*    max_contours :: Maximal number of contours in builder outline.     */
+  /*                                                                       */
+  /*    last         :: The last point position.                           */
+  /*                                                                       */
+  /*    scale_x      :: The horizontal scale (FUnits to sub-pixels).       */
+  /*                                                                       */
+  /*    scale_y      :: The vertical scale (FUnits to sub-pixels).         */
+  /*                                                                       */
+  /*    pos_x        :: The horizontal translation (if composite glyph).   */
+  /*                                                                       */
+  /*    pos_y        :: The vertical translation (if composite glyph).     */
+  /*                                                                       */
+  /*    left_bearing :: The left side bearing point.                       */
+  /*                                                                       */
+  /*    advance      :: The horizontal advance vector.                     */
+  /*                                                                       */
+  /*    bbox         :: Unused.                                            */
+  /*                                                                       */
+  /*    path_begun   :: A flag which indicates that a new path has begun.  */
+  /*                                                                       */
+  /*    load_points  :: If this flag is not set, no points are loaded.     */
+  /*                                                                       */
+  /*    no_recurse   :: Set but not used.                                  */
+  /*                                                                       */
+  /*    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  T2_Builder_
+  {
+    FT_Memory        memory;
+    FT_Face          face;
+    FT_GlyphSlot     glyph;
+    FT_GlyphLoader*  loader;
+    FT_Outline*      base;
+    FT_Outline*      current;
+
+    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;
+
+
+  typedef  FT_Error  (*T1_Builder_Check_Points_Func)( T1_Builder*  builder,
+                                                      FT_Int       count );
+                                                      
+  typedef  void      (*T1_Builder_Add_Point_Func) ( T1_Builder*  builder,
+                                                    FT_Pos       x,
+                                                    FT_Pos       y,
+                                                    FT_Byte      flag );    
+  
+  typedef  void      (*T1_Builder_Add_Point1_Func)( T1_Builder*  builder,
+                                                    FT_Pos       x,
+                                                    FT_Pos       y );
+                                                    
+  typedef  FT_Error  (*T1_Builder_Add_Contour_Func)( T1_Builder*  builder );                                                    
+
+  typedef  FT_Error  (*T1_Builder_Start_Point_Func)( T1_Builder*  builder,
+                                                     FT_Pos       x,
+                                                     FT_Pos       y );
+
+  typedef  void      (*T1_Builder_Close_Contour_Func)( T1_Builder*  builder );
+
+
+  typedef struct T1_Builder_Funcs_
+  {
+    FT_Error  (*init)( T1_Builder*   builder,
+                       FT_Face       face,
+                       FT_Size       size,
+                       FT_GlyphSlot  slot );
+  
+    void      (*done)( T1_Builder*   builder );
+    
+    T1_Builder_Check_Points_Func   check_points;
+    T1_Builder_Add_Points_Func     add_point;
+    T1_Builder_Add_Point1_Func     add_point1;
+    T1_Builder_Add_Contour_Func    add_contour;
+    T1_Builder_Start_Point_Func    start_point;
+    T1_Builder_Close_Contour_Func  close_contour;
+  
+  } T1_Builder_Funcs;
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                        PSAux Module Interface                 *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+
+  typedef struct PSAux_Interface_
+  {
+    const T1_Table_Funcs*   t1_table_funcs;
+    const T1_Parser_Funcs*  t1_parser_funcs;
+    const T1_Builder_Funcs* t1_builder_funcs;
+
+  } PSAux_Interface;
+
+
+#endif /* PSAUX_H */
--- a/include/freetype/internal/t1types.h
+++ b/include/freetype/internal/t1types.h
@@ -116,6 +116,7 @@
     FT_Byte          paint_type;
     FT_Byte          font_type;
     FT_Matrix        font_matrix;
+    FT_Vector        font_offset;
     FT_BBox          font_bbox;
     FT_Long          font_id;
 
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1020,7 +1020,7 @@
     }
 
     /* now, transform the glyph image when needed */
-    if ( face->transform_flags )
+    if ( face->transform_flags && !(load_flags & FT_LOAD_NO_RECURSE))
     {
       /* get renderer */
       FT_Renderer  renderer = ft_lookup_glyph_renderer( slot );
--- a/src/otlayout/oltypes.h
+++ b/src/otlayout/oltypes.h
@@ -1,8 +1,7 @@
 #ifndef OLTYPES_H
 #define OLTYPES_H
 
-#include <ftobjs.h>
-#include <tttypes.h>
+#include <freetype/internal/ftobjs.h>
 
  /*************************************************************
   *
@@ -48,34 +47,34 @@
   {
     FT_Memory memory;
 
-    TT_Int    num_scripts;
-    TT_Tag*   script_tags;
+    FT_Int    num_scripts;
+    FT_Tag*   script_tags;
 
-    TT_Int    max_languages;
-    TT_Int    num_languages;
-    TT_Tag*   language_tags;
+    FT_Int    max_languages;
+    FT_Int    num_languages;
+    FT_Tag*   language_tags;
 
-    TT_Int    max_features;
-    TT_Tag*   feature_tags;
-    TT_Bool*  features;
+    FT_Int    max_features;
+    FT_Tag*   feature_tags;
+    FT_Bool*  features;
 
-    TT_Int    max_lookups;
-    TT_Bool*  lookups;
+    FT_Int    max_lookups;
+    FT_Bool*  lookups;
 
-    TT_Byte*  scripts_table;
-    TT_Long   scripts_len;
+    FT_Byte*  scripts_table;
+    FT_Long   scripts_len;
 
-    TT_Byte*  features_table;
-    TT_Long*  features_len;
+    FT_Byte*  features_table;
+    FT_Long*  features_len;
 
-    TT_Byte*  lookups_table;
-    TT_Byte*  lookups_len;
+    FT_Byte*  lookups_table;
+    FT_Byte*  lookups_len;
 
-    TT_Byte*  cur_script;   /* current script   */
-    TT_Byte*  cur_language; /* current language */
+    FT_Byte*  cur_script;   /* current script   */
+    FT_Byte*  cur_language; /* current language */
 
-    TT_Byte*  cur_base_values;
-    TT_Byte*  cur_min_max;
+    FT_Byte*  cur_base_values;
+    FT_Byte*  cur_min_max;
 
     OTL_Type  otl_type;
 
@@ -84,11 +83,11 @@
 
   typedef struct OTL_BaseCoord_
   {
-    TT_UShort  format;
-    TT_Short   coordinate;
-    TT_UShort  ref_glyph;
-    TT_UShort  ref_point;
-    TT_Byte*   device;
+    FT_UShort  format;
+    FT_Short   coordinate;
+    FT_UShort  ref_glyph;
+    FT_UShort  ref_point;
+    FT_Byte*   device;
 
   } OTL_BaseCoord;
 
@@ -95,13 +94,13 @@
 
   typedef struct OTL_ValueRecord_
   {
-    TT_Vector  placement;
-    TT_Vector  advance;
+    FT_Vector  placement;
+    FT_Vector  advance;
 
-    TT_Byte*   device_pla_x;
-    TT_Byte*   device_pla_y;
-    TT_Byte*   device_adv_x;
-    TT_Byte*   device_adv_y;
+    FT_Byte*   device_pla_x;
+    FT_Byte*   device_pla_y;
+    FT_Byte*   device_adv_x;
+    FT_Byte*   device_adv_y;
 
   } OTL_ValueRecord;
 
@@ -108,35 +107,20 @@
 
   typedef struct OTL_Anchor_
   {
-    TT_UInt    format;
-    TT_Vector  coord;
-    TT_UInt    anchor_point;
-    TT_Byte*   device_x;
-    TT_Byte*   device_y;
+    FT_UInt    format;
+    FT_Vector  coord;
+    FT_UInt    anchor_point;
+    FT_Byte*   device_x;
+    FT_Byte*   device_y;
 
   } OTL_Anchor;
 
+
   LOCAL_DEF
-  TT_Error  OTL_Table_Init( OTL_Table*  table,
+  FT_Error  OTL_Table_Init( OTL_Table*  table,
                             FT_Memory   memory );
 
   LOCAL_DEF
-  TT_Error  OTL_Table_Set_Scripts( OTL_Table*  table,
-                                   TT_Byte*    bytes,
-                                   TT_Long     len,
-                                   OTL_Type    otl_type );
-
-  LOCAL_DEF
-  TT_Error  OTL_Table_Set_Features( OTL_Table*  table,
-                                    TT_Byte*    bytes,
-                                    TT_Long     len );
-
-  LOCAL_DEF
-  TT_Error  OTL_Table_Set_Lookups( OTL_Table*  table,
-                                   TT_Byte*    bytes,
-                                   TT_Long     len );
-
-  LOCAL_DEF
   void      OTL_Table_Done( OTL_Table*  table );
 
 
@@ -153,7 +137,13 @@
  *      table->num_scripts is the number of scripts
  *
  */
+  LOCAL_DEF
+  FT_Error  OTL_Table_Set_Scripts( OTL_Table*  table,
+                                   FT_Byte*    bytes,
+                                   FT_Long     len,
+                                   OTL_Type    otl_type );
 
+
 /********************************************************
  *
  *  - after calling OTL_Table_Set_Features:
@@ -169,7 +159,19 @@
  *      it is empty (zero-filled) by default.
  *
  */
+  LOCAL_DEF
+  FT_Error  OTL_Table_Set_Features( OTL_Table*  table,
+                                    FT_Byte*    bytes,
+                                    FT_Long     len );
 
+
+
+  LOCAL_DEF
+  FT_Error  OTL_Table_Set_Lookups( OTL_Table*  table,
+                                   FT_Byte*    bytes,
+                                   FT_Long     len );
+
+
 /*******************************************************************
  *
  *  - after calling OTL_Get_Languages_List(script_tag):
@@ -187,7 +189,7 @@
  */
   LOCAL_DEF
   void  OTL_Get_Languages_List( OTL_Table*  table,
-                                TT_ULong    script_tag );
+                                FT_ULong    script_tag );
 
 
 /*******************************************************************
@@ -208,15 +210,15 @@
  */
   LOCAL_DEF
   void OTL_Get_Features_List( OTL_Table*  table,
-                              TT_ULong    language_tag );
+                              FT_ULong    language_tag );
 
   LOCAL_DEF
   void OTL_Get_Baseline_Values( OTL_Table*  table,
-                                TT_ULong    language_tag );
+                                FT_ULong    language_tag );
 
   LOCAL_DEF
   void OTL_Get_Justification( OTL_Table*  table,
-                              TT_ULong    language_tag );
+                              FT_ULong    language_tag );
 
 /*******************************************************************
  *
@@ -259,42 +261,42 @@
 
 
   LOCAL_DEF
-  TT_Long  OTL_Get_Coverage_Index( TT_Byte*  coverage,
-                                   TT_UInt   glyph_id );
+  FT_Long  OTL_Get_Coverage_Index( FT_Byte*  coverage,
+                                   FT_UInt   glyph_id );
 
   LOCAL_DEF
-  TT_UInt  OTL_Get_Glyph_Class( TT_Byte*  class_def,
-                                TT_UInt   glyph_id );
+  FT_UInt  OTL_Get_Glyph_Class( FT_Byte*  class_def,
+                                FT_UInt   glyph_id );
 
   LOCAL_DEF
-  TT_Int  OTL_Get_Device_Adjustment( TT_Byte* device,
-                                     TT_UInt  size );
+  FT_Int  OTL_Get_Device_Adjustment( FT_Byte* device,
+                                     FT_UInt  size );
 
   LOCAL_DEF
-  void    OTL_Get_Base_Coordinate( TT_Byte*        base_coord,
+  void    OTL_Get_Base_Coordinate( FT_Byte*        base_coord,
                                    OTL_BaseCoord*  coord );
 
 
   LOCAL_DEF
-  TT_Int  OTL_ValueRecord_Size( TT_UShort  value_format );
+  FT_Int  OTL_ValueRecord_Size( FT_UShort  value_format );
 
 
   LOCAL_DEF
-  void  OTL_Get_ValueRecord( TT_Byte*          value_record,
-                             TT_UShort         value_format,
-			     TT_Byte*          pos_table,
+  void  OTL_Get_ValueRecord( FT_Byte*          value_record,
+                             FT_UShort         value_format,
+			     FT_Byte*          pos_table,
 			     OTL_ValueRecord*  record );
 
 
   LOCAL_DEF
-  void  OTL_Get_Anchor( TT_Byte*     anchor_table,
+  void  OTL_Get_Anchor( FT_Byte*     anchor_table,
                         OTL_Anchor*  anchor );
 
 
   LOCAL_DEF
-  void  OTL_Get_Mark( TT_Byte*     mark_array,
-                      TT_UInt      index,
-		      TT_UShort*   clazz,
+  void  OTL_Get_Mark( FT_Byte*     mark_array,
+                      FT_UInt      index,
+		      FT_UShort*   clazz,
 		      OTL_Anchor*  anchor );
 
 
@@ -301,10 +303,10 @@
 
 #define OTL_Byte(p)   (p++, p[-1])
 
-#define OTL_UShort(p) (p+=2, ((TT_UShort)p[-2] << 8) | p[-1])
+#define OTL_UShort(p) (p+=2, ((FT_UShort)p[-2] << 8) | p[-1])
 
-#define OTL_ULong(p)  (p+=4, ((TT_ULong)p[-4] << 24) |        \
-                             ((TT_ULong)p[-3] << 16) |        \
-                             ((TT_ULong)p[-2] << 8 ) | p[-1] )
+#define OTL_ULong(p)  (p+=4, ((FT_ULong)p[-4] << 24) |        \
+                             ((FT_ULong)p[-3] << 16) |        \
+                             ((FT_ULong)p[-2] << 8 ) | p[-1] )
 
 #endif /* OLTYPES_H */
--- /dev/null
+++ b/src/psaux/psobjs.c
@@ -1,0 +1,1244 @@
+#include <freetype/internal/psaux.h>
+#include <freetype/fterrors.h>
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                             T1_TABLE                          *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    T1_New_Table                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initialises a T1_Table.                                            */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    table  :: The address of the target table.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    count  :: The table size = the maximum number of elements.         */
+  /*                                                                       */
+  /*    memory :: The memory object to use for all subsequent              */
+  /*              reallocations.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  FT_Error  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;
+  }
+
+
+  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;
+
+
+    /* reallocate the base block */
+    if ( REALLOC( table->block, table->capacity, new_size ) )
+      return error;
+
+    table->capacity = new_size;
+
+    /* shift all offsets if necessary */
+    if ( old_base )
+      shift_elements( table, old_base );
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    T1_Add_Table                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Adds an object to a T1_Table, possibly growing its memory block.   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    table  :: The target table.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    index  :: The index of the object in the table.                    */
+  /*                                                                       */
+  /*    object :: The address of the object to copy in memory.             */
+  /*                                                                       */
+  /*    length :: The length in bytes of the source object.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.  An error is returned if a  */
+  /*    reallocation fails.                                                */
+  /*                                                                       */
+  LOCAL_DEF
+  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 FT_Err_Invalid_Argument;
+    }
+
+    /* 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 FT_Err_Ok;
+  }
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    T1_Done_Table                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finalizes a T1_Table (i.e., reallocate it to its current cursor).  */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    table :: The target table.                                         */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function does NOT release the heap's memory block.  It is up  */
+  /*    to the caller to clean it, or reference it in its own structures.  */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  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 );
+  }
+
+
+
+  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;
+    }
+  }
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                            T1 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_Skip_Alpha( 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*   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*   tokens,
+                         FT_UInt     max_tokens,
+                         FT_Int*     pnum_tokens )
+  {
+    T1_Token  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*  cur        = tokens;
+      T1_Token*  limit      = cur + max_tokens;
+
+
+      parser->cursor = master.start;
+      parser->limit  = master.limit;
+
+      while ( parser->cursor < parser->limit )
+      {
+        T1_Token  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 = '\0', 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, check the sign */
+    if ( *cur == '-' )
+    {
+      sign = 1;
+      cur++;
+    }
+
+    /* then, read the integer part, if any */
+    if ( *cur != '.' )
+      result = t1_toint( &cur, limit ) << 16;
+    else
+      result = 0;
+
+    num     = 0;
+    divider = 1;
+
+    if ( cur >= limit )
+      goto Exit;
+
+    /* read decimal part, if any */
+    if ( *cur == '.' && cur + 1 < limit )
+    {
+      cur++;
+
+      for (;;)
+      {
+        d = (FT_Byte)( *cur - '0' );
+        if ( d >= 10 )
+          break;
+
+        if ( divider < 10000000L )
+        {
+          num      = num * 10 + d;
+          divider *= 10;
+        }
+
+        cur++;
+        if ( cur >= limit )
+          break;
+      }
+    }
+
+    /* read exponent, if any */
+    if ( cur + 1 < limit && ( *cur == 'e' || *cur == 'E' ) )
+    {
+      cur++;
+      power_ten += t1_toint( &cur, limit );
+    }
+
+  Exit:
+    /* raise to power of ten if needed */
+    while ( power_ten > 0 )
+    {
+      result = result * 10;
+      num    = num * 10;
+      power_ten--;
+    }
+
+    while ( power_ten < 0 )
+    {
+      result  = result / 10;
+      divider = divider * 10;
+      power_ten++;
+    }
+
+    if ( num )
+      result += FT_DivFix( num, divider );
+
+    if ( sign )
+      result = -result;
+
+    *cursor = cur;
+    return result;
+  }
+
+
+  static
+  FT_Int  t1_tocoordarray( FT_Byte**  cursor,
+                           FT_Byte*   limit,
+                           FT_Int     max_coords,
+                           FT_Short*  coords )
+  {
+    FT_Byte*  cur   = *cursor;
+    FT_Int    count = 0;
+    FT_Byte   c, ender;
+
+
+    if ( cur >= limit )
+      goto Exit;
+
+    /* check for the beginning of an array. If not, only one number will */
+    /* be read                                                           */
+    c     = *cur;
+    ender = 0;
+
+    if ( c == '[' )
+      ender = ']';
+
+    if ( c == '{' )
+      ender = '}';
+
+    if ( ender )
+      cur++;
+
+    /* now, read the coordinates */
+    for ( ; cur < limit; )
+    {
+      /* skip whitespace in front of data */
+      for (;;)
+      {
+        c = *cur;
+        if ( c != ' ' && c != '\t' )
+          break;
+
+        cur++;
+        if ( cur >= limit )
+          goto Exit;
+      }
+
+      if ( count >= max_coords || c == ender )
+        break;
+
+      coords[count] = (FT_Short)( t1_tofixed( &cur, limit, 0 ) >> 16 );
+      count++;
+
+      if ( !ender )
+        break;
+    }
+
+  Exit:
+    *cursor = cur;
+    return count;
+  }
+
+
+  static
+  FT_Int  t1_tofixedarray( FT_Byte**  cursor,
+                           FT_Byte*   limit,
+                           FT_Int     max_values,
+                           FT_Fixed*  values,
+                           FT_Int     power_ten )
+  {
+    FT_Byte*  cur   = *cursor;
+    FT_Int    count = 0;
+    FT_Byte   c, ender;
+
+
+    if ( cur >= limit ) goto Exit;
+
+    /* check for the beginning of an array. If not, only one number will */
+    /* be read                                                           */
+    c     = *cur;
+    ender = 0;
+
+    if ( c == '[' )
+      ender = ']';
+
+    if ( c == '{' )
+      ender = '}';
+
+    if ( ender )
+      cur++;
+
+    /* now, read the values */
+    for ( ; cur < limit; )
+    {
+      /* skip whitespace in front of data */
+      for (;;)
+      {
+        c = *cur;
+        if ( c != ' ' && c != '\t' )
+          break;
+
+        cur++;
+        if ( cur >= limit )
+          goto Exit;
+      }
+
+      if ( count >= max_values || c == ender )
+        break;
+
+      values[count] = t1_tofixed( &cur, limit, power_ten );
+      count++;
+
+      if ( !ender )
+        break;
+    }
+
+  Exit:
+    *cursor = cur;
+    return count;
+  }
+
+
+#if 0
+
+  static
+  FT_String*  t1_tostring( FT_Byte**  cursor,
+                           FT_Byte*   limit,
+                           FT_Memory  memory )
+  {
+    FT_Byte*    cur = *cursor;
+    FT_Int      len = 0;
+    FT_Int      count;
+    FT_String*  result;
+    FT_Error    error;
+
+
+    /* XXX: some stupid fonts have a `Notice' or `Copyright' string     */
+    /*      that simply doesn't begin with an opening parenthesis, even */
+    /*      though they have a closing one!  E.g. "amuncial.pfb"        */
+    /*                                                                  */
+    /*      We must deal with these ill-fated cases there.  Note that   */
+    /*      these fonts didn't work with the old Type 1 driver as the   */
+    /*      notice/copyright was not recognized as a valid string token */
+    /*      and made the old token parser commit errors.                */
+
+    while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) )
+      cur++;
+    if ( cur + 1 >= limit )
+      return 0;
+
+    if ( *cur == '(' )
+      cur++;  /* skip the opening parenthesis, if there is one */
+
+    *cursor = cur;
+    count   = 0;
+
+    /* then, count its length */
+    for ( ; cur < limit; cur++ )
+    {
+      if ( *cur == '(' )
+        count++;
+
+      else if ( *cur == ')' )
+      {
+        count--;
+        if ( count < 0 )
+          break;
+      }
+    }
+
+    len = cur - *cursor;
+    if ( cur >= limit || ALLOC( result, len + 1 ) )
+      return 0;
+
+    /* now copy the string */
+    MEM_Copy( result, *cursor, len );
+    result[len] = '\0';
+    *cursor = cur;
+    return result;
+  }
+
+#endif /* 0 */
+
+
+  static
+  int  t1_tobool( FT_Byte**  cursor,
+                  FT_Byte*   limit )
+  {
+    FT_Byte*  cur    = *cursor;
+    FT_Bool   result = 0;
+
+
+    /* return 1 if we find `true', 0 otherwise */
+    if ( cur + 3 < limit &&
+         cur[0] == 't' &&
+         cur[1] == 'r' &&
+         cur[2] == 'u' &&
+         cur[3] == 'e' )
+    {
+      result = 1;
+      cur   += 5;
+    }
+    else if ( cur + 4 < limit &&
+              cur[0] == 'f' &&
+              cur[1] == 'a' &&
+              cur[2] == 'l' &&
+              cur[3] == 's' &&
+              cur[4] == 'e' )
+    {
+      result = 0;
+      cur   += 6;
+    }
+
+    *cursor = cur;
+    return result;
+  }
+
+
+  /* Load a simple field (i.e. non-table) into the current list of objects */
+  LOCAL_FUNC
+  FT_Error  T1_Load_Field( T1_Parser*       parser,
+                           const T1_Field*  field,
+                           void**           objects,
+                           FT_UInt          max_objects,
+                           FT_ULong*        pflags )
+  {
+    T1_Token  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;
+
+        case 4:
+          *(FT_UInt32*)q = (FT_UInt32)val;
+          break;
+
+        default:  /* for 64-bit systems */
+          *(FT_Long*)q = val;
+        }
+        break;
+
+      case t1_field_string:
+        {
+          FT_Memory  memory = parser->memory;
+          FT_UInt    len    = limit-cur;
+
+          if ( *(FT_String**)q )
+            /*  with synthetic fonts, it's possible to find a field twice  */
+            break;
+
+          if ( ALLOC( string, len + 1 ) )
+            goto Exit;
+
+          MEM_Copy( string, cur, len );
+          string[len] = 0;
+
+          *(FT_String**)q = string;
+        }
+        break;
+
+      default:
+        /* an error occured */
+        goto Fail;
+      }
+    }
+
+    if ( pflags )
+      *pflags |= 1L << field->flag_bit;
+
+    error = FT_Err_Ok;
+
+  Exit:
+    return error;
+
+  Fail:
+    error = FT_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*  field,
+                                 void**           objects,
+                                 FT_UInt          max_objects,
+                                 FT_ULong*        pflags )
+  {
+    T1_Token   elements[T1_MAX_TABLE_ELEMENTS];
+    T1_Token*  token;
+    FT_Int     num_elements;
+    FT_Error   error = 0;
+    FT_Byte*   old_cursor;
+    FT_Byte*   old_limit;
+    T1_Field   fieldrec = *(T1_Field*)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 = FT_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_Fixed  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 /* 0 */
+
+
+  LOCAL_FUNC
+  void      T1_Init_Parser( T1_Parser*  parser,
+                            FT_Byte*    base,
+                            FT_Byte*    limit,
+                            FT_Memory   memory )
+  {
+    parser->error  = 0;
+    parser->base   = base;
+    parser->limit  = base;
+    parser->cursor = base;
+    parser->memory = memory;
+  }                            
+
+
+  LOCAL_FUNC
+  void      T1_Done_Parser( T1_Parser*  parser )
+  {
+    FT_UNUSED(parser);
+  }
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                            T1 BUILDER                         *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    T1_Init_Builder                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a given glyph builder.                                 */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    builder :: A pointer to the glyph builder to initialize.           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face    :: The current face object.                                */
+  /*                                                                       */
+  /*    size    :: The current size object.                                */
+  /*                                                                       */
+  /*    glyph   :: The current glyph object.                               */
+  /*                                                                       */
+  LOCALFUNC
+  void  T1_Init_Builder( T1_Builder*   builder,
+                         FT_Face       face,
+                         FT_Size       size,
+                         FT_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->base    = &loader->base.outline;
+      builder->current = &loader->current.outline;
+      FT_GlyphLoader_Rewind( loader );
+    }
+
+    if ( size )
+    {
+      builder->scale_x = size->metrics.x_scale;
+      builder->scale_y = size->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>                                                         */
+  /*    Finalizes a given glyph builder.  Its contents can still be used   */
+  /*    after the call, but the function saves important information       */
+  /*    within the corresponding glyph slot.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    builder :: A pointer to the glyph builder to finalize.             */
+  /*                                                                       */
+  LOCALFUNC
+  void  T1_Done_Builder( T1_Builder*  builder )
+  {
+    T1_GlyphSlot  glyph = builder->glyph;
+
+
+    if ( glyph )
+      glyph->root.outline = *builder->base;
+  }
+
+
+  /* check that there is enough room for `count' more points */
+  LOCAL_FUNC
+  FT_Error  T1_Builder_Check_Points( T1_Builder*  builder,
+                                     FT_Int       count )
+  {
+    return FT_GlyphLoader_Check_Points( builder->loader, count, 0 );
+  }
+
+
+  /* add a new point, do not check space */
+  LOCAL_FUNC
+  void  T1_Builder_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 >> 16;
+      point->y = y >> 16;
+      *control = flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic;
+
+      builder->last = *point;
+    }
+    outline->n_points++;
+  }
+
+
+  /* check space for a new on-curve point, then add it */
+  LOCAL_FUNC
+  FT_Error  T1_Builder_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 */
+  LOCAL_FUNC
+  FT_Error  T1_Builder_Add_Contour( T1_Builder*  builder )
+  {
+    FT_Outline*  outline = builder->current;
+    FT_Error     error;
+
+
+    if ( !builder->load_points )
+    {
+      outline->n_contours++;
+      return T1_Err_Ok;
+    }
+
+    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 */
+  LOCAL_FUNC
+  FT_Error  T1_Builder_Start_Point( T1_Builder*  builder,
+                                    FT_Pos       x,
+                                    FT_Pos       y )
+  {
+    FT_Error  error = 0;
+
+
+    /* test whether we are building a new contour */
+    if ( !builder->path_begun )
+    {
+      builder->path_begun = 1;
+      error = add_contour( builder );
+      if ( !error )
+        error = add_point1( builder, x, y );
+    }
+    return error;
+  }
+
+
+  /* close the current contour */
+  LOCAL_FUNC
+  void  T1_Builder_Close_Contour( T1_Builder*  builder )
+  {
+    FT_Outline*  outline = builder->current;
+
+    /* XXXX: We must not include the last point in the path if it */
+    /*       is located on the first point.                       */
+    if ( outline->n_points > 1 )
+    {
+      FT_Int      first = 0;
+      FT_Vector*  p1    = outline->points + first;
+      FT_Vector*  p2    = outline->points + outline->n_points - 1;
+
+      if ( outline->n_contours > 1 )
+      {
+        first = outline->contours[outline->n_contours - 2] + 1;
+        p1    = outline->points + first;
+      }
+
+      if ( p1->x == p2->x && p1->y == p2->y )
+        outline->n_points--;
+    }
+
+    if ( outline->n_contours > 0 )
+      outline->contours[outline->n_contours - 1] = outline->n_points - 1;
+  }
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                            OTHER                              *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+
+
+
+
+  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--;
+    }
+  }
+
+
+
+
--- /dev/null
+++ b/src/psaux/psobjs.h
@@ -1,0 +1,113 @@
+#ifndef PSOBJS_H
+#define PSOBJS_H
+
+#include <freetype/internal/psaux.h>
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                             T1_TABLE                          *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  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 );
+
+  LOCAL_DEF
+  void  T1_Done_Table( T1_Table*  table );
+
+  LOCAL_DEF
+  void  T1_Release_Table( T1_Table*  table );
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                            T1 PARSER                          *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  LOCAL_DEF
+  void  T1_Skip_Spaces( T1_Parser*  parser );
+
+  LOCAL_DEF
+  void  T1_Skip_Alpha( T1_Parser*  parser );
+
+  LOCAL_DEF
+  void  T1_ToToken( T1_Parser*  parser,
+                    T1_Token*   token );
+
+  LOCAL_DEF
+  void  T1_ToTokenArray( T1_Parser*  parser,
+                         T1_Token*   tokens,
+                         FT_UInt     max_tokens,
+                         FT_Int*     pnum_tokens );
+ 
+  LOCAL_DEF
+  FT_Error  T1_Load_Field( T1_Parser*       parser,
+                           const T1_Field*  field,
+                           void**           objects,
+                           FT_UInt          max_objects,
+                           FT_ULong*        pflags );
+ 
+  LOCAL_DEF
+  FT_Error  T1_Load_Field_Table( T1_Parser*       parser,
+                                 const T1_Field*  field,
+                                 void**           objects,
+                                 FT_UInt          max_objects,
+                                 FT_ULong*        pflags );
+ 
+  LOCAL_DEF
+  FT_Long  T1_ToInt  ( T1_Parser*  parser );
+
+
+  LOCAL_DEF
+  FT_Fixed  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 );
+
+
+  LOCAL_DEF
+  void      T1_Init_Parser( T1_Parser*  parser,
+                            FT_Byte*    base,
+                            FT_Byte*    limit,
+                            FT_Memory   memory );
+
+  LOCAL_DEF
+  void      T1_Done_Parser( T1_Parser*  parser )
+
+
+
+  LOCAL_DEF
+  void  T1_Decrypt( FT_Byte*   buffer,
+                    FT_Int     length,
+                    FT_UShort  seed );
+
+
+#endif /* PSOBJS_H */
+
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -436,7 +436,7 @@
     stream = face->root.stream;
     /* the `if' is syntactic sugar for picky compilers */
     if ( FILE_Read_At( offset, buffer, size ) )
-      ;
+      goto Exit;
 
   Exit:
     return error;
--- a/src/type1z/z1gload.c
+++ b/src/type1z/z1gload.c
@@ -1425,6 +1425,14 @@
         if ( size && size->root.metrics.y_ppem < 24 )
           glyph->root.outline.flags |= ft_outline_high_precision;
 
+        /* apply the font matrix */
+        FT_Outline_Transform( &glyph->root.outline,
+                              &face->type1.font_matrix );
+
+        FT_Outline_Translate( &glyph->root.outline,
+                              face->type1.font_offset.x,
+                              face->type1.font_offset.y );
+
 #if 0
         glyph->root.outline.second_pass    = TRUE;
         glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24;
@@ -1457,10 +1465,6 @@
           metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
           metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_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 );
--- a/src/type1z/z1load.c
+++ b/src/type1z/z1load.c
@@ -1069,7 +1069,8 @@
   {
     Z1_Parser*  parser = &loader->parser;
     FT_Matrix*  matrix = &face->type1.font_matrix;
-    FT_Fixed    temp[4];
+    FT_Vector*  offset = &face->type1.font_offset;
+    FT_Fixed    temp[6];
 
 
     if ( matrix->xx || matrix->yx )
@@ -1076,11 +1077,25 @@
       /*  with synthetic fonts, it's possible we get here twice  */
       return;
 
-    (void)Z1_ToFixedArray( parser, 4, temp, 3 );
+    (void)Z1_ToFixedArray( parser, 6, temp, 3 );
+
+    /* we need to scale the values by 1.0/temp[3] */
+    if ( temp[3] != 0x10000 )
+    {
+      temp[0] = FT_DivFix( temp[0], temp[3] );
+      temp[1] = FT_DivFix( temp[1], temp[3] );
+      temp[2] = FT_DivFix( temp[2], temp[3] );
+      temp[4] = FT_DivFix( temp[4], temp[3] );
+      temp[5] = FT_DivFix( temp[5], temp[3] );
+      temp[3] = 0x10000;
+    }
+
     matrix->xx = temp[0];
     matrix->yx = temp[1];
     matrix->xy = temp[2];
     matrix->yy = temp[3];
+    offset->x  = temp[4];
+    offset->y  = temp[5];
   }
 
 
--- a/src/type1z/z1tokens.h
+++ b/src/type1z/z1tokens.h
@@ -64,69 +64,4 @@
   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 routine */
-  PARSE_INT    ( "StrokeWidth", stroke_width )
-
-#undef FACE
-
-#endif /* 0 */
-
-
 /* END */