Initial revision
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 0000000..cc42e48
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,176 @@
+This file summarizes the changes that occured since the last "beta" of FreeType 2.
+Because the list is important, it has been divided into separate sections:
+
+
+-----------------------------------------------------------------------------------------
+High-Level Interface :
+
+  The high-level API has been considerably simplified. Here is how :
+
+    - resource objects have disappeared. this means that face objects can now
+      be created with a single function call (see FT_New_Face and
+      FT_Open_Face)
+    
+    - when calling either FT_New_Face & FT_Open_Face, a size object and a
+      glyph slot object are automatically created for the face, and can be
+      accessed through "face->glyph" and "face->size" if one really needs to.
+      In most cases, there's no need to call FT_New_Size or FT_New_Glyph.
+    
+    - similarly, FT_Load_Glyph now only takes a "face" argument (instead of
+      a glyph slot and a size). Also, it's "result" parameter is gone, as
+      the glyph image type is returned in the field "face->glyph.format"
+    
+    - the list of available charmaps is directly accessible through
+      "face->charmaps", counting "face->num_charmaps" elements. Each
+      charmap has an 'encoding' field which specifies which known encoding
+      it deals with. Valid values are, for example :
+    
+          ft_encoding_unicode      (for ASCII, Latin-1 and Unicode)
+          ft_encoding_apple_roman
+          ft_encoding_sjis
+          ft_encoding_adobe_standard
+    
+      other values may be added in the future. Each charmap still holds its
+      "platform_id" and "encoding_id" values in case the encoding is too
+      exotic for the current library
+
+
+-----------------------------------------------------------------------------------------
+Directory Structure:
+
+  Should seem obvious to most of you:
+
+     freetype/
+         config/        -- configuration sub-makefiles
+            ansi/
+            unix/
+            win32/
+            os2/
+            msdos/
+
+         include/       -- public header files, those to be included directly
+                           by client apps
+
+         src/           -- sources of the library
+           base/        -- the base layer
+           sfnt/        -- the sfnt "driver" (see the drivers section below)
+           truetype/    -- the truetype driver
+           type1/       -- the type1 driver
+           shared/      -- some header files shared between drivers
+
+         demos/         -- demos/tools
+
+         docs/          -- documentation (a bit empty for now)
+
+-----------------------------------------------------------------------------------------
+Glyph Image Formats :
+
+  Drivers are now able to register new glyph image formats within the library.
+  For now, the base layer supports of course bitmaps and vector outlines, but
+  one could imagine something different like colored bitmaps, bi-color
+  vectors or wathever else (Metafonts anyone ??).
+
+  See the file `include/ftimage.h'. Note also that the type FT_Raster_Map is
+  gone, and is now replaced by FT_Bitmap, which should encompass all known
+  bitmap types.
+
+  Each new image format must provide at least one "raster", i.e. a module
+  capable of transforming the glyph image into a bitmap. It is also possible
+  to change the default raster used for a given glyph image format.
+
+  The default outline scan-converter now uses 128 levels of grays by default,
+  which tends to smooth many things. Note that the demo programs have been
+  updated significantly to be able to display these..
+
+
+-----------------------------------------------------------------------------------------
+Build system :
+
+  You still need GNU Make to build the library. The build system has been
+  very seriously re-vamped in order to provide things like :
+
+   - automatic host platform detection (reverting to 'config/ansi'
+     if it is not detected, with pseudo-standard compilation flags)
+
+   - the ability to compile from the Makefiles with very different and
+     exotic compilers. Note that linking the library can be difficult for
+     some platforms.
+
+     For example, the file `config/win32/lcclib.bat' is invoked by the
+     build system to create the ".lib" file with LCC-Win32 because its
+     librarian has too many flaws to be invoked directly from the Makefile.
+
+  Here's how it works :
+
+  - the first time you type `make', the build system runs a series of
+    sub-makefiles in order to detect your host platform. It then dumps
+    what it found, and creates a file called `config.mk' in the current
+    directory. This is a sub-Makefile used to define many important Make
+    variables used to build the library.
+
+  - the second time, the build system detects the `config.mk' then use it
+    to build the library. All object files go into 'obj' by default, as
+    well as the library file, but  this can easily be changed.
+
+  Note that you can run "make setup" to force another host platform detection
+  even if a `config.mk' is present in the current directory. Another solution
+  is simply to delete the file, then re-run make.
+
+  Finally, the default compiler for all platforms is gcc (for now, this will
+  hopefully changed in the future). You can however specify a different
+  compiler by specifying it after the 'setup' target as in :
+
+      gnumake setup lcc         on Win32 to use the LCC compiler
+      gnumake setup visualc     on Win32 to use Visual C++
+
+  See the file `config/<system>/detect.mk' for a list of supported compilers
+  for your platforms.
+
+  It should be relatively easy to write new detection rules files and
+  config.mk..
+
+  Finally, to build the demo programs, go to `demos' and launch GNU Make,
+  it will use the `config.mk' in the top directory to build the test
+  programs..
+
+-----------------------------------------------------------------------------------------
+Portability :
+
+  In the previous beta, a single FT_System object was used to encompass
+  all low-level operations like thread synchronisation, memory management
+  and i/o access. This has been greatly simplified :
+
+    - thread synchronisation has been dropped, for the simple reason that
+      the library is already re-entrant, and that if you really need two
+      threads accessing the same FT_Library, you should really synchronize
+      access to it yourself with a simple mutex.
+
+    - memory management is performed through a very simple object called
+      "FT_Memory", which really is a table containing a table of pointers
+      to functions like malloc, realloc and free as well as some user data
+      (closure).
+
+    - resources have disappeared (they created more problems than they
+      solved), and i/o management have been simplified greatly as a
+      result. Streams are defined through FT_Stream objects, which can
+      be either memory-based or disk-based.
+
+      Note that each face has its own stream, which is closed only when
+      the face object is destroyed. Hence, a function like TT_Flush_Face
+      in 1.x cannot be directly supported. However, if you really need
+      something like this, you can easily tailor your own streams to achieve
+      the same feature at a lower level (and use FT_Open_Face instead of
+      FT_New_Face to create the face).
+
+  See the file "include/ftsystem.h" for more details, as well as the
+  implementations found in "config/unix" and "config/ansi".
+
+
+-----------------------------------------------------------------------------------------
+Drivers Interface :
+  (To be written)
+
+-----------------------------------------------------------------------------------------
+Extensions support :
+  (To be defined)
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5932377
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,90 @@
+#******************************************************************************
+#*
+#*  FreeType build system - top-level Makefile
+#*
+#*  This file is designed for GNU Make, do not use it with another Make tool.
+#*  It works as follows :
+#*
+#*  - when invoked for the first time, this Makefile will include
+#*    the rules found in `freetype/config/detect.mk'. They are in charge
+#*    of detecting the current platform.
+#*
+#*    A summary of the detection will be displayed, and the file `config.mk'
+#*    will be created in the current directory
+#*
+#*
+#*  - when invoked later, this Makefile will include the rules found in
+#*    `config.mk'. This sub-Makefile will define some system-specific
+#*    variables (like compiler, compilation flags, object suffix, etc..),
+#*    then include the rules found in `freetype/config/freetype.mk',
+#*    used to build the library.
+#*
+#*  See the comments in `config/detect.mk' and `config/freetype.mk' for
+#*  more details on host platform detection and library builds..
+#*
+#******************************************************************************
+
+.PHONY: setup
+
+#
+# The variable TOP holds the path to the topmost directory in the FreeType
+# engine source hierarchy. If it is not defined, default it to '.'
+#
+ifndef TOP
+TOP := .
+endif
+
+CONFIG_MK := config.mk
+
+#############################################################################
+#
+# If no configuration sub-makefile is present, or if "setup" is the target
+# to be built, run the auto-detection rules to figure out which configuration
+# rules file to use.. 
+#
+# Note that the configuration file is put in the current directory, which is
+# not necessarily TOP.
+#
+
+# if `config.mk' is not present, set "check_platform" and "first_time"
+#
+ifeq ($(wildcard $(CONFIG_MK)),)
+check_platform := 1
+first_time     := 1
+endif
+
+# if `setup' is one of the targets requested, set "check_platform"
+#
+ifneq ($(findstring setup,$(MAKECMDGOALS)),)
+check_platform := 1
+endif
+
+
+#########################################################################
+#
+# include the automatic host platform detection rules when we need to
+# check the platform.
+#
+#
+ifdef check_platform
+
+all: setup
+
+include $(TOP)/config/detect.mk
+
+# "setup" must be defined by the host platform detection rules
+
+else
+
+########################################################################
+#
+# A configuration sub-Makefile is present, simply run it..
+#
+#
+all: build_freetype
+
+BUILD_FREETYPE := yes
+include $(CONFIG_MK)
+
+endif #test check_platform
+
diff --git a/config/ansi/Makefile b/config/ansi/Makefile
new file mode 100644
index 0000000..07db192
--- /dev/null
+++ b/config/ansi/Makefile
@@ -0,0 +1,178 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for a `normal' ANSI compiler
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE   := rm -f
+SEP      := /
+BUILD    := $(TOP)/config/ansi
+PLATFORM := ansi
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o 
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c
+endif
+
+# Now include the main sub-makefile. It contains all the rules used
+# to build the library with the previous variables defined
+#
+include $(TOP)/config/freetype.mk
+
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	-$(DELETE) $@
+	$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
diff --git a/config/ansi/ftconfig.h b/config/ansi/ftconfig.h
new file mode 100644
index 0000000..43a4c95
--- /dev/null
+++ b/config/ansi/ftconfig.h
@@ -0,0 +1,182 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftconfig.h                                                             */
+/*                                                                         */
+/*    ANSI-specific configuration file (specification only).               */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This header file contains a number of macro definitions that are used */
+  /* by the rest of the engine.  Porters are free to copy this file and    */
+  /* adapt it to suit their own system.                                    */
+  /*                                                                       */
+  /* IMPORTANT NOTE:                                                       */
+  /*                                                                       */
+  /*    Porters, read carefully the comments in `ftsys.h' before trying to */
+  /*    port this file to your system.  It contains many essential         */
+  /*    remarks, and will ease your work greatly.                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/* Include the header file containing all developer build options */
+#include <ftoption.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled to suit a specific system.  The current   */
+  /* ones are defaults used to compile FreeType in an ANSI C environment   */
+  /* (16bit compilers are also supported).  Copy this file to your own     */
+  /* `freetype/arch/<system>'  directory, and edit it to port the engine.  */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* We use <limits.h> values to know the sizes of the types.  */
+#include <limits.h>
+
+/* The number of bytes in an `int' type.  */
+#if   UINT_MAX == 0xFFFFFFFF
+#define SIZEOF_INT  4
+#elif UINT_MAX == 0xFFFF
+#define SIZEOF_INT  2
+#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_INT  8
+#else
+#error "Unsupported number of bytes in `int' type!"
+#endif
+
+/* The number of bytes in a `long' type.  */
+#if   ULONG_MAX == 0xFFFFFFFF
+#define SIZEOF_LONG  4
+#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_LONG  8
+#else
+#error "Unsupported number of bytes in `long' type!"
+#endif
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 0
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 0
+
+
+/* Preferred alignment of data */
+#define FT_ALIGNMENT  8
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                     AUTOMATIC CONFIGURATION MACROS                    */
+  /*                                                                       */
+  /*  These macros are computed from the ones defined above.  Don't touch  */
+  /*  their definition, unless you know precisely what you're doing.  No   */
+  /*  porter should need to mess with them.                                */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* IntN types                                                            */
+  /*                                                                       */
+  /*   Used to guarantee the size of some specific integers.               */
+  /*                                                                       */
+  typedef signed short    FT_Int16;
+  typedef unsigned short  FT_Word16;
+
+#if SIZEOF_INT == 4
+
+  typedef signed int      FT_Int32;
+  typedef unsigned int    FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+  typedef signed long     FT_Int32;
+  typedef unsigned long   FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+  /* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64   long
+
+#else
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI 'long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'.  Note  */
+  /* that this will produce many -ansi warnings during library             */
+  /* compilation.                                                          */
+  /*                                                                       */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64   long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define  LOCAL_DEF   static
+#define  LOCAL_FUNC  static
+#else
+#define  LOCAL_DEF   extern
+#define  LOCAL_FUNC  /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define  BASE_DEF    LOCAL_DEF
+#define  BASE_FUNC   LOCAL_FUNC
+#else
+#define  BASE_DEF    extern
+#define  BASE_FUNC   /* nothing */
+#endif
+
+#ifndef  EXPORT_DEF
+#define  EXPORT_DEF   extern
+#endif
+
+#ifndef  EXPORT_FUNC
+#define  EXPORT_FUNC  /* nothing */
+#endif
+
+#endif /* FTCONFIG_H */
+
+
+/* END */
diff --git a/config/ansi/ftoption.h b/config/ansi/ftoption.h
new file mode 100644
index 0000000..852f65f
--- /dev/null
+++ b/config/ansi/ftoption.h
@@ -0,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled by developers to enable or disable        */
+  /* certain aspects of FreeType.  This file contains macros that apply to */
+  /* all of FreeType.  Driver-specific configurations are placed in each   */
+  /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h').          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Alternate Glyph Image Format support                                  */
+  /*                                                                       */
+  /*   By default, the glyph images returned by the FreeType glyph loader  */
+  /*   can either be a pixmap or a vectorial outline defined through       */
+  /*   bezier control points. When defining the following configuration    */
+  /*   macro, some font drivers will be able to register alternate         */
+  /*   glyph image formats.                                                */
+  /*                                                                       */
+  /*   Unset this macro if you're sure that you'll never use a font driver */
+  /*   with an alternate glyph format, this will reduce the size of the    */
+  /*   base layer code.                                                    */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI `long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro here.  Note however     */
+  /* that we did not experience any improvement in speed with gcc, and     */
+  /* that the final code seems bigger when linked.                         */
+  /*                                                                       */
+#undef FTCALC_USE_LONG_LONG
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* When compiling FreeType as a DLL, some systems/compilers need a       */
+  /* special keyword in front of each function definition instead of       */
+  /* `extern'.                                                             */
+  /*                                                                       */
+  /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define         */
+  /* exported library function interfaces and exported library functions   */
+  /* implementations respectively.                                         */
+  /*                                                                       */
+  /* If not defined here, they automatically default to `extern' and void  */
+  /* later in this header file.                                            */
+  /*                                                                       */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Debug level                                                           */
+  /*                                                                       */
+  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
+  /*   errors are reported through the `ftdebug' component.  In trace      */
+  /*   mode, additional messages are sent to the standard output during    */
+  /*   execution.                                                          */
+  /*                                                                       */
+  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
+  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
+  /*                                                                       */
+  /*   Don't define any of these macros to compile in `release' mode.      */
+  /*                                                                       */
+#undef  FT_DEBUG_LEVEL_ERROR
+#undef  FT_DEBUG_LEVEL_TRACE
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Anti-aliasing support                                                 */
+  /*                                                                       */
+  /*   Undefine this macro only if you want to disable the anti-aliasing   */
+  /*   support in FreeType.  This will save you about 5 Kb of code.  It    */
+  /*   may be important for some embedded systems.                         */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Endianess performance improvement                                     */
+  /*                                                                       */
+  /*   FreeType is completely endian-independent, and can thus be compiled */
+  /*   directly on _any_ machine.  However, some components of the library */
+  /*   provide improved routines for the cases where endianess is known.   */
+  /*                                                                       */
+  /*   It usually results in speed-ups and reduced code size.  Note that   */
+  /*   you should not define both of these macros.                         */
+  /*                                                                       */
+  /*                                                                       */
+  /*   NOTE: For now, only the scan-line converter (base/ftraster.c) uses  */
+  /*         these macros to speed-up some anti-alias rendering routines.  */
+  /*                                                                       */
+#undef  FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef  FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define this configuration macro whenever you want to build a version  */
+  /* of FreeType that does not include a default `system' component.       */
+  /*                                                                       */
+  /* Note that this will prevent the compilation of `ftinit', hence the    */
+  /* function FT_Init_FreeType                                             */
+  /*                                                                       */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    The size in bytes of the render pool used by the scan-line         */
+  /*    converter to do all of its work.                                   */
+  /*                                                                       */
+  /*    This must be greater than 4 Kb                                     */
+  /*                                                                       */
+#define FT_RENDER_POOL_SIZE   32768
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_DRIVERS                                                     */
+  /*                                                                       */
+  /*    The maximum number of font drivers that can be registered in a     */
+  /*    single FreeType library object.  8 seems to be a good choice due   */
+  /*    to the relative low actual number of drivers ;-)                   */
+  /*                                                                       */
+#define FT_MAX_DRIVERS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_EXTENSIONS                                                  */
+  /*                                                                       */
+  /*    The maximum number of extensions that can be registered in a       */
+  /*    single font driver. 8 seems to be a good choice for now..          */
+  /*                                                                       */
+#define FT_MAX_EXTENSIONS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_GLYPH_FORMATS                                               */
+  /*                                                                       */
+  /*    The maximum number of glyph image formats that might be registered */
+  /*    in a given library instance. 8 seems to be a good choice due to    */
+  /*    the relatively low number of current formats ;-)                   */
+  /*                                                                       */
+
+#define FT_MAX_GLYPH_FORMATS  8
+
+
+
+#endif /* FTOPTION_H */
diff --git a/config/ansi/ftsys.c b/config/ansi/ftsys.c
new file mode 100644
index 0000000..8042d56
--- /dev/null
+++ b/config/ansi/ftsys.c
@@ -0,0 +1,971 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftsys.c                                                                */
+/*                                                                         */
+/*    ANSI-specific system operations (body).                              */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This implementation of the `ftsys' component uses the standard ANSI C */
+  /* library.                                                              */
+  /*                                                                       */
+  /* IMPORTANT NOTE:                                                       */
+  /*                                                                       */
+  /*    Porters, read carefully the comments in ftsys.h before trying to   */
+  /*    port this file to your system.  It contains many essential         */
+  /*    remarks, and will ease your work greatly.                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include "ftsys.h"
+#include "ftstream.h"
+#include "ftdebug.h"
+
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+#include "memdebug.c"
+#endif
+
+
+  /*************************************************************************/
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the PTRACE() and PERROR() macros, used to print/log      */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_io
+
+
+#undef  CUR_SYSTEM  /* just in case */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* To ease porting, we use the macro SYS_STREAM to name the              */
+  /* system-specific stream type.  For example, it is a `FILE*' with the   */
+  /* ANSI libc, it will be a file descriptor, i.e. an integer, when using  */
+  /* the Unix system API, etc.                                             */
+  /*                                                                       */
+#define SYS_STREAM  FILE*
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This implementation of ftsys uses the ANSI C library.  Memory         */
+  /* management is performed through malloc/free, i/o access through       */
+  /* fopen/fread/fseek, and no synchronisation primitive is implemented    */
+  /* (they contain dummy code)                                             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                      I/O ACCESS AND MANAGEMENT                        */
+  /*                                                                       */
+  /* We only define the `ANSI' resource class in this class.  It is        */
+  /* disk-based and provides a MRU cache in order to only keep the file    */
+  /* descriptors of the 10 most recently used resource files.              */
+  /*                                                                       */
+  /* It simply contains two lists.  One contains the `cached' resources    */
+  /* with a valid FILE* pointer, the second contains all other `flushed'   */
+  /* resource objects.                                                     */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_AnsiFileRec                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The FT_AnsiFile class derives from FT_ResourceRec.                 */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    root      :: The root resource class fields.                       */
+  /*                                                                       */
+  /*    pathname  :: This is a copy of the ANSI file pathname used to open */
+  /*                 streams for the resource.  A different implementation */
+  /*                 is free to use Unicode chars, or file i-node numbers, */
+  /*                 etc.                                                  */
+  /*                                                                       */
+  /*    file_size :: The size in bytes of the resource.  This field should */
+  /*                 be set to -1 until the resource is first opened.      */
+  /*                                                                       */
+  typedef struct  FT_AnsiFileRec_
+  {
+    FT_ResourceRec  root;
+    char*           pathname;   /* the font file's pathname           */
+    FT_Long         file_size;  /* file size in bytes                 */
+
+  } FT_AnsiFileRec, *FT_AnsiFile;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* We use the macro STREAM_Name() as a convenience to return a given     */
+  /* ANSI resource's pathname.  Its `stream' argument is a FT_Resource     */
+  /* which is typecasted to the FT_AnsiFile class.                         */
+  /*                                                                       */
+#define STREAM_Name( stream )  ((FT_AnsiFile)stream->resource)->pathname
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* We use the macro STREAM_File() as a convenience to extract the        */
+  /* system-specific stream handle from a given FreeType stream object.    */
+  /*                                                                       */
+#define STREAM_File( stream )  ((FILE*)stream->stream_id.pointer)
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    AnsiFile_Open                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used to open a system-stream for a given          */
+  /*    resource.                                                          */
+  /*                                                                       */
+  /*    Note that it must update the target FreeType stream object with    */
+  /*    the system-stream handle and the resource's size.                  */
+  /*                                                                       */
+  /*    Also, the `stream->base' field must be set to NULL for disk-based  */
+  /*    resources, and to the address in memory of the resource's first    */
+  /*    byte for memory-based ones.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    resource :: The source resource.                                   */
+  /*    stream   :: The target stream object.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function simply calls fopen() in the resource's file          */
+  /*    pathname.                                                          */
+  /*                                                                       */
+  /*    The stream object IS NOT CREATED by this function, but by its      */
+  /*    caller.                                                            */
+  /*                                                                       */
+  static
+  FT_Error  AnsiFile_Open( FT_AnsiFile  resource,
+                           FT_Stream    stream )
+  {
+    FILE*  file;
+
+    /* open the file */
+    file = fopen( resource->pathname, "rb" );
+    if ( !file )
+    {
+      PERROR(( "AnsiFile_Open: Could not open file `%s'\n",
+               resource->pathname ));
+      return FT_Err_Cannot_Open_Stream;
+    }
+
+    /* compute file size if necessary */
+    if ( resource->file_size < 0 )
+    {
+      fseek( file, 0, SEEK_END );
+      resource->file_size = ftell( file );
+      fseek( file, 0, SEEK_SET );
+    }
+
+    stream->resource          = (FT_Resource)resource;
+    stream->stream_id.pointer = file;
+    stream->size              = resource->file_size;
+
+    /* it's a disk-based resource, we don't need to use the `base' and   */
+    /* `cursor' fields of the stream objects                             */
+    stream->base              = NULL;
+    stream->cursor            = NULL;
+
+    PTRACE1(( "AnsiFile_Open: Opened `%s' (%d bytes) successfully\n",
+              resource->pathname, resource->file_size ));
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    AnsiFile_Close                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Closes a given stream.                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream :: The target stream object.                                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function simply calls fclose() on the stream's ANSI FILE      */
+  /*    object.                                                            */
+  /*                                                                       */
+  static
+  FT_Error  AnsiFile_Close( FT_Stream  stream )
+  {
+    PTRACE1(( "AnsiFile_Close: Closing file `%s'\n", STREAM_Name( stream ) ));
+
+    fclose( STREAM_File( stream ) );
+
+    stream->resource          = NULL;
+    stream->stream_id.pointer = NULL;
+    stream->size              = 0;
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    AnsiFile_Seek                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Seeks a stream to a given position.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream   :: The target stream object.                              */
+  /*    position :: The offset in bytes from the start of the              */
+  /*                resource/stream.                                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function simply calls fseek() on the stream.                  */
+  /*                                                                       */
+  /*    The `seek' method is never called by the stream manager in case    */
+  /*    of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+  /*                                                                       */
+  static
+  FT_Error  AnsiFile_Seek( FT_Stream  stream,
+                           FT_Long    position )
+  {
+    if ( fseek( STREAM_File( stream ), position, SEEK_SET ) )
+    {
+      PERROR(( "AnsiFile_Seek: FAILED!  Pos. %ld of `%s'\n",
+               position, STREAM_Name( stream ) ));
+
+      return FT_Err_Invalid_Stream_Seek;
+    }
+
+    PTRACE2(( "AnsiFile_Seek: Pos. %ld of `%s'\n",
+              position, STREAM_Name( stream ) ));
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    AnsiFile_Skip                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Skips a given number of bytes in an ANSI stream.  Useful to skip   */
+  /*    pad bytes, for example.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream :: The target stream object.                                */
+  /*    count  :: The number of bytes to skip in the stream.               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function simply calls fseek() on the stream.                  */
+  /*                                                                       */
+  /*    The `skip' method is never called by the stream manager in case    */
+  /*    of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+  /*                                                                       */
+  static
+  FT_Error  AnsiFile_Skip( FT_Stream  stream,
+                           FT_Long    count )
+  {
+    if ( fseek( STREAM_File( stream ), count, SEEK_CUR ) )
+    {
+      PERROR(( "AnsiFile_Skip: FAILED!  %ld bytes in `%s'\n",
+               count, STREAM_Name( stream ) ));
+
+      return FT_Err_Invalid_Stream_Seek;
+    }
+
+    PTRACE2(( "AnsiFile_Skip: %ld bytes in `%s'\n",
+              count, STREAM_Name( stream ) ));
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    AnsiFile_Pos                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the current offset within an ANSI stream's resource.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream   :: The target stream object.                              */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    position :: The current offset.  -1 in case of error.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function simply calls ftell() on the stream.                  */
+  /*                                                                       */
+  /*    The `pos' method is never called by the stream manager in case     */
+  /*    of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+  /*                                                                       */
+  static
+  FT_Error  AnsiFile_Pos( FT_Stream  stream,
+                          FT_Long*   position )
+  {
+    *position = ftell( STREAM_File( stream ) );
+    if ( *position == -1 )
+    {
+      PTRACE2(( "AnsiFile_Pos: FAILED!  In `%s'\n", STREAM_Name( stream ) ));
+      return FT_Err_Invalid_Stream_Seek;
+    }
+
+    PTRACE2(( "AnsiFile_Pos: For `%s'\n", STREAM_Name( stream ) ));
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    AnsiFile_Read                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Reads a given number of bytes from an ANSI stream into memory.     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream     :: The target stream object.                            */
+  /*    buffer     :: The target read buffer where data is copied.         */
+  /*    size       :: The number of bytes to read from the stream.         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    read_bytes :: The number of bytes effectively read from the        */
+  /*                  stream.  Used in case of error                       */
+  /*                  (i.e. FT_Err_Invalid_Stream_Read) by some parts of   */
+  /*                  the library.                                         */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*   This function simply calls fread() on the stream.                   */
+  /*                                                                       */
+  /*   It MUST return the error FT_Err_Invalid_Stream_Read in case of      */
+  /*   an over-read (i.e., reading more bytes from the stream that what    */
+  /*   is left), as the stream component checks for this specific value.   */
+  /*                                                                       */
+  /*   The `read' method is never called by the stream manager in case     */
+  /*   of a memory-based resource (i.e., when `stream->base' isn't NULL).  */
+  /*                                                                       */
+  static
+  FT_Error  AnsiFile_Read( FT_Stream  stream,
+                           FT_Char*   buffer,
+                           FT_Long    size,
+                           FT_Long*   read_bytes )
+  {
+    *read_bytes = fread( buffer, 1, size, STREAM_File( stream ) );
+    if ( *read_bytes != size )
+    {
+      /* Note : we can have an over-read here when called by the */
+      /*        function FT_Access_Compressed_Frame. This means  */
+      /*        that the following message should be a trace,    */
+      /*        rather than an error for disk-based resources..  */
+      /*                                                         */
+      /*        the function must set the value of 'read_bytes'  */
+      /*        even if it returns an error code..               */
+      PTRACE2(( "AnsiFile_Read: FAILED!  Read %ld bytes from '%s'\n",
+               size, STREAM_Name( stream ) ));
+
+      return FT_Err_Invalid_Stream_Read;
+    }
+
+    PTRACE2(( "AnsiFile_Read: Read %ld bytes to buffer 0x%08lx from `%s'\n",
+              size, (long)buffer, STREAM_Name( stream ) ));
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The following table is the `virtual method table' for the `ANSI       */
+  /* resource class', which methods are defined above.  Its address is set */
+  /* in the `interface' field of all resource objects created by the       */
+  /* function FT_Create_AnsiFile() (see below).                            */
+  /*                                                                       */
+  static
+  FTRes_InterfaceRec  FT_AnsiFile_Interface =
+  {
+    (FTRes_Open_Func) AnsiFile_Open,
+    (FTRes_Close_Func)AnsiFile_Close,
+    (FTRes_Seek_Func) AnsiFile_Seek,
+    (FTRes_Skip_Func) AnsiFile_Skip,
+    (FTRes_Pos_Func)  AnsiFile_Pos,
+    (FTRes_Read_Func) AnsiFile_Read,
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Create_Resource                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new resource object.  This function is called by the     */
+  /*    FT_New_Resource() function of the base layer.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library   :: The input library object.                             */
+  /*    pathname  :: The file's pathname as an ASCII string.               */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    aresource :: A handle to new resource object.                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This functions does not open a stream.  It simply copies the       */
+  /*    pathname within a fresh new resource object.                       */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Create_Resource( FT_Library    library,
+                                const char*   pathname,
+                                FT_Resource*  aresource )
+  {
+    FT_Int       len;
+    FT_AnsiFile  resource;
+    FT_Error     error;
+    FT_System    system;
+
+
+    if ( !library )
+      return FT_Err_Invalid_Library_Handle;
+
+    system = library->system;
+
+    if ( !pathname )
+      goto Fail_Null;
+
+    len = strlen( pathname );
+    if ( len == 0 )
+      goto Fail_Null;
+
+    resource = NULL;
+
+    if ( ALLOC( resource, sizeof ( *resource ) ) ||
+         ALLOC( resource->pathname, len + 1 )    )
+      goto Fail_Memory;
+
+    resource->root.library   = library;
+    resource->root.interface = &FT_AnsiFile_Interface;
+    resource->root.flags     = FT_RESOURCE_TYPE_DISK_BASED;
+    resource->file_size      = -1;
+    strcpy( resource->pathname, pathname );
+
+    PTRACE1(( "Create_AnsiFile: Ansi resource created for `%s'\n",
+              pathname ));
+
+    *aresource = (FT_Resource)resource;
+    return FT_Err_Ok;
+
+  Fail_Null:
+    PERROR(( "Create_AnsiFile: Null pathname!\n" ));
+    return FT_Err_Invalid_Argument;
+
+  Fail_Memory:
+    if ( resource )
+      FREE( resource->pathname );
+    FREE( resource );
+    PERROR(( "Create_AnsiFile: Not enough memory to create resource!\n" ));
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Destroy_Resource                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards a given resource object explicitly.                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    resource :: The ANSI resource object.                              */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function does not check whether runs or streams are opened    */
+  /*    for the resource (for now, we assume developer intelligence.       */
+  /*    We'll most probably lower our standard later to ease debugging :-) */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Destroy_Resource( FT_Resource  resource )
+  {
+    FT_System    system = resource->library->system;
+    FT_AnsiFile  ansi   = (FT_AnsiFile)resource;
+
+    if ( !ansi || ansi->root.interface != &FT_AnsiFile_Interface )
+    {
+      PERROR((
+        "Destroy_AnsiFile: Trying to destroy an invalid resource!\n" ));
+      return FT_Err_Invalid_Resource_Handle;
+    }
+
+    PTRACE1(( "Destroy_AnsiFile: Destroying resource for `%s'\n",
+              ansi->pathname ));
+
+    FREE( ansi->pathname );
+    FREE( ansi );
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                          MEMORY MANAGEMENT                            */
+  /*                                                                       */
+  /*                                                                       */
+  /*  This part copies the old FreeType 1.0 and 1.1 memory management      */
+  /*  scheme that was defined in the file `ttmemory.h'.  One can see that  */
+  /*                                                                       */
+  /*  - a set of macros is defined for the memory operations used by the   */
+  /*    engine (MEM_Copy(), MEM_Move(), MEM_Set()).  This comes from the   */
+  /*    fact that many compilers are able to inline these operations       */
+  /*    directly within the compiled code, rather than generating a call   */
+  /*    to the C library.  However, this obliges us to include the         */
+  /*    `<string.h>' header file.                                          */
+  /*                                                                       */
+  /*    If you provide your own memory operations, you can get rid of the  */
+  /*    `#include <string.h>' below.                                       */
+  /*                                                                       */
+  /*                                                                       */
+  /*  - the FT_Alloc() function has several essential properties that MUST */
+  /*    be retained by each port:                                          */
+  /*                                                                       */
+  /*    - It returns an error code, NOT the allocated block's base         */
+  /*      address.                                                         */
+  /*                                                                       */
+  /*    - It takes the address of a target pointer, where the block's base */
+  /*      address will be set.  If the size is zero, its value will be     */
+  /*      NULL, and the function returns successfully.                     */
+  /*                                                                       */
+  /*    - In case of error, the pointer's value is set to NULL and an      */
+  /*      error code is returned.                                          */
+  /*                                                                       */
+  /*    - The new allocated block MUST be zero-filled.  This is a strong   */
+  /*      convention the rest of the engine relies on.                     */
+  /*                                                                       */
+  /*                                                                       */
+  /*  - the FT_Free() function has also its essentials:                    */
+  /*                                                                       */
+  /*    - It takes the address of a pointer which value is the block's     */
+  /*      base address.  This is UNLIKE a standard `free()' which takes    */
+  /*      the block's base directly.                                       */
+  /*                                                                       */
+  /*    - It accepts successfully the address of a pointer which value is  */
+  /*      NULL, in which case it simply returns.                           */
+  /*                                                                       */
+  /*    - The pointer is always set to NULL by the function.               */
+  /*                                                                       */
+  /*                                                                       */
+  /*  - The MEM_Alloc(), ALLOC(), and ALLOC_ARRAY() macros are used by the */
+  /*    library and should NOT be modified by porters!                     */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the PTRACE() and PERROR() macros, used to print/log      */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_memory
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Alloc                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Allocates a new block of memory.  The returned area is always      */
+  /*    zero-filled, this is a strong convention in many FreeType parts.   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    system :: A handle to a given `system object' where allocation     */
+  /*              occurs.                                                  */
+  /*                                                                       */
+  /*    size   :: The size in bytes of the block to allocate.              */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+  /*              NULL if `size' is 0, or in case of error.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Alloc( FT_System  system,
+                      FT_Long    size,
+                      void**     P )
+  {
+    if ( !P )
+    {
+      PERROR(( "FT_Alloc: Invalid pointer address!\n" ));
+      return FT_Err_Invalid_Argument;
+    }
+
+    if ( size > 0 )
+    {
+      *P = malloc( size );
+      if ( !*P )
+      {
+        PERROR(( "FT_Alloc: Out of memory (%ld bytes requested)!\n",
+                 size ));
+
+        return FT_Err_Out_Of_Memory;
+      }
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+      DM_Record( (char*)*P, size );
+#endif
+
+      system->total_alloc += size;
+
+      /* ALWAYS ZERO-FILL THE BLOCK! */
+      MEM_Set( *P, 0, size );
+    }
+    else
+      *P = NULL;
+
+    PTRACE2(( "FT_Alloc: Size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
+              size, (long)P, (long)*P ));
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Realloc                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Reallocates a block of memory pointed to by `*P' to `Size' bytes   */
+  /*    from the heap, possibly changing `*P'.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    system :: A handle to a given `system object' where allocation     */
+  /*              occurs.                                                  */
+  /*                                                                       */
+  /*    size   :: The size in bytes of the block to allocate.              */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+  /*              NULL if `size' is 0, or in case of error.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Realloc( FT_System  system,
+                        FT_Long    size,
+                        void*     *P )
+  {
+    void*  Q;
+
+
+    if ( !P )
+    {
+      PERROR(( "FT_Realloc: Invalid pointer address!\n" ));
+      return FT_Err_Invalid_Argument;
+    }
+
+    /* if the original pointer is NULL, call FT_Alloc() */
+    if ( !*P )
+      return FT_Alloc( system, size, P );
+
+    /* if the new block if zero-sized, clear the current one */
+    if ( size <= 0 )
+      return FT_Free( system, P );
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+    DM_Forget( (char*)*P );
+#endif
+
+    Q = (void*)realloc( *P, size );
+    if ( !Q )
+    {
+      PERROR(( "FT_Realloc: Reallocation failed!\n" ));
+      return FT_Err_Out_Of_Memory;
+    }
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+    DM_Record( (char*)Q, size );
+#endif
+
+    *P = Q;
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Free                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given block of memory allocated through FT_Alloc().     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    system :: A handle to a given `system object' where allocation     */
+  /*              occured.                                                 */
+  /*                                                                       */
+  /*    P      :: This is the _address_ of a _pointer_ which points to the */
+  /*              allocated block.  It is always set to NULL on exit.      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    If P or *P are NULL, this function should return successfully.     */
+  /*    This is a strong convention within all of FreeType and its         */
+  /*    drivers.                                                           */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Free( FT_System  system,
+                     void*     *P )
+  {
+    UNUSED( system );
+
+    PTRACE2(( "FT_Free: Freeing pointer 0x%08lx (block 0x%08lx)\n",
+              (long)P, (P ? (long)*P : -1) ));
+
+    if ( !P || !*P )
+      return FT_Err_Ok;
+
+    free( *P );
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+    DM_Forget( (char*)*P );
+#endif
+
+    *P = NULL;
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                       SYNCHRONIZATION MANAGEMENT                      */
+  /*                                                                       */
+  /*                                                                       */
+  /*   This section deals with mutexes.  The library can be compiled to    */
+  /*   two distinct thread support levels (namely single threaded and      */
+  /*   re-entrant modes).                                                  */
+  /*                                                                       */
+  /*   It protects its variables through the MUTEX_Lock() and              */
+  /*   MUTEX_Release() macros which are void in single threaded mode.      */
+  /*                                                                       */
+  /*   It defines a typeless mutex reference type, `FT_Mutex', that you're */
+  /*   free to redefine for your system's needs.                           */
+  /*                                                                       */
+  /*   The default implementation of ftsys.c contains only dummy functions */
+  /*   which always return successfully.  You NEED to specialize them in   */
+  /*   order to port ftsys.c to any multi-threaded environment.            */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the PTRACE() and PERROR() macros, used to print/log      */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_sync
+
+
+#ifdef FT_CONFIG_THREADS
+
+  BASE_FUNC
+  FT_Error  FT_Mutex_Create( FT_System  system,
+                             TMutex*    mutex )
+  {
+    UNUSED( system );
+
+    mutex = (void*)-1;
+    system->num_mutexes++;
+
+    /* Insert your own mutex creation code here */
+
+    return FT_Err_Ok;
+  }
+
+
+  BASE_FUNC
+  void  FT_Mutex_Delete( FT_System  system,
+                         TMutex*    mutex )
+  {
+    UNUSED( system );
+
+    mutex = (void*)0;
+    system->num_mutexes--;
+
+    /* Insert your own mutex destruction code here */
+  }
+
+
+  BASE_FUNC
+  void  FT_Mutex_Lock( FT_System  system,
+                       TMutex*    mutex )
+  {
+    /* NOTE: It is legal to call this function with a NULL argument */
+    /*       in which case an immediate return is appropriate.      */
+
+    UNUSED( system );
+
+    if ( !mutex )
+      return;
+
+    /* Insert your own mutex locking code here */
+  }
+
+
+  BASE_FUNC
+  void  FT_Mutex_Release( FT_System  system,
+                          TMutex*    mutex )
+  {
+    /* NOTE: It is legal to call this function with a NULL argument */
+    /*       in which case an immediate return is appropriate       */
+
+    UNUSED( system );
+
+    if ( !mutex )
+      return;
+
+    /* Insert your own mutex release code here */
+  }
+
+#endif /* FT_CONFIG_THREADS */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_System                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used to create and initialize new system objects. */
+  /*    These are mainly used to let client applications and font servers  */
+  /*    specify their own memory allocators and synchronization            */
+  /*    procedures.                                                        */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    system :: A handle to a given `system object'.                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_New_System( FT_System*  system )
+  {
+    *system = (FT_System)malloc( sizeof ( **system ) );
+
+    if ( !*system )
+      return FT_Err_Out_Of_Memory;
+
+    /* the ANSI function `free()' is unable to return the number   */
+    /* of released bytes.  Hence, the `current_alloc' field of the */
+    /* system object cannot be used.                               */
+
+    (*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
+                              FT_SYSTEM_FLAG_MUTEXES;
+    (*system)->total_alloc = 0;
+    (*system)->num_mutexes = 0;
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+    DM_Init_Mem();
+#endif
+
+    /* initialize i/o management (nothing) */
+
+    /* initialize synchronisation (nothing) */
+
+    /* initialize streams (nothing) */
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_System                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given FreeType system object.                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    system :: A handle to a given `system object'.                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Done_System( FT_System  system )
+  {
+    /* finalize synchronization (nothing) */
+
+    /* finalize i/o management (nothing) */
+
+    /* finalize memory management */
+
+#ifdef FT_CONFIG_OPTION_DEBUG_MEMORY
+    DM_Done_Mem();
+#endif
+
+    free( system );
+
+    return FT_Err_Ok;
+  }
+
+
+/* END */
diff --git a/config/ansi/ftsystem.c b/config/ansi/ftsystem.c
new file mode 100644
index 0000000..459f668
--- /dev/null
+++ b/config/ansi/ftsystem.c
@@ -0,0 +1,214 @@
+/**************************************************************************
+ *
+ *  ftsystem.h                                                        1.0
+ *
+ *    ANSI-specific FreeType low-level system interface
+ *
+ *    This file contains the definition of interface used by FreeType
+ *    to access low-level, i.e. memory management, i/o access as well
+ *    as thread synchronisation.              
+ *
+ *
+ *  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 <ftsystem.h>
+#include <fterrors.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                       MEMORY MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Alloc_Func
+ *
+ * <Description>
+ *    The memory allocator function type
+ *
+ * <Input>
+ *    system    :: pointer to the system object
+ *    size      :: requested size in bytes
+ *
+ * <Output>
+ *    block     :: address of newly allocated block
+ *
+ * <Return>  
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    If your allocation routine ALWAYS zeroes the new block, you
+ *    should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ *    object 'flags' field.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_alloc( FT_Memory  memory,
+                   long       size )
+  {
+    (void)memory;
+    return malloc(size);
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Realloc_Func
+ *
+ * <Description>
+ *    The memory reallocator function type
+ *
+ * <Input>
+ *    system   :: pointer to the system object
+ *    new_size :: new requested size in bytes
+ *
+ * <InOut>
+ *    block    :: address of block in memory
+ *
+ * <Return>
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    This function is _never_ called when the system flag 
+ *    FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ *    realloc through "alloc" and "free".
+ *
+ *    Note that this is possible due to the fact that FreeType's
+ *    "FT_Realloc" always requests the _current_ size of the reallocated
+ *    block as a parameter, thus avoiding memory leaks.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_realloc( FT_Memory  memory,
+                     long       cur_size,
+                     long       new_size,
+                     void*      block )
+  {
+    (void)memory;
+    (void)cur_size;
+
+    return realloc( block, new_size );
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Free_Func
+ *
+ * <Description>
+ *    The memory release function type
+ *
+ * <Input>
+ *    system  :: pointer to the system object
+ *    block   :: address of block in memory
+ *
+ * <Note>
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void  ft_free( FT_Memory  memory,
+                 void*      block )
+  {
+    (void)memory;
+    free( block );
+  }
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                     RESOURCE MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+
+#define STREAM_FILE(stream)  ((FILE*)stream->descriptor.pointer)
+
+  static
+  void  ft_close_stream( FT_Stream  stream )
+  {
+    fclose( STREAM_FILE(stream) );
+  }
+
+  static
+  unsigned long  ft_io_stream( FT_Stream      stream,
+                               unsigned long  offset,
+                               char*          buffer,
+                               unsigned long  count )
+  {
+    FILE*  file;
+    
+    file = STREAM_FILE(stream);
+
+    fseek( file, offset, SEEK_SET );    
+    return (unsigned long)fread( buffer, count, 1, file );
+  }
+
+
+  extern
+  int  FT_New_Stream( const char*  filepathname,
+                      FT_Stream    stream )
+  {
+    FILE*  file;
+    
+    file = fopen( filepathname, "rb" );
+    if (!file)
+      return FT_Err_Cannot_Open_Resource;
+      
+    fseek( file, 0, SEEK_END );
+    stream->size = ftell(file);
+    fseek( file, 0, SEEK_SET );
+    
+    stream->descriptor.pointer = file;
+    stream->pos                = 0;
+    
+    stream->read  = ft_io_stream;
+    stream->close = ft_close_stream;
+
+    return 0;
+  }
+
+
+  extern
+  FT_Memory  FT_New_Memory( void )
+  {
+    FT_Memory  memory;
+    
+    memory = (FT_Memory)malloc( sizeof(*memory) );
+    if (memory)
+    {
+      memory->user    = 0;
+      memory->alloc   = ft_alloc;
+      memory->realloc = ft_realloc;
+      memory->free    = ft_free;
+    }
+    return memory;
+  }
+
diff --git a/config/ansi/memdebug.c b/config/ansi/memdebug.c
new file mode 100644
index 0000000..fa27961
--- /dev/null
+++ b/config/ansi/memdebug.c
@@ -0,0 +1,143 @@
+/***************************************************************************/
+/*                                                                         */
+/*  memdebug.c                                                             */
+/*                                                                         */
+/*    Memory debugging functions (body only).                              */
+/*                                                                         */
+/*  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 <stdio.h>
+#include <stdlib.h>
+
+
+  typedef struct  TBlockRec_
+  {
+    char*  base;
+    long   size;
+
+  } TBlockRec;
+
+
+  static TBlockRec*  mem_blocks;
+  static int         num_mem_blocks;
+  static int         max_mem_blocks;
+
+
+  void  DM_Init_Mem()
+  {
+    num_mem_blocks = 0;
+    max_mem_blocks = 4096;
+    mem_blocks     = (TBlockRec*)malloc( max_mem_blocks *
+                                         sizeof ( *mem_blocks ) );
+  }
+
+
+  void  DM_Done_Mem()
+  {
+    /* Now print the remaining blocks */
+    if ( num_mem_blocks == 0 )
+    {
+      fprintf( stderr, "No memory leaked!\n" );
+    }
+    else
+    {
+      int  i;
+
+
+      fprintf( stderr, "There were %d leaked memory blocks\n\n",
+               num_mem_blocks );
+
+      fprintf( stderr, "base     size\n" );
+      fprintf( stderr, "------------------\n" );
+
+      for ( i = 0; i < num_mem_blocks; i++ )
+      {
+        fprintf( stderr, "%08lx  %04lx\n", 
+                 (long)mem_blocks[i].base, mem_blocks[i].size );
+      }
+    }
+    free( mem_blocks );
+  }
+
+
+  void  DM_Record( char*  base,
+                   long   size )
+  {
+    TBlockRec*  block;
+
+
+#if 0
+    /* First, check that the block is not located within one of the */
+    /* recorded blocks                                              */
+    for ( i = 0; i < num_mem_blocks; i++ )
+    {
+      char  *start, *end, *_limit, *_base;
+
+
+      _base  = mem_blocks[i].base;
+      _limit = _base + mem_blocks[i].size;
+
+      start = base;
+      end   = base + size - 1;
+
+      if ( ( start >= base && start < limit ) ||
+           ( end >= base && end < limit )     )
+      {
+        fprintf( stderr, "Warning: Recording an invalid block!\n" );
+      }
+    }
+#endif
+
+    /* Add block to list */
+    if ( num_mem_blocks >= max_mem_blocks )
+    {
+      max_mem_blocks *= 2;
+      mem_blocks = realloc( mem_blocks,
+                            max_mem_blocks * sizeof ( *mem_blocks ) );
+    }
+    block = mem_blocks + num_mem_blocks;
+    block->base = base;
+    block->size = size;
+    num_mem_blocks++;
+  }
+
+
+  void  DM_Forget( char*  base )
+  {
+    TBlockRec*  block = mem_blocks;
+    int         i;
+
+
+    for ( i = 0; i < num_mem_blocks; i++, block++ )
+    {
+      if ( block->base == base )
+      {
+        /* simply move last block to the current position */
+        if ( num_mem_blocks > 1 )
+          *block = mem_blocks[num_mem_blocks - 1];
+
+        num_mem_blocks--;
+        return;
+      }
+
+#if 1
+      if ( base >= block->base && base < block->base + block->size )
+      {
+        fprintf( stderr, "Invalid block forgotten!\n" );
+      }
+#endif
+    }
+  }
+
+
+/* END */
diff --git a/config/detect.mk b/config/detect.mk
new file mode 100644
index 0000000..0dcc7c9
--- /dev/null
+++ b/config/detect.mk
@@ -0,0 +1,127 @@
+#****************************************************************************
+#*                                                                          *
+#*  FreeType host platform detection rules                                  *
+#*                                                                          *
+#*  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.                                         *
+#*                                                                          *
+#*                                                                          *
+#*  This sub-Makefile is in charge of detecting the current platform        *
+#*  It sets some variables accordingly. Namely :                            *
+#*                                                                          *
+#*   PLATFORM     The detected platform. This will default to "ansi" if     *
+#*                auto-detection fails.                                     *
+#*                                                                          *
+#*   BUILD        The configuration and system-specific directory. Usually  *
+#*                'freetype/config/$(PLATFORM)' but can be different when   *
+#*                a specific compiler has been requested on the             *
+#*                command line..                                            *
+#*                                                                          *
+#*   CONFIG_RULES The Makefile to use. This usually depends on the compiler *
+#*                defined in the 'CC' environment variable.                 *
+#*                                                                          *
+#*   DELETE       The shell command used to remove a given file             *
+#*   COPY         The shell command used to copy one file                   *
+#*                                                                          *
+#*  You need to set the following variable(s) before calling it:            *
+#*                                                                          *
+#*    TOP         The top-most directory in the FreeType library source     *
+#*                hierarchy. If not defined, it will default to '.'         *
+#*                                                                          *
+#****************************************************************************
+
+# If TOP is not defined, default it to '.'
+#
+ifndef TOP
+TOP := .
+endif
+
+#
+# set auto-detection default to ANSI.
+# Note that we delay the valuation of BUILD and RULES
+#
+PLATFORM := ansi
+CONFIG    = $(TOP)$(SEP)config
+DELETE   := $(RM)
+COPY     := cp
+SEP      := /
+
+BUILD       = $(CONFIG)$(SEP)$(PLATFORM)
+CONFIG_FILE = $(BUILD)/Makefile
+
+
+###########################################################################
+#
+# Now, include each detection rules file found in a `config/<system>'
+# directory..
+#
+#
+
+# we define the BACKSLASH variable to hold a single back-slash character
+# This is needed because a line like
+#
+# SEP := \
+#
+# does not work with GNU Make (the back-slash is interpreted as a line
+# continuation). While a line like :
+#
+# SEP := \\
+#
+# really define $(SEP) as "\" on Unix, and "\\" on Dos and Windows !!
+#
+BACKSLASH := $(strip \ )
+
+include $(wildcard $(CONFIG)/*/detect.mk)
+
+
+# The following targets are equivalent, with the exception that they use
+# slightly different syntaxes for the `echo' command. This is due to
+#
+# std_setup: is defined for most platforms
+# dos_setup: is defined for Dos-ish platforms like Dos, Windows & OS/2
+#
+
+.PHONY: std_setup  dos_setup
+
+std_setup:
+	@echo ""
+	@echo "FreeType build system - automatic system detection"
+	@echo ""
+	@echo "The following settings were detected :"
+	@echo ""
+	@echo "  platform                 :  $(PLATFORM)"
+	@echo "  compiler                 :  $(CC)"
+	@echo "  configuration directory  :  $(BUILD)"
+	@echo "  configuration rules      :  $(CONFIG_RULES)"
+	@echo ""
+	@echo "If this does not correspond to your system or settings please remove the file"
+	@echo "\`$(CONFIG_MK)' from this directory then read the INSTALL file for help."
+	@echo ""
+	@echo "Otherwise, simple type \`make' again to build the library"
+	@echo ""
+	@$(COPY) $(CONFIG_RULES) $(CONFIG_MK)
+
+dos_setup:
+	@echo ÿ
+	@echo FreeType build system - automatic system detection
+	@echo ÿ
+	@echo The following settings were detected :
+	@echo ÿ
+	@echo ÿÿplatformÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ:  $(PLATFORM)
+	@echo ÿÿcompilerÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ:  $(CC)
+	@echo ÿÿconfiguration directoryÿÿ:  $(BUILD)
+	@echo ÿÿconfiguration rulesÿÿÿÿÿÿ:  $(CONFIG_RULES)
+	@echo ÿ
+	@echo If this does not correspond to your system or settings please remove the file
+	@echo '$(CONFIG_MK)' from this directory then read the INSTALL file for help.
+	@echo ÿ
+	@echo Otherwise, simple type 'make' again to build the library
+	@echo ÿ
+	@$(COPY) $(CONFIG_RULES) $(CONFIG_MK) > nul
+
diff --git a/config/dos/FTCONFIG.H b/config/dos/FTCONFIG.H
new file mode 100644
index 0000000..43a4c95
--- /dev/null
+++ b/config/dos/FTCONFIG.H
@@ -0,0 +1,182 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftconfig.h                                                             */
+/*                                                                         */
+/*    ANSI-specific configuration file (specification only).               */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This header file contains a number of macro definitions that are used */
+  /* by the rest of the engine.  Porters are free to copy this file and    */
+  /* adapt it to suit their own system.                                    */
+  /*                                                                       */
+  /* IMPORTANT NOTE:                                                       */
+  /*                                                                       */
+  /*    Porters, read carefully the comments in `ftsys.h' before trying to */
+  /*    port this file to your system.  It contains many essential         */
+  /*    remarks, and will ease your work greatly.                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/* Include the header file containing all developer build options */
+#include <ftoption.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled to suit a specific system.  The current   */
+  /* ones are defaults used to compile FreeType in an ANSI C environment   */
+  /* (16bit compilers are also supported).  Copy this file to your own     */
+  /* `freetype/arch/<system>'  directory, and edit it to port the engine.  */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* We use <limits.h> values to know the sizes of the types.  */
+#include <limits.h>
+
+/* The number of bytes in an `int' type.  */
+#if   UINT_MAX == 0xFFFFFFFF
+#define SIZEOF_INT  4
+#elif UINT_MAX == 0xFFFF
+#define SIZEOF_INT  2
+#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_INT  8
+#else
+#error "Unsupported number of bytes in `int' type!"
+#endif
+
+/* The number of bytes in a `long' type.  */
+#if   ULONG_MAX == 0xFFFFFFFF
+#define SIZEOF_LONG  4
+#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_LONG  8
+#else
+#error "Unsupported number of bytes in `long' type!"
+#endif
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 0
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 0
+
+
+/* Preferred alignment of data */
+#define FT_ALIGNMENT  8
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                     AUTOMATIC CONFIGURATION MACROS                    */
+  /*                                                                       */
+  /*  These macros are computed from the ones defined above.  Don't touch  */
+  /*  their definition, unless you know precisely what you're doing.  No   */
+  /*  porter should need to mess with them.                                */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* IntN types                                                            */
+  /*                                                                       */
+  /*   Used to guarantee the size of some specific integers.               */
+  /*                                                                       */
+  typedef signed short    FT_Int16;
+  typedef unsigned short  FT_Word16;
+
+#if SIZEOF_INT == 4
+
+  typedef signed int      FT_Int32;
+  typedef unsigned int    FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+  typedef signed long     FT_Int32;
+  typedef unsigned long   FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+  /* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64   long
+
+#else
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI 'long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'.  Note  */
+  /* that this will produce many -ansi warnings during library             */
+  /* compilation.                                                          */
+  /*                                                                       */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64   long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define  LOCAL_DEF   static
+#define  LOCAL_FUNC  static
+#else
+#define  LOCAL_DEF   extern
+#define  LOCAL_FUNC  /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define  BASE_DEF    LOCAL_DEF
+#define  BASE_FUNC   LOCAL_FUNC
+#else
+#define  BASE_DEF    extern
+#define  BASE_FUNC   /* nothing */
+#endif
+
+#ifndef  EXPORT_DEF
+#define  EXPORT_DEF   extern
+#endif
+
+#ifndef  EXPORT_FUNC
+#define  EXPORT_FUNC  /* nothing */
+#endif
+
+#endif /* FTCONFIG_H */
+
+
+/* END */
diff --git a/config/dos/FTOPTION.H b/config/dos/FTOPTION.H
new file mode 100644
index 0000000..caded50
--- /dev/null
+++ b/config/dos/FTOPTION.H
@@ -0,0 +1,152 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled by developers to enable or disable        */
+  /* certain aspects of FreeType.  This file contains macros that apply to */
+  /* all of FreeType.  Driver-specific configurations are placed in each   */
+  /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h').          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Alternate Glyph Image Format support                                  */
+  /*                                                                       */
+  /*   By default, the glyph images returned by the FreeType glyph loader  */
+  /*   can either be a pixmap or a vectorial outline defined through       */
+  /*   bezier control points. When defining the following configuration    */
+  /*   macro, some font drivers will be able to register alternate         */
+  /*   glyph image formats.                                                */
+  /*                                                                       */
+  /*   Unset this macro if you're sure that you'll never use a font driver */
+  /*   with an alternate glyph format, this will reduce the size of the    */
+  /*   base layer code.                                                    */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI `long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro here.  Note however     */
+  /* that we did not experience any improvement in speed with gcc, and     */
+  /* that the final code seems bigger when linked.                         */
+  /*                                                                       */
+#undef FTCALC_USE_LONG_LONG
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* When compiling FreeType as a DLL, some systems/compilers need a       */
+  /* special keyword in front of each function definition instead of       */
+  /* `extern'.                                                             */
+  /*                                                                       */
+  /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define         */
+  /* exported library function interfaces and exported library functions   */
+  /* implementations respectively.                                         */
+  /*                                                                       */
+  /* If not defined here, they automatically default to `extern' and void  */
+  /* later in this header file.                                            */
+  /*                                                                       */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Debug level                                                           */
+  /*                                                                       */
+  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
+  /*   errors are reported through the `ftdebug' component.  In trace      */
+  /*   mode, additional messages are sent to the standard output during    */
+  /*   execution.                                                          */
+  /*                                                                       */
+  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
+  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
+  /*                                                                       */
+  /*   Don't define any of these macros to compile in `release' mode.      */
+  /*                                                                       */
+#undef  FT_DEBUG_LEVEL_ERROR
+#undef  FT_DEBUG_LEVEL_TRACE
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Anti-aliasing support                                                 */
+  /*                                                                       */
+  /*   Undefine this macro only if you want to disable the anti-aliasing   */
+  /*   support in FreeType.  This will save you about 5 Kb of code.  It    */
+  /*   may be important for some embedded systems.                         */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Endianess performance improvement                                     */
+  /*                                                                       */
+  /*   FreeType is completely endian-independent, and can thus be compiled */
+  /*   directly on _any_ machine.  However, some components of the library */
+  /*   provide improved routines for the cases where endianess is known.   */
+  /*                                                                       */
+  /*   It usually results in speed-ups and reduced code size.  Note that   */
+  /*   you should not define both of these macros.                         */
+  /*                                                                       */
+  /*                                                                       */
+  /*   NOTE: For now, only the scan-line converter (base/ftraster.c) uses  */
+  /*         these macros to speed-up some anti-alias rendering routines.  */
+  /*                                                                       */
+#undef  FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef  FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define this configuration macro whenever you want to build a version  */
+  /* of FreeType that does not include a default `system' component.       */
+  /*                                                                       */
+  /* Note that this will prevent the compilation of `ftinit', hence the    */
+  /* function FT_Init_FreeType                                             */
+  /*                                                                       */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    The size in bytes of the render pool used by the scan-line         */
+  /*    converter to do all of its work.                                   */
+  /*                                                                       */
+  /*    This must be greater than 4 Kb                                     */
+  /*                                                                       */
+#define FT_RENDER_POOL_SIZE   32768
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_DRIVERS                                                     */
+  /*                                                                       */
+  /*    The maximum number of font drivers that can be registered in a     */
+  /*    single FreeType library object.  8 seems to be a good choice due   */
+  /*    to the relative low actual number of drivers ;-)                   */
+  /*                                                                       */
+#define FT_MAX_DRIVERS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_GLYPH_FORMATS                                               */
+  /*                                                                       */
+  /*    The maximum number of glyph image formats that might be registered */
+  /*    in a given library instance. 8 seems to be a good choice due to    */
+  /*    the relatively low number of current formats ;-)                   */
+  /*                                                                       */
+
+#define FT_MAX_GLYPH_FORMATS  8
+
+
+
+#endif /* FTOPTION_H */
diff --git a/config/dos/FTSYSTEM.C b/config/dos/FTSYSTEM.C
new file mode 100644
index 0000000..459f668
--- /dev/null
+++ b/config/dos/FTSYSTEM.C
@@ -0,0 +1,214 @@
+/**************************************************************************
+ *
+ *  ftsystem.h                                                        1.0
+ *
+ *    ANSI-specific FreeType low-level system interface
+ *
+ *    This file contains the definition of interface used by FreeType
+ *    to access low-level, i.e. memory management, i/o access as well
+ *    as thread synchronisation.              
+ *
+ *
+ *  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 <ftsystem.h>
+#include <fterrors.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                       MEMORY MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Alloc_Func
+ *
+ * <Description>
+ *    The memory allocator function type
+ *
+ * <Input>
+ *    system    :: pointer to the system object
+ *    size      :: requested size in bytes
+ *
+ * <Output>
+ *    block     :: address of newly allocated block
+ *
+ * <Return>  
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    If your allocation routine ALWAYS zeroes the new block, you
+ *    should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ *    object 'flags' field.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_alloc( FT_Memory  memory,
+                   long       size )
+  {
+    (void)memory;
+    return malloc(size);
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Realloc_Func
+ *
+ * <Description>
+ *    The memory reallocator function type
+ *
+ * <Input>
+ *    system   :: pointer to the system object
+ *    new_size :: new requested size in bytes
+ *
+ * <InOut>
+ *    block    :: address of block in memory
+ *
+ * <Return>
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    This function is _never_ called when the system flag 
+ *    FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ *    realloc through "alloc" and "free".
+ *
+ *    Note that this is possible due to the fact that FreeType's
+ *    "FT_Realloc" always requests the _current_ size of the reallocated
+ *    block as a parameter, thus avoiding memory leaks.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_realloc( FT_Memory  memory,
+                     long       cur_size,
+                     long       new_size,
+                     void*      block )
+  {
+    (void)memory;
+    (void)cur_size;
+
+    return realloc( block, new_size );
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Free_Func
+ *
+ * <Description>
+ *    The memory release function type
+ *
+ * <Input>
+ *    system  :: pointer to the system object
+ *    block   :: address of block in memory
+ *
+ * <Note>
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void  ft_free( FT_Memory  memory,
+                 void*      block )
+  {
+    (void)memory;
+    free( block );
+  }
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                     RESOURCE MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+
+#define STREAM_FILE(stream)  ((FILE*)stream->descriptor.pointer)
+
+  static
+  void  ft_close_stream( FT_Stream  stream )
+  {
+    fclose( STREAM_FILE(stream) );
+  }
+
+  static
+  unsigned long  ft_io_stream( FT_Stream      stream,
+                               unsigned long  offset,
+                               char*          buffer,
+                               unsigned long  count )
+  {
+    FILE*  file;
+    
+    file = STREAM_FILE(stream);
+
+    fseek( file, offset, SEEK_SET );    
+    return (unsigned long)fread( buffer, count, 1, file );
+  }
+
+
+  extern
+  int  FT_New_Stream( const char*  filepathname,
+                      FT_Stream    stream )
+  {
+    FILE*  file;
+    
+    file = fopen( filepathname, "rb" );
+    if (!file)
+      return FT_Err_Cannot_Open_Resource;
+      
+    fseek( file, 0, SEEK_END );
+    stream->size = ftell(file);
+    fseek( file, 0, SEEK_SET );
+    
+    stream->descriptor.pointer = file;
+    stream->pos                = 0;
+    
+    stream->read  = ft_io_stream;
+    stream->close = ft_close_stream;
+
+    return 0;
+  }
+
+
+  extern
+  FT_Memory  FT_New_Memory( void )
+  {
+    FT_Memory  memory;
+    
+    memory = (FT_Memory)malloc( sizeof(*memory) );
+    if (memory)
+    {
+      memory->user    = 0;
+      memory->alloc   = ft_alloc;
+      memory->realloc = ft_realloc;
+      memory->free    = ft_free;
+    }
+    return memory;
+  }
+
diff --git a/config/dos/MAKEFILE.GCC b/config/dos/MAKEFILE.GCC
new file mode 100644
index 0000000..a7642cb
--- /dev/null
+++ b/config/dos/MAKEFILE.GCC
@@ -0,0 +1,172 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for Unix + gcc
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE   := rm -f
+SEP      := /
+BUILD    := $(TOP)/config/dos
+PLATFORM := dos
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o 
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O6 -Wall
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	-$(DELETE) $@
+	$(AR) -r $@ $(OBJECTS_LIST)
+
+endif
diff --git a/config/dos/detect.mk b/config/dos/detect.mk
new file mode 100644
index 0000000..9fe4400
--- /dev/null
+++ b/config/dos/detect.mk
@@ -0,0 +1,87 @@
+#
+# This file is used to detect a DOS host platform.
+#
+# This configuration file to be used depends on the value of the CC
+# environment variable.
+#
+#
+
+# We test for the COMSPEC environment variable, then run the 'ver'
+# command-line program to see if its output contains the word "Dos"
+#
+# If this is true, we're running a Dos-ish platform (or an emulation)
+#
+
+ifeq ($(PLATFORM),ansi)
+
+ifdef COMSPEC
+
+is_dos := $(findstring Dos,$(shell ver))
+
+# We try to recognize a Dos session under OS/2. The "ver" command
+# returns 'Operating System/2 ...' there so 'is_dos' should be empty
+# there.
+#
+# To recognize a Dos session under OS/2, we check COMSPEC for the
+# substring "MDOS\COMMAND"
+#
+ifeq ($(is_dos),)
+is_dos := $(findstring MDOS\COMMAND,$(COMSPEC))
+endif
+
+ifneq ($(is_dos),)
+
+PLATFORM := dos
+DELETE   := del
+COPY     := copy
+
+#####################################################################
+#
+# Use gcc, i.e. DJGPP by default. Aren't we biased ;-)
+#
+#
+CONFIG_FILE := Makefile.gcc
+SEP         := /
+ifndef CC
+CC          := gcc
+endif
+
+
+ifneq ($(findstring turboc,$(MAKECMDGOALS)),)     # Turbo C
+CONFIG_FILE := Makefile.tcc
+SEP         := $(BACKSLASH)
+CC          := tcc
+.PHONY: turboc
+endif
+
+ifneq ($(findstring watcom,$(MAKECMDGOALS)),)     # Watcom C/C++
+CONFIG_FILE := Makefile.wat
+SEP         := $(BACKSLASH)
+CC          := wcc386
+.PHONY: watcom
+endif
+
+ifneq ($(findstring borlandc16,$(MAKECMDGOALS)),)   # Borland C/C++ 16 bits
+CONFIG_FILE := Makefile.bcc
+SEP         := $(BACKSLASH)
+CC          := bcc
+.PHONY: borlandc16
+endif
+
+ifneq ($(findstring borlandc,$(MAKECMDGOALS)),)   # Borland C/C++ 32 bits
+CONFIG_FILE := Makefile.bcc
+SEP         := $(BACKSLASH)
+CC          := bcc32
+.PHONY: borlandc
+endif
+
+CONFIG_RULES := $(TOP)\config\dos\$(CONFIG_FILE)
+
+# use the Dos version of the "setup dump"
+#
+setup:  dos_setup
+
+endif # test Dos
+endif # test COMSPEC
+endif # test PLATFORM
+
diff --git a/config/dos/ftoption.h b/config/dos/ftoption.h
new file mode 100644
index 0000000..852f65f
--- /dev/null
+++ b/config/dos/ftoption.h
@@ -0,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled by developers to enable or disable        */
+  /* certain aspects of FreeType.  This file contains macros that apply to */
+  /* all of FreeType.  Driver-specific configurations are placed in each   */
+  /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h').          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Alternate Glyph Image Format support                                  */
+  /*                                                                       */
+  /*   By default, the glyph images returned by the FreeType glyph loader  */
+  /*   can either be a pixmap or a vectorial outline defined through       */
+  /*   bezier control points. When defining the following configuration    */
+  /*   macro, some font drivers will be able to register alternate         */
+  /*   glyph image formats.                                                */
+  /*                                                                       */
+  /*   Unset this macro if you're sure that you'll never use a font driver */
+  /*   with an alternate glyph format, this will reduce the size of the    */
+  /*   base layer code.                                                    */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI `long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro here.  Note however     */
+  /* that we did not experience any improvement in speed with gcc, and     */
+  /* that the final code seems bigger when linked.                         */
+  /*                                                                       */
+#undef FTCALC_USE_LONG_LONG
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* When compiling FreeType as a DLL, some systems/compilers need a       */
+  /* special keyword in front of each function definition instead of       */
+  /* `extern'.                                                             */
+  /*                                                                       */
+  /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define         */
+  /* exported library function interfaces and exported library functions   */
+  /* implementations respectively.                                         */
+  /*                                                                       */
+  /* If not defined here, they automatically default to `extern' and void  */
+  /* later in this header file.                                            */
+  /*                                                                       */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Debug level                                                           */
+  /*                                                                       */
+  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
+  /*   errors are reported through the `ftdebug' component.  In trace      */
+  /*   mode, additional messages are sent to the standard output during    */
+  /*   execution.                                                          */
+  /*                                                                       */
+  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
+  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
+  /*                                                                       */
+  /*   Don't define any of these macros to compile in `release' mode.      */
+  /*                                                                       */
+#undef  FT_DEBUG_LEVEL_ERROR
+#undef  FT_DEBUG_LEVEL_TRACE
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Anti-aliasing support                                                 */
+  /*                                                                       */
+  /*   Undefine this macro only if you want to disable the anti-aliasing   */
+  /*   support in FreeType.  This will save you about 5 Kb of code.  It    */
+  /*   may be important for some embedded systems.                         */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Endianess performance improvement                                     */
+  /*                                                                       */
+  /*   FreeType is completely endian-independent, and can thus be compiled */
+  /*   directly on _any_ machine.  However, some components of the library */
+  /*   provide improved routines for the cases where endianess is known.   */
+  /*                                                                       */
+  /*   It usually results in speed-ups and reduced code size.  Note that   */
+  /*   you should not define both of these macros.                         */
+  /*                                                                       */
+  /*                                                                       */
+  /*   NOTE: For now, only the scan-line converter (base/ftraster.c) uses  */
+  /*         these macros to speed-up some anti-alias rendering routines.  */
+  /*                                                                       */
+#undef  FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef  FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define this configuration macro whenever you want to build a version  */
+  /* of FreeType that does not include a default `system' component.       */
+  /*                                                                       */
+  /* Note that this will prevent the compilation of `ftinit', hence the    */
+  /* function FT_Init_FreeType                                             */
+  /*                                                                       */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    The size in bytes of the render pool used by the scan-line         */
+  /*    converter to do all of its work.                                   */
+  /*                                                                       */
+  /*    This must be greater than 4 Kb                                     */
+  /*                                                                       */
+#define FT_RENDER_POOL_SIZE   32768
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_DRIVERS                                                     */
+  /*                                                                       */
+  /*    The maximum number of font drivers that can be registered in a     */
+  /*    single FreeType library object.  8 seems to be a good choice due   */
+  /*    to the relative low actual number of drivers ;-)                   */
+  /*                                                                       */
+#define FT_MAX_DRIVERS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_EXTENSIONS                                                  */
+  /*                                                                       */
+  /*    The maximum number of extensions that can be registered in a       */
+  /*    single font driver. 8 seems to be a good choice for now..          */
+  /*                                                                       */
+#define FT_MAX_EXTENSIONS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_GLYPH_FORMATS                                               */
+  /*                                                                       */
+  /*    The maximum number of glyph image formats that might be registered */
+  /*    in a given library instance. 8 seems to be a good choice due to    */
+  /*    the relatively low number of current formats ;-)                   */
+  /*                                                                       */
+
+#define FT_MAX_GLYPH_FORMATS  8
+
+
+
+#endif /* FTOPTION_H */
diff --git a/config/dos/ftsys.c b/config/dos/ftsys.c
new file mode 100644
index 0000000..e276dfc
--- /dev/null
+++ b/config/dos/ftsys.c
@@ -0,0 +1,866 @@
+/*******************************************************************
+ *
+ *  ftsys.c
+ *
+ *    ANSI-specific system operations.
+ *
+ *  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.
+ *
+ *
+ *  This implementation of the 'ftsys' component uses the standard
+ *  ANSI C library.
+ *
+ *  IMPORTANT NOTE :
+ *
+ *    Porters, read carefully the comments in ftsys.h before trying
+ *    to port this file to your system. It contains many essential
+ *    remarks, and will ease your work greatly..
+ *
+ ******************************************************************/
+
+#include "ftsys.h"
+#include "ftstream.h"
+#include "ftdebug.h"
+
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log    */
+/* messages during execution..                                     */
+/*                                                                 */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_io
+
+
+#undef  CUR_SYSTEM  /* just in case */
+
+
+/* To ease porting, we use the macro SYS_STREAM to name the system-specific */
+/* stream type. For example, it is a "FILE*" with the ANSI libc, it will be */
+/* a file descriptor, i.e. an integer, when using the Unix system api, etc. */
+ 
+#define  SYS_STREAM  FILE*
+
+
+  /* This implementation of ftsys uses the ANSI C library. Memory       */
+  /* management is performed through malloc/free, i/o access through    */
+  /* fopen/fread/fseek, and no synchronisation primitive is implemented */
+  /* (they contain dummy code)                                          */
+
+
+
+/**************************************************************************/
+/*                                                                        */
+/*                      I/O ACCESS AND MANAGEMENT                         */
+/*                                                                        */
+/*  We only define the "ANSI" resource class in this class. It is         */
+/*  disk-based, and provides a MRU cache, in order to only keep the file  */
+/*  descriptors of the 10 most recently used resource files.              */
+/*                                                                        */
+/*  it simply contains two lists. One contains the "cached" resources     */
+/*  with a valid FILE* pointer, the second contains all other "flushed"   */
+/*  resource objects.                                                     */
+/*                                                                        */
+
+/* The FT_ANSI_File class derives from FT_ResourceRec - description :  */
+/*                                                                     */
+/* <Struct> FT_AnsiFileRec                                             */
+/*                                                                     */
+/* <Fields>                                                            */
+/*                                                                     */
+/* root ::                                                             */
+/*    the root resource class fields.                                  */
+/*                                                                     */
+/* pathname ::                                                         */
+/*    this is a copy of the ANSI file pathname used to open streams    */
+/*    for the resource. A different implementation is free to use      */
+/*    unicode chars, or file i-node numbers, etc..                     */
+/*                                                                     */
+/* file_size ::                                                        */
+/*    the size in bytes of the resource. This field should be set to   */
+/*    -1 until the resource is first opened..                          */
+/*                                                                     */
+
+#include <stdio.h>
+
+  typedef struct FT_AnsiFileRec_
+  {
+    FT_ResourceRec  root;
+    char*           pathname;   /* the font file's pathname           */
+    FT_Long         file_size;  /* file size in bytes                 */
+    
+  } FT_AnsiFileRec, *FT_AnsiFile;
+
+
+/* We use the macro STREAM_Name as a convenience to return a given  */
+/* ANSI resource's pathname. Its "stream" argument is a FT_Resource */
+/* which is typecasted to the FT_AnsiFile class                     */
+#define STREAM_Name(stream)  ((FT_AnsiFile)stream->resource)->pathname
+
+/* We use the macro STREAM_File as a convenience to extract the      */
+/* system-specific stream handle from a given FreeType stream object */
+#define STREAM_File(stream)  ((FILE*)stream->stream_id.pointer)
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> AnsiFile_Open                                                */
+/*                                                                         */
+/* <Description>                                                           */
+/*    This function is used to open a system-stream for a given resource.  */
+/*                                                                         */
+/*    Note that it must update the target FreeType stream object with the  */
+/*    system-stream handle and the resource's size.                        */
+/*                                                                         */
+/*    Also, the 'stream->base' field must be set to NULL for disk-based    */
+/*    resource, and to the address in memory of the resource's first byte  */
+/*    for a memory-based one.                                              */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   resource :: the source resource                                       */
+/*   stream   :: the target stream object                                  */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function simply calls fopen in the resource's file pathname      */
+/*                                                                         */
+/*   The stream object IS NOT CREATED by this function, but by its caller. */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  AnsiFile_Open( FT_AnsiFile  resource,
+                           FT_Stream    stream )
+  {
+    FILE*  file;
+    
+    /* open the file */
+    file = fopen( resource->pathname, "rb" );
+    if (!file)
+    {
+      PERROR(( "AnsiFile_Open: could not open file '%s'\n",
+               resource->pathname ));
+      return FT_Err_Cannot_Open_Stream;
+    }
+
+    /* compute file size if necessary */
+    if ( resource->file_size < 0 )
+    {
+      fseek( file, 0, SEEK_END );
+      resource->file_size = ftell(file);
+      fseek( file, 0, SEEK_SET );
+    }
+
+    stream->resource          = (FT_Resource)resource;
+    stream->stream_id.pointer = file;
+    stream->size              = resource->file_size;
+    
+    /* it's a disk-based resource, we don't need to use the "base" and   */
+    /* "cursor" fields of the stream objects                             */
+    stream->base              = NULL;
+    stream->cursor            = NULL;
+
+    PTRACE1(( "AnsiFile_Open: opened '%s' (%d bytes) succesfully\n",
+              resource->pathname, resource->file_size ));
+
+    return FT_Err_Ok;
+  }
+
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> AnsiFile_Close                                               */
+/*                                                                         */
+/* <Description> Closes a given stream                                     */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function simply calls fclose on the stream's ANSI FILE object    */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  AnsiFile_Close( FT_Stream  stream )
+  {
+    PTRACE1(( "Closing file '%s'\n", STREAM_Name(stream) ));
+    
+    fclose( STREAM_File(stream) );
+    
+    stream->resource          = NULL;
+    stream->stream_id.pointer = NULL;
+    stream->size              = 0;
+
+    return FT_Err_Ok;
+  }
+
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> AnsiFile_Seek                                                */
+/*                                                                         */
+/* <Description> Seek a stream to a given position                         */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*   position :: offset in bytes from start of resource/stream             */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function simply calls fseek on the stream.                       */
+/*                                                                         */
+/*   The "seek" method is never called by the stream manager in the case   */
+/*   of a memory-based resource (i.e. when 'stream->base' isn't NULL).     */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  AnsiFile_Seek( FT_Stream  stream,
+                           FT_Long    position )
+  {
+    if ( fseek( STREAM_File(stream), position, SEEK_SET ) )
+    {
+      PERROR(( "AnsiFile_Seek : FAILED !! pos. %ld of '%s'\n",
+               position, STREAM_Name(stream) ));
+             
+      return FT_Err_Invalid_Stream_Seek;
+    }
+      
+    PTRACE2(( "AnsiFile_Seek : pos. %ld of '%s'\n",
+              position, STREAM_Name(stream) ));
+             
+    return FT_Err_Ok;
+  }
+
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> AnsiFile_Skip                                                */
+/*                                                                         */
+/* <Description> Skip a given number of bytes in an ANSI stream.           */
+/*               Useful to skip pad bytes, for example.                    */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*   count    :: number of bytes to skip in the stream                     */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function simply calls fseek on the stream.                       */
+/*                                                                         */
+/*   The "skip" method is never called by the stream manager in the case   */
+/*   of a memory-based resource (i.e. when 'stream->base' isn't NULL).     */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  AnsiFile_Skip( FT_Stream  stream,
+                           FT_Long    count )
+  {
+    if ( fseek( STREAM_File(stream), count, SEEK_CUR ) )
+    {
+      PERROR(( "AnsiFile_Skip : FAILED !! %ld bytes in '%s'\n",
+               count, STREAM_Name(stream) ));
+             
+      return FT_Err_Invalid_Stream_Seek;
+    }
+      
+    PTRACE2(( "AnsiFile_Skip : %ld bytes in '%s'\n",count, 
+              STREAM_Name(stream) ));
+             
+    return FT_Err_Ok;
+  }                        
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> AnsiFile_Pos                                                 */
+/*                                                                         */
+/* <Description> Returns the current offset within an ANSI stream's        */
+/*               resource.                                                 */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*                                                                         */
+/* <Output>                                                                */
+/*   position :: current offset. -1 in case of error                       */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code.                                                           */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function simply calls ftell on the stream.                       */
+/*                                                                         */
+/*   The  "pos" method is never called by the stream manager in the case   */
+/*   of a memory-based resource (i.e. when 'stream->base' isn't NULL).     */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  AnsiFile_Pos( FT_Stream  stream,
+                          FT_Long*   position )
+  {
+    *position = ftell( STREAM_File(stream) );
+    if ( *position == -1 )
+    {
+      PTRACE2(( "AnsiFile_Pos : FAILED !! in '%s'\n", STREAM_Name(stream) ));
+      return FT_Err_Invalid_Stream_Seek;
+    }
+    
+    PTRACE2(( "AnsiFile_Pos : for '%s'\n", STREAM_Name(stream) ));
+    return FT_Err_Ok;
+  }
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> AnsiFile_Read                                                */
+/*                                                                         */
+/* <Description> Read a given number of bytes from an ANSI stream into     */
+/*               memory.                                                   */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*   buffer   :: the target read buffer where data is copied               */
+/*   size     :: number of bytes to read from the stream                   */
+/*                                                                         */
+/* <Output>                                                                */
+/*   read_bytes :: the number of bytes effectively read from the stream    */
+/*                 used in case of error (i.e. FT_Err_Invalid_Stream_Read) */
+/*                 by some parts of the library..                          */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function simply calls fread on the stream.                       */
+/*                                                                         */
+/*   It MUST return the error FT_Err_Invalid_Stream_Read in case of        */
+/*   an over-read (i.e. reading more bytes from the stream that what       */
+/*   is left int), as the stream component checks for this specific        */
+/*   value..                                                                      */
+/*                                                                         */
+/*   The "read" method is never called by the stream manager in the case   */
+/*   of a memory-based resource (i.e. when 'stream->base' isn't NULL).     */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  AnsiFile_Read( FT_Stream  stream,
+                           FT_Char*   buffer,
+                           FT_Long    size,
+                           FT_Long*   read_bytes )
+  {
+    *read_bytes = fread( buffer, 1, size, STREAM_File(stream) );
+    if ( *read_bytes != size )
+    {
+      /* Note : we can have an over-read here when called by the */
+      /*        function FT_Access_Compressed_Frame. This means  */
+      /*        that the following message should be a trace,    */
+      /*        rather than an error for disk-based resources..  */
+      /*                                                         */
+      /*        the function must set the value of 'read_bytes'  */
+      /*        even if it returns an error code..               */
+      PTRACE2(( "AnsiFile_Read : FAILED !! read %ld bytes from '%s'\n",
+               size, STREAM_Name(stream) ));
+
+      return FT_Err_Invalid_Stream_Read;
+    }
+
+    PTRACE2(( "AnsiFile_Read : read %ld bytes to buffer 0x%08lx from '%s'\n",
+              size, (long)buffer, STREAM_Name(stream) ));
+    return FT_Err_Ok;
+  }
+
+/* The following table is the "virtual method table" for the 'ANSI  */
+/* resource class', which methods are defined above. Its address is */
+/* set in the 'interface' field of all resource objects created by  */
+/* the function FT_Create_AnsiFile (see below)                      */
+
+  static
+  FTRes_InterfaceRec  FT_AnsiFile_Interface =
+  {
+    (FTRes_Open_Func)        AnsiFile_Open,
+    (FTRes_Close_Func)       AnsiFile_Close,
+    (FTRes_Seek_Func)        AnsiFile_Seek,
+    (FTRes_Skip_Func)        AnsiFile_Skip,
+    (FTRes_Pos_Func)         AnsiFile_Pos,
+    (FTRes_Read_Func)        AnsiFile_Read,
+  };
+
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> FT_Create_Resource                                           */
+/*                                                                         */
+/* <Description> Creates a new resource object, of class "AnsiFile".       */
+/*               This function is never called directly by the font        */
+/*               drivers. Only by the higher-level part of FreeType        */
+/*               (called the HLib), or client applications                 */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   pathname :: the file's pathname, in ASCII                             */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Handle/pointer to the new resource object. NULL in case of error      */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This functions does not open a stream. It simply copies the           */
+/*   pathname within a fresh new resource object.                          */
+/*                                                                         */
+/***************************************************************************/
+
+  EXPORT_FUNC
+  FT_Error     FT_Create_Resource( FT_Library    library,
+                                   const char*   pathname,
+                                   FT_Resource*  aresource )
+  {
+    FT_Int       len;
+    FT_AnsiFile  resource;
+    FT_Error     error;
+    FT_System    system = library->system;
+    
+    if ( !pathname )
+      goto Fail_Null;
+      
+    len = strlen(pathname);
+    if (len == 0)
+      goto Fail_Null;
+
+    resource = NULL;
+    
+    if ( ALLOC( resource, sizeof(*resource) ) ||
+         ALLOC( resource->pathname, len+1   ) )
+      goto Fail_Memory;
+
+    resource->root.library   = library;
+    resource->root.interface = &FT_AnsiFile_Interface;
+    resource->root.flags     = FT_RESOURCE_TYPE_DISK_BASED;
+    resource->file_size      = -1;
+    strcpy( resource->pathname, pathname );
+
+    PTRACE1(( "Create_AnsiFile : Ansi resource created for '%s'\n",
+              pathname ));
+    
+    *aresource = (FT_Resource)resource;
+    return FT_Err_Ok;
+
+  Fail_Null:    
+    PERROR(( "Create_AnsiFile : null pathname !!\n" ));
+    return FT_Err_Invalid_Argument;
+    
+  Fail_Memory:
+    if (resource)
+      FREE( resource->pathname );
+    FREE( resource );
+    PERROR(( "Create_AnsiFile : not enough memory to create resource !\n" ));
+    return error;
+  }
+
+  
+/***************************************************************************/
+/*                                                                         */
+/* <Function> FT_Destroy_Resource                                          */
+/*                                                                         */
+/* <Description> Destroys an ANSI resource object.                         */
+/*               This function is never called directly by the font        */
+/*               drivers. Only by the higher-level part of FreeType        */
+/*               (called the HLib), or client applications                 */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   resource :: the Ansi resource object                                  */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This functions does not check that runs or streams are opened for     */
+/*   the resource (for now, we assume developer intelligence. We'll most   */
+/*   probably lower our standard later to ease debugging ;-)               */
+/*                                                                         */
+/***************************************************************************/
+ 
+  EXPORT_FUNC
+  FT_Error  FT_Destroy_Resource( FT_Resource  resource )
+  {
+    FT_System    system = resource->library->system;
+    FT_AnsiFile  ansi   = (FT_AnsiFile)resource;
+    
+    if ( !ansi || ansi->root.interface != &FT_AnsiFile_Interface )
+    {
+      PERROR(( 
+        "Destroy_AnsiFile : Trying to destroy an invalid resource !!\n" ));
+      return FT_Err_Invalid_Resource_Handle;
+    }
+    
+    PTRACE1(( "Destroy_AnsiFile : destroying resource for '%s'\n",
+              ansi->pathname ));
+
+    FREE( ansi->pathname );
+    FREE( ansi );
+
+    return FT_Err_Ok;
+  }
+
+  
+  
+/**************************************************************************/
+/*                                                                        */
+/*                         MEMORY MANAGEMENT                              */
+/*                                                                        */
+/*                                                                        */
+/*   This part copies the old FreeType 1.0 and 1.1 memory management      */
+/*   scheme that was defined in the file "ttmemory.h". One can see that   */
+/*                                                                        */
+/*   - a set of macros is defined for the memory operations used          */
+/*     by the engine ( MEM_Copy, MEM_Move, MEM_Set ). This comes from     */
+/*     the fact that many compilers are able to inline these ops directly */
+/*     within the compiled code, rather than generating a call to the     */
+/*     C library. However, this obliges us to include the <string.h>      */
+/*     header file.                                                       */
+/*                                                                        */
+/*     If you provide your own memory operations routine, you can get     */
+/*     rid of the #include <string.h> below.                              */
+/*                                                                        */
+/*                                                                        */
+/*   - the FT_Alloc function has several essential properties that        */
+/*     MUST be retained by each port :                                    */
+/*                                                                        */
+/*      - it returns an error code, NOT the allocated block's base        */
+/*        address                                                         */
+/*                                                                        */
+/*      - it takes the address of a target pointer, where the block's     */
+/*        base address will be set. if the size is zero, its value        */
+/*        will be NULL and the function returns successfully              */
+/*                                                                        */
+/*      - in case of error, the pointer's value is set to NULL and        */
+/*        an error code is returned..                                     */
+/*                                                                        */
+/*      - the new allocated block MUST be zero-filled. This is a strong   */
+/*        convetion the rest of the engine relies on                      */
+/*                                                                        */
+/*                                                                        */
+/*                                                                        */
+/*   - the FT_Free function has also its essentials :                     */
+/*                                                                        */
+/*      - it takes the address of a pointer which value is the block's    */
+/*        base address. This is UNLIKE a standard "free" which takes the  */
+/*        the block's base directly.                                      */
+/*                                                                        */
+/*      - it accepts succesfully the address of a pointer which value     */
+/*        is NULL, in which case it simply returns.                       */
+/*                                                                        */
+/*      - the pointer is always set to NULL by the function               */
+/*                                                                        */
+/*                                                                        */
+/*   - the MEM_Alloc, ALLOC and ALLOC_ARRAY macros are used by the        */
+/*     library, and should NOT be modified by porters !!                  */
+/*                                                                        */
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log    */
+/* messages during execution..                                     */
+/*                                                                 */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_memory
+
+
+#include <stdlib.h>
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> FT_Alloc                                                    */
+/*                                                                        */
+/* <Description>                                                          */
+/*    Allocates a new bloc of memory. The returned area is always         */
+/*    zero-filled, this is a strong convention in many FreeType parts     */
+/*                                                                        */
+/* <Input>                                                                */
+/*    system    :: handle to a given 'system object' where allocation     */
+/*                 occurs..                                               */
+/*                                                                        */
+/*    size      :: size in bytes of the block to allocate                 */
+/*                                                                        */
+/* <Output>                                                               */
+/*    P         :: pointer to the fresh new block. It should be set       */
+/*                 to NULL if 'size' is 0, of in case of error..          */
+/*                                                                        */
+/* <Return>                                                               */
+/*    FreeType error code. 0 means success.                               */
+/*                                                                        */
+/**************************************************************************/
+
+  BASE_FUNC
+  FT_Error  FT_Alloc( FT_System  system,
+                      long       size, 
+                      void*     *P ) 
+  {
+  
+    if (!P)
+    {
+      PERROR(( "FT_Alloc : invalid pointer address !!\n" ));
+      return FT_Err_Invalid_Argument;
+    }
+    
+    if ( size > 0 )
+    {
+      *P = malloc( size );
+      if ( !*P )
+      {
+        PERROR(( "FT_Alloc : out of memory (%ld bytes requested) !!\n",
+                 size ));
+
+        return FT_Err_Out_Of_Memory;
+      }
+
+      system->total_alloc += size;
+
+      /* ALWAYS ZERO-FILL THE BLOCK !!!!! */   
+      MEM_Set( *P, 0, size );
+    }
+    else
+      *P = NULL;
+
+    PTRACE2(( "FT_Alloc : size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
+              size, (long)P, (long)*P ));
+
+    return FT_Err_Ok;
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> FT_Realloc                                                  */
+/*                                                                        */
+/* <Description>                                                          */
+/*    Reallocates a block of memory pointed to by '*P' to 'Size'          */
+/*    bytes from the hea^, possibly changing '*P'.                        */
+/*                                                                        */
+/* <Input>                                                                */
+/*    system    :: handle to a given 'system object' where allocation     */
+/*                 occurs..                                               */
+/*                                                                        */
+/*    size      :: size in bytes of the block to allocate                 */
+/*                                                                        */
+/* <InOut>                                                                */
+/*    P         :: pointer to the fresh new block. It should be set       */
+/*                 to NULL if 'size' is 0, of in case of error..          */
+/*                                                                        */
+/* <Return>                                                               */
+/*    FreeType error code. 0 means success.                               */
+/*                                                                        */
+
+  BASE_FUNC
+  int  FT_Realloc( FT_System  system,
+                   long       size, 
+                   void*     *P )
+  {
+    void*  Q;
+    
+    if (!P)
+    {
+      PERROR(( "FT_Realloc : invalid pointer address !!\n" ));
+      return FT_Err_Invalid_Argument;
+    }
+
+    /* if the original pointer is NULL, call FT_Alloc */    
+    if (!*P)
+      return FT_Alloc( system, size, P );
+
+    /* if the new block if zero-sized, clear the current one */    
+    if (size <= 0)
+      return FT_Free( system, P );
+    
+    Q = (void*)realloc( *P, size );
+    if (!Q)
+    {
+      PERROR(( "FT_Realloc : reallocation failed\n" ));
+      return FT_Err_Out_Of_Memory;
+    }
+
+    *P = Q;    
+    return FT_Err_Ok;
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> FT_Free                                                     */
+/*                                                                        */
+/* <Description>                                                          */
+/*    Releases a given block of memory allocated through FT_Alloc         */
+/*                                                                        */
+/* <Input>                                                                */
+/*    system    :: handle to a given 'system object' where allocation     */
+/*                 occured..                                              */
+/*                                                                        */
+/*    P         :: This is the _address_ of a _pointer_ which points to   */
+/*                 the allocated block. It is always set to NULL on exit  */
+/*                                                                        */
+/* <Return>                                                               */
+/*    FreeType error code. 0 means success.                               */
+/*                                                                        */
+/* <Note>                                                                 */
+/*    If P or *P are NULL, this function should return successfuly. This  */
+/*    is a strong convention within all of FreeType and its drivers..     */
+/*                                                                        */
+
+  BASE_FUNC
+  FT_Error  FT_Free( FT_System  system,
+                     void*     *P )
+  {
+    (void)system;  /* unused parameter. Gets rid of warnings */
+
+    PTRACE2(( "FT_Free : freeing pointer 0x%08lx (block 0x%08lx)\n",
+              (long)P, (P ? (long)*P : -1) ));
+
+    if ( !P || !*P )
+      return FT_Err_Ok;
+
+    free( *P );
+    *P = NULL;
+
+    return FT_Err_Ok;
+  }
+
+/**************************************************************************/
+/*                                                                        */
+/*                       SYNCHRONIZATION MANAGEMENT                       */
+/*                                                                        */
+/*                                                                        */
+/*   This section deals with mutexes. The library can be compiled to      */
+/*   three distinct thread-support levels ( namely single-threaded,       */
+/*   thread-safe and re-entrant modes ).                                  */
+/*                                                                        */
+/*   It protects its variables through the MUTEX_Lock and MUTEX_Release   */
+/*   macros which are void in single-threaded mode.                       */
+/*                                                                        */
+/*                                                                        */
+/*   It defines a type-less mutex reference type, "TMutex", that you're   */
+/*   free to redefine for your system's needs..                           */
+/*                                                                        */
+/*   The default implementation of ftsys.c contains only dummy functions  */
+/*   which always return succesfully. you NEED to specialize them in      */
+/*   order to port ftsys.c in any multi-threaded environment...           */
+/*                                                                        */
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log    */
+/* messages during execution..                                     */
+/*                                                                 */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_sync
+
+#ifdef FT_CONFIG_THREADS
+
+
+  BASE_FUNC
+  FT_Error  FT_Mutex_Create ( FT_System  system,
+                              TMutex*    mutex )
+  {
+    (void)system;  /* unused parameter. Gets rid of warnings */
+    
+    mutex = (void*)-1;
+    system->num_mutexes++;
+    return FT_Err_Ok;
+    /* Replace this line with your own mutex creation code */
+  }
+
+
+  BASE_FUNC
+  void  FT_Mutex_Delete ( FT_System  system,
+                          TMutex*    mutex )
+  {
+    (void)system; /* unused parameter. Gets rid of warnings */
+    
+    mutex = (void*)0;
+    system->num_mutexes--;
+    /* Replace this line with your own mutex destruction code */
+  }
+
+  BASE_FUNC
+  void  FT_Mutex_Lock   ( FT_System  system,
+                          TMutex*    mutex )
+  {
+    /* NOTE: It is legal to call this function with a NULL argument */
+    /*       in which case an immediate return is appropriate.      */
+    (void)system; /* unused parameter. Gets rid of warnings */
+    
+    if ( !mutex )
+      return;
+
+    ; /* Insert your own mutex locking code here */
+  }
+
+
+  void  FT_Mutex_Release( FT_System  system,
+                          TMutex*  mutex )
+  {
+    /* NOTE: It is legal to call this function with a NULL argument */
+    /*       in which case an immediate return is appropriate       */
+    (void)system; /* unused parameter. Gets rid of warnings */
+    
+    if ( !mutex )
+      return;
+    ; /* Insert your own mutex release code here */
+  }
+
+#endif /* FT_CONFIG_THREADS */
+
+
+
+
+  EXPORT_FUNC
+  FT_Error  FT_New_System( FT_System*  system )
+  {
+    *system = (FT_System)malloc( sizeof(**system) );
+    if ( !*system )
+      return FT_Err_Out_Of_Memory;
+
+    /* the ANSI function 'free' is unable to  return the number   */
+    /* of released bytes. Hence, the 'current_alloc' field of the */
+    /* system object cannot be used                               */
+    
+    (*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
+                              FT_SYSTEM_FLAG_MUTEXES;
+    (*system)->total_alloc = 0;
+    (*system)->num_mutexes = 0;
+
+    /* initialise i/o management (nothing) */
+    
+    /* initialise synchronisation (nothing) */
+    
+    /* initialise streams */
+
+    return FT_Err_Ok;
+  }
+
+
+
+  EXPORT_FUNC
+  FT_Error  FT_Done_System( FT_System  system )
+  {
+    /* finalise syncrhonisation (nothing) */
+    
+    /* finalise i/o management (nothing)  */
+    
+    /* finalise memory management         */
+    free( system );
+
+    return FT_Err_Ok;
+  }
+
+
+
+
diff --git a/config/freetype.mk b/config/freetype.mk
new file mode 100644
index 0000000..4f78e08
--- /dev/null
+++ b/config/freetype.mk
@@ -0,0 +1,199 @@
+#****************************************************************************
+#*                                                                          *
+#*  FreeType library sub-Makefile                                           *
+#*                                                                          *
+#*  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.                                         *
+#*                                                                          *
+#*                                                                          *
+#*                                                                          *
+#*  DO NOT INVOKE THIS MAKEFILE DIRECTLY. IT IS MEANT TO BE INCLUDED BY     *
+#*  OTHER MAKEFILES.                                                        *
+#*                                                                          *
+#****************************************************************************
+
+
+# The targets `objects', `library' and `multiple' are defined
+# at the end of this Makefile when all rules have been included..
+#
+.PHONY: build_freetype objects library
+
+# default target - build objects and library
+#
+build_freetype: objects library
+
+# `multi' target - build multiple objects and library
+#
+multi: objects library
+
+
+# The FreeType sources directory.
+#
+SRC := $(TOP)$(SEP)src
+
+
+# The directory where the base layer components are placed.
+# By default, this is 'freetype/src/base'
+#
+BASE_DIR := $(SRC)$(SEP)base
+
+
+# A Few short-cuts in order to avoid typing $(SEP) all the time for
+# the directory separator
+#
+# For example:  SRC_ equals to './src/' where '.' is $(TOP)
+#
+#
+SRC_    := $(SRC)$(SEP)
+BASE_   := $(BASE_DIR)$(SEP)
+OBJ_    := $(OBJ_DIR)$(SEP)
+LIB_    := $(LIB_DIR)$(SEP)
+PUBLIC_ := $(TOP)$(SEP)include$(SEP)
+
+# The name of the final library file.
+#
+FT_LIBRARY := $(LIB_DIR)$(SEP)$(LIBRARY).$A
+
+
+# include paths
+#
+# IMPORTANT NOTE: The architecture-dependent directory must ALWAYS be placed
+#                 in front of the include list.  Porters are then able to put
+#                 their own version of some of the FreeType components in
+#                 the 'freetype/arch/<system>' directory, as these files
+#                 will override the default sources.
+#
+INCLUDES := $(BUILD) $(TOP)$(SEP)include $(INCLUDES)
+
+INCLUDE_FLAGS = $(INCLUDES:%=$I%)
+
+
+# C flags used for the compilation of an object file.  This must include at
+# least the paths for the 'base' and 'config/<system>' directories,
+# debug/optimization/warning flags + ansi compliance if needed.
+#
+FT_CFLAGS  = $(CFLAGS) $(INCLUDE_FLAGS)
+FT_CC      = $(CC) $(FT_CFLAGS)
+FT_COMPILE = $(FT_CC)
+
+
+#
+# Free the lists of driver objects
+#
+COMPONENTS_LIST :=
+DRIVERS_LIST    :=
+OBJECTS_LIST    :=
+
+# free the list of 'ftinit' variables
+#
+FTINIT_DRIVER_PATHS  :=
+FTINIT_DRIVER_H      :=
+FTINIT_DRIVER_MACROS :=
+
+
+# System-specific component - this must be defined in this Makefile
+# for easy updates
+#
+# BASE_H is defined in src/base/rules.mk and contains the list of all
+# base layer header files.
+#
+FTSYS_SRC = $(BUILD)$(SEP)ftsystem.c
+FTSYS_OBJ = $(OBJ_DIR)$(SEP)ftsystem.$O
+
+OBJECTS_LIST += $(FTSYS_OBJ)
+
+$(FTSYS_OBJ): $(FTSYS_SRC) $(BASE_H)
+	$(FT_COMPILE) $T$@ $<
+
+
+# ftdebug component
+#
+#
+#
+
+FTDEBUG_SRC = $(BASE_)ftdebug.c
+FTDEBUG_OBJ = $(OBJ_)ftdebug.$O
+
+OBJECTS_LIST += $(FTDEBUG_OBJ)
+
+$(FTDEBUG_OBJ): $(FTDEBUG_SRC) $(BASE_H)
+	$(FT_COMPILE) $T$@ $<
+
+
+
+# Define PUBLIC_H as the list of all public header files located in
+# `$(TOP)/include'
+#
+PUBLIC_H := $(wildcard $(PUBLIC_)*.h)
+
+
+# Include all rule files from FreeType components
+#
+#
+include $(wildcard $(SRC)/*/rules.mk)
+
+# FTInit file:
+#
+#   The C source 'ftinit.c' contains the FreeType initialisation routines.
+#   It is able to automatically register one or more drivers when the API
+#   function FT_Init_FreeType() is called.
+#
+#   The set of initial drivers is determined by the driver Makefiles
+#   includes above.  Each driver Makefile updates the FTINIT_xxxx lists
+#   which contain additional include paths and macros used to compile the
+#   single 'ftapi.c' source.
+#
+FTINIT_SRC := $(BASE_DIR)$(SEP)ftinit.c
+FTINIT_OBJ := $(OBJ_)ftinit.$O
+
+$(FTINIT_OBJ): $(FTINIT_SRC) $(BASE_H) $(FTINIT_DRIVER_H)
+	$(FT_COMPILE) $(FTINIT_DRIVER_PATHS:%=$I%) \
+                      $(FTINIT_DRIVER_MACROS:%=$D%) $T$@ $<
+
+
+# All FreeType library objects
+#
+#   By default, we include the base layer extensions.  These could be
+#   ommitted on builds which do not want them.
+#
+OBJ_M = $(BASE_OBJ_M) $(BASE_EXT_OBJ) $(DRV_OBJS_M) \
+        $(FTSYS_OBJ)  $(FTINIT_OBJ) $(FTDEBUG_OBJ)
+
+OBJ_S = $(BASE_OBJ_S) $(BASE_EXT_OBJ) $(DRV_OBJS_S) \
+        $(FTSYS_OBJ)  $(FTINIT_OBJ) $(FTDEBUG_OBJ)
+
+ifneq ($(findstring multi,$(MAKECMDGOALS)),)
+OBJECTS_LIST += $(OBJ_M)
+else
+OBJECTS_LIST += $(OBJ_S)
+endif
+
+objects: $(OBJECTS_LIST)
+
+library: $(FT_LIBRARY)
+
+.c.$O:
+	$(FT_COMPILE) $T$@ $<
+
+
+clean_freetype:
+	-$(DELETE) $(OBJ_S:/=$(SEP)) $(OBJ_M:/=$(SEP))
+
+
+distclean_freetype: clean_freetype
+	-$(DELETE) $(FT_LIBRARY:/=$(SEP))
+	-$(DELETE) *.orig *~ core *.core
+
+remove_config_mk:
+	-$(DELETE) $(CONFIG_MK:/=$(SEP))
+
+clean: clean_freetype
+distclean: distclean_freetype remove_config_mk
+
+# END
diff --git a/config/os2/Makefile.emx b/config/os2/Makefile.emx
new file mode 100644
index 0000000..75394ea
--- /dev/null
+++ b/config/os2/Makefile.emx
@@ -0,0 +1,196 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for Unix + gcc
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE   := del
+SEP      := /
+BUILD    := $(TOP)/config/os2
+PLATFORM := os2
+CC       := gcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o 
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O6 -Wall
+endif
+
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	-$(DELETE) $@
+	$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
+
+# Cleaning rules
+#
+DIR_OBJ := $(subst $(SEP),\,$(OBJ_DIR))
+
+clean_freetype_objects:
+	-del $(DIR_OBJ)\*.$O
+
+clean_freetype_lib:
+	-del $(subst $(SEP),\,$(FT_LIBRARY))
+
+clean: clean_freetype_objects
+
+
+
+endif
+
+
diff --git a/config/os2/detect.mk b/config/os2/detect.mk
new file mode 100644
index 0000000..42dc47b
--- /dev/null
+++ b/config/os2/detect.mk
@@ -0,0 +1,47 @@
+#
+# This file is used to detect an OS/2 host, and set the build variables
+# accordingly..
+#
+# which Makefile to use based on the value of the CC environment variable.
+#
+# OS/2
+#
+#
+
+ifeq ($(PLATFORM),ansi)
+ifdef OS2_SHELL
+
+PLATFORM := os2
+COPY     := copy
+DELETE   := del
+
+CONFIG_FILE := Makefile.emx   # gcc-emx by default
+SEP         := /
+
+ifneq ($(findstring visualage,$(MAKECMDGOALS)),)     # Visual Age C++
+CONFIG_FILE := Makefile.icc
+SEP         := $(BACKSLASH)
+CC          := icc
+.PHONY: visualage
+endif
+
+ifneq ($(findstring watcom,$(MAKECMDGOALS)),)        # Watcom C/C++
+CONFIG_FILE := Makefile.wat
+SEP         := $(BACKSLASH)
+CC          := wcc386
+.PHONY: watcom
+endif
+
+ifneq ($(findstring borlandc,$(MAKECMDGOALS)),)      # Borland C++ 32 bits
+CONFIG_FILE := Makefile.bcc
+SEP         := $(BACKSLASH)
+CC          := bcc32
+.PHONY: borlandc
+endif
+
+CONFIG_RULES := $(TOP)\config\os2\$(CONFIG_FILE)
+
+setup: dos_setup
+
+endif #test OS2_SHELL
+endif #test PLATFORM
diff --git a/config/os2/ftconfig.h b/config/os2/ftconfig.h
new file mode 100644
index 0000000..43a4c95
--- /dev/null
+++ b/config/os2/ftconfig.h
@@ -0,0 +1,182 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftconfig.h                                                             */
+/*                                                                         */
+/*    ANSI-specific configuration file (specification only).               */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This header file contains a number of macro definitions that are used */
+  /* by the rest of the engine.  Porters are free to copy this file and    */
+  /* adapt it to suit their own system.                                    */
+  /*                                                                       */
+  /* IMPORTANT NOTE:                                                       */
+  /*                                                                       */
+  /*    Porters, read carefully the comments in `ftsys.h' before trying to */
+  /*    port this file to your system.  It contains many essential         */
+  /*    remarks, and will ease your work greatly.                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/* Include the header file containing all developer build options */
+#include <ftoption.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled to suit a specific system.  The current   */
+  /* ones are defaults used to compile FreeType in an ANSI C environment   */
+  /* (16bit compilers are also supported).  Copy this file to your own     */
+  /* `freetype/arch/<system>'  directory, and edit it to port the engine.  */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* We use <limits.h> values to know the sizes of the types.  */
+#include <limits.h>
+
+/* The number of bytes in an `int' type.  */
+#if   UINT_MAX == 0xFFFFFFFF
+#define SIZEOF_INT  4
+#elif UINT_MAX == 0xFFFF
+#define SIZEOF_INT  2
+#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_INT  8
+#else
+#error "Unsupported number of bytes in `int' type!"
+#endif
+
+/* The number of bytes in a `long' type.  */
+#if   ULONG_MAX == 0xFFFFFFFF
+#define SIZEOF_LONG  4
+#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_LONG  8
+#else
+#error "Unsupported number of bytes in `long' type!"
+#endif
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 0
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 0
+
+
+/* Preferred alignment of data */
+#define FT_ALIGNMENT  8
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                     AUTOMATIC CONFIGURATION MACROS                    */
+  /*                                                                       */
+  /*  These macros are computed from the ones defined above.  Don't touch  */
+  /*  their definition, unless you know precisely what you're doing.  No   */
+  /*  porter should need to mess with them.                                */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* IntN types                                                            */
+  /*                                                                       */
+  /*   Used to guarantee the size of some specific integers.               */
+  /*                                                                       */
+  typedef signed short    FT_Int16;
+  typedef unsigned short  FT_Word16;
+
+#if SIZEOF_INT == 4
+
+  typedef signed int      FT_Int32;
+  typedef unsigned int    FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+  typedef signed long     FT_Int32;
+  typedef unsigned long   FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+  /* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64   long
+
+#else
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI 'long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'.  Note  */
+  /* that this will produce many -ansi warnings during library             */
+  /* compilation.                                                          */
+  /*                                                                       */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64   long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define  LOCAL_DEF   static
+#define  LOCAL_FUNC  static
+#else
+#define  LOCAL_DEF   extern
+#define  LOCAL_FUNC  /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define  BASE_DEF    LOCAL_DEF
+#define  BASE_FUNC   LOCAL_FUNC
+#else
+#define  BASE_DEF    extern
+#define  BASE_FUNC   /* nothing */
+#endif
+
+#ifndef  EXPORT_DEF
+#define  EXPORT_DEF   extern
+#endif
+
+#ifndef  EXPORT_FUNC
+#define  EXPORT_FUNC  /* nothing */
+#endif
+
+#endif /* FTCONFIG_H */
+
+
+/* END */
diff --git a/config/os2/ftoption.h b/config/os2/ftoption.h
new file mode 100644
index 0000000..852f65f
--- /dev/null
+++ b/config/os2/ftoption.h
@@ -0,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled by developers to enable or disable        */
+  /* certain aspects of FreeType.  This file contains macros that apply to */
+  /* all of FreeType.  Driver-specific configurations are placed in each   */
+  /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h').          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Alternate Glyph Image Format support                                  */
+  /*                                                                       */
+  /*   By default, the glyph images returned by the FreeType glyph loader  */
+  /*   can either be a pixmap or a vectorial outline defined through       */
+  /*   bezier control points. When defining the following configuration    */
+  /*   macro, some font drivers will be able to register alternate         */
+  /*   glyph image formats.                                                */
+  /*                                                                       */
+  /*   Unset this macro if you're sure that you'll never use a font driver */
+  /*   with an alternate glyph format, this will reduce the size of the    */
+  /*   base layer code.                                                    */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI `long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro here.  Note however     */
+  /* that we did not experience any improvement in speed with gcc, and     */
+  /* that the final code seems bigger when linked.                         */
+  /*                                                                       */
+#undef FTCALC_USE_LONG_LONG
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* When compiling FreeType as a DLL, some systems/compilers need a       */
+  /* special keyword in front of each function definition instead of       */
+  /* `extern'.                                                             */
+  /*                                                                       */
+  /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define         */
+  /* exported library function interfaces and exported library functions   */
+  /* implementations respectively.                                         */
+  /*                                                                       */
+  /* If not defined here, they automatically default to `extern' and void  */
+  /* later in this header file.                                            */
+  /*                                                                       */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Debug level                                                           */
+  /*                                                                       */
+  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
+  /*   errors are reported through the `ftdebug' component.  In trace      */
+  /*   mode, additional messages are sent to the standard output during    */
+  /*   execution.                                                          */
+  /*                                                                       */
+  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
+  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
+  /*                                                                       */
+  /*   Don't define any of these macros to compile in `release' mode.      */
+  /*                                                                       */
+#undef  FT_DEBUG_LEVEL_ERROR
+#undef  FT_DEBUG_LEVEL_TRACE
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Anti-aliasing support                                                 */
+  /*                                                                       */
+  /*   Undefine this macro only if you want to disable the anti-aliasing   */
+  /*   support in FreeType.  This will save you about 5 Kb of code.  It    */
+  /*   may be important for some embedded systems.                         */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Endianess performance improvement                                     */
+  /*                                                                       */
+  /*   FreeType is completely endian-independent, and can thus be compiled */
+  /*   directly on _any_ machine.  However, some components of the library */
+  /*   provide improved routines for the cases where endianess is known.   */
+  /*                                                                       */
+  /*   It usually results in speed-ups and reduced code size.  Note that   */
+  /*   you should not define both of these macros.                         */
+  /*                                                                       */
+  /*                                                                       */
+  /*   NOTE: For now, only the scan-line converter (base/ftraster.c) uses  */
+  /*         these macros to speed-up some anti-alias rendering routines.  */
+  /*                                                                       */
+#undef  FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef  FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define this configuration macro whenever you want to build a version  */
+  /* of FreeType that does not include a default `system' component.       */
+  /*                                                                       */
+  /* Note that this will prevent the compilation of `ftinit', hence the    */
+  /* function FT_Init_FreeType                                             */
+  /*                                                                       */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    The size in bytes of the render pool used by the scan-line         */
+  /*    converter to do all of its work.                                   */
+  /*                                                                       */
+  /*    This must be greater than 4 Kb                                     */
+  /*                                                                       */
+#define FT_RENDER_POOL_SIZE   32768
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_DRIVERS                                                     */
+  /*                                                                       */
+  /*    The maximum number of font drivers that can be registered in a     */
+  /*    single FreeType library object.  8 seems to be a good choice due   */
+  /*    to the relative low actual number of drivers ;-)                   */
+  /*                                                                       */
+#define FT_MAX_DRIVERS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_EXTENSIONS                                                  */
+  /*                                                                       */
+  /*    The maximum number of extensions that can be registered in a       */
+  /*    single font driver. 8 seems to be a good choice for now..          */
+  /*                                                                       */
+#define FT_MAX_EXTENSIONS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_GLYPH_FORMATS                                               */
+  /*                                                                       */
+  /*    The maximum number of glyph image formats that might be registered */
+  /*    in a given library instance. 8 seems to be a good choice due to    */
+  /*    the relatively low number of current formats ;-)                   */
+  /*                                                                       */
+
+#define FT_MAX_GLYPH_FORMATS  8
+
+
+
+#endif /* FTOPTION_H */
diff --git a/config/os2/ftsys.c b/config/os2/ftsys.c
new file mode 100644
index 0000000..df50f1c
--- /dev/null
+++ b/config/os2/ftsys.c
@@ -0,0 +1,940 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftsys.c                                                                */
+/*                                                                         */
+/*    OS/2-specific system operations (body).                              */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This implementation of the `ftsys' component uses malloc()/free() for */
+  /* memory management, and the OS/2 DosXXXXX() API functionss for file    */
+  /* access.                                                               */
+  /*                                                                       */
+  /* IMPORTANT NOTE:                                                       */
+  /*                                                                       */
+  /*    Porters, read carefully the comments in ftsys.h before trying to   */
+  /*    port this file to your system.  It contains many essential         */
+  /*    remarks, and will ease your work greatly.                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include "ftsys.h"
+#include "ftstream.h"
+#include "ftdebug.h"
+
+#include <os2.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+
+  /*************************************************************************/
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the PTRACE() and PERROR() macros, used to print/log      */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_io
+
+
+#undef  CUR_SYSTEM  /* just in case */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* To ease porting, we use the macro SYS_STREAM to name the              */
+  /* system-specific stream type.  For example, it is a `FILE*' with the   */
+  /* ANSI libc, it will be a file descriptor, i.e. an integer, when using  */
+  /* the Unix system API, etc.                                             */
+  /*                                                                       */
+#define SYS_STREAM  HFILE
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                      I/O ACCESS AND MANAGEMENT                        */
+  /*                                                                       */
+  /* We only define the `ANSI' resource class in this class.  It is        */
+  /* disk-based and provides a MRU cache in order to only keep the file    */
+  /* descriptors of the 10 most recently used resource files.              */
+  /*                                                                       */
+  /* It simply contains two lists.  One contains the `cached' resources    */
+  /* with a valid FILE* pointer, the second contains all other `flushed'   */
+  /* resource objects.                                                     */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Os2FileRec                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The FT_Os2File class derives from FT_ResourceRec.                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    root      :: The root resource class fields.                       */
+  /*                                                                       */
+  /*    pathname  :: This is a copy of the ANSI file pathname used to open */
+  /*                 streams for the resource.  A different implementation */
+  /*                 is free to use Unicode chars, or file i-node numbers, */
+  /*                 etc.                                                  */
+  /*                                                                       */
+  /*    file_size :: The size in bytes of the resource.  This field should */
+  /*                 be set to -1 until the resource is first opened.      */
+  /*                                                                       */
+  typedef struct  FT_Os2FileRec_
+  {
+    FT_ResourceRec  root;
+    char*           pathname;   /* the font file's pathname           */
+    FT_Long         file_size;  /* file size in bytes                 */
+
+  } FT_Os2FileRec, *FT_Os2File;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* We use the macro STREAM_Name() as a convenience to return a given     */
+  /* ANSI resource's pathname.  Its `stream' argument is a FT_Resource     */
+  /* which is typecasted to the FT_Os2File class.                          */
+  /*                                                                       */
+#define STREAM_Name( stream )  ((FT_Os2File)stream->resource)->pathname
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* We use the macro STREAM_File() as a convenience to extract the        */
+  /* system-specific stream handle from a given FreeType stream object.    */
+  /*                                                                       */
+#define STREAM_File(stream)  ((HFILE)stream->stream_id.pointer)
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Os2File_Open                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used to open a system-stream for a given          */
+  /*    resource.                                                          */
+  /*                                                                       */
+  /*    Note that it must update the target FreeType stream object with    */
+  /*    the system-stream handle and the resource's size.                  */
+  /*                                                                       */
+  /*    Also, the `stream->base' field must be set to NULL for disk-based  */
+  /*    resources, and to the address in memory of the resource's first    */
+  /*    byte for memory-based ones.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    resource :: The source resource.                                   */
+  /*    stream   :: The target stream object.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The stream object IS NOT CREATED by this function, but by its      */
+  /*    caller.                                                            */
+  /*                                                                       */
+  static
+  FT_Error  Os2File_Open( FT_Os2File  resource,
+                          FT_Stream   stream )
+  {
+    HFILE  file;
+    ULONG  ulAction;
+
+
+    /* open the file */
+#ifdef __EMX__
+    if ( DosOpen( (FT_Byte*)resource->pathname,
+                  &file,
+                  &ulAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS,
+                  OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
+                  NULL ) )
+#else
+    if ( DosOpen( resource->pathname,
+                  &file,
+                  &ulAction, 0, 0, OPEN_ACTION_OPEN_IF_EXISTS,
+                  OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
+                  NULL ) )
+#endif  /* __EMX__ */
+    {
+      PERROR(( "Os2File_Open: Could not open file `%s'\n",
+               resource->pathname ));
+      return FT_Err_Cannot_Open_Stream;
+    }
+
+    /* compute file size if necessary */
+    if ( resource->file_size < 0 )
+    {
+      DosSetFilePtr( file, 0, FILE_END, (ULONG*)&resource->file_size );
+      DosSetFilePtr( file, 0, FILE_BEGIN, &ulAction );
+    }
+
+    stream->resource          = (FT_Resource)resource;
+    stream->stream_id.pointer = (void*)file;
+    stream->size              = resource->file_size;
+
+    /* it's a disk-based resource, we don't need to use the "base" and   */
+    /* "cursor" fields of the stream objects                             */
+    stream->base              = NULL;
+    stream->cursor            = NULL;
+
+    PTRACE1(( "Os2File_Open: Opened `%s' (%d bytes) successfully\n",
+              resource->pathname, resource->file_size ));
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Os2File_Close                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Closes a given stream.                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream :: The target stream object.                                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  FT_Error  Os2File_Close( FT_Stream  stream )
+  {
+    PTRACE1(( "OS2File_Close: Closing file `%s'\n", STREAM_Name( stream ) ));
+
+    DosClose( STREAM_File( stream ) );
+
+    stream->resource          = NULL;
+    stream->stream_id.pointer = NULL;
+    stream->size              = 0;
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Os2File_Seek                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Seeks a stream to a given position.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream   :: The target stream object.                              */
+  /*    position :: The offset in bytes from the start of the              */
+  /*                resource/stream.                                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The `seek' method is never called by the stream manager in case    */
+  /*    of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+  /*                                                                       */
+  static
+  FT_Error  Os2File_Seek( FT_Stream  stream,
+                          FT_Long    position )
+  {
+    ULONG  ibActual;
+
+
+    if ( DosSetFilePtr( STREAM_File( stream ), position,
+                        FILE_BEGIN, &ibActual ) )
+    {
+      PERROR(( "Os2File_Seek: FAILED! Pos. %ld of `%s'\n",
+               position, STREAM_Name( stream ) ));
+
+      return FT_Err_Invalid_Stream_Seek;
+    }
+
+    PTRACE2(( "Os2File_Seek: Pos. %ld of `%s'\n",
+              position, STREAM_Name( stream ) ));
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Os2File_Skip                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Skips a given number of bytes in an OS/2 stream.  Useful to skip   */
+  /*    pad bytes, for example.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream :: The target stream object.                                */
+  /*    count  :: The number of bytes to skip in the stream.               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The `skip' method is never called by the stream manager in case    */
+  /*    of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+  /*                                                                       */
+  static
+  FT_Error  Os2File_Skip( FT_Stream  stream,
+                          FT_Long    count )
+  {
+    ULONG  ibActual;
+
+
+    DosSetFilePtr( STREAM_File( stream ), 0, FILE_CURRENT, &ibActual );
+    return Os2File_Seek( stream, ibActual + count );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Os2File_Pos                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the current offset within an OS/2 stream's resource.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream   :: The target stream object.                              */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    position :: The current offset.  -1 in case of error.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The `pos' method is never called by the stream manager in case     */
+  /*    of a memory-based resource (i.e., when `stream->base' isn't NULL). */
+  /*                                                                       */
+  static
+  FT_Error  Os2File_Pos( FT_Stream  stream,
+                         FT_Long*   position )
+  {
+    ULONG  ibActual;
+
+
+    if ( DosSetFilePtr( STREAM_File( stream ), 0, FILE_CURRENT, &ibActual ) )
+    {
+      PTRACE2(( "Os2File_Pos: FAILED! in `%s'\n", STREAM_Name( stream ) ));
+      return FT_Err_Invalid_Stream_Seek;
+    }
+
+    *position = ibActual;
+
+    PTRACE2(( "Os2File_Pos: For `%s'\n", STREAM_Name( stream ) ));
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Os2File_Read                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Reads a given number of bytes from an OS/2 stream into memory.     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream     :: The target stream object.                            */
+  /*    buffer     :: The target read buffer where data is copied.         */
+  /*    size       :: The number of bytes to read from the stream.         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    read_bytes :: The number of bytes effectively read from the        */
+  /*                  stream.  Used in case of error                       */
+  /*                  (i.e. FT_Err_Invalid_Stream_Read) by some parts of   */
+  /*                  the library.                                         */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*   It MUST return the error FT_Err_Invalid_Stream_Read in case of      */
+  /*   an over-read (i.e., reading more bytes from the stream that what    */
+  /*   is left), as the stream component checks for this specific value.   */
+  /*                                                                       */
+  /*   The `read' method is never called by the stream manager in case     */
+  /*   of a memory-based resource (i.e., when `stream->base' isn't NULL).  */
+  /*                                                                       */
+  static
+  FT_Error  Os2File_Read( FT_Stream  stream,
+                          char*      buffer,
+                          FT_Long    size,
+                          FT_Long*   read_bytes )
+  {
+    ULONG  cbActual;
+
+
+    DosRead( STREAM_File( stream ), buffer, size, &cbActual );
+
+    *read_bytes = cbActual;
+
+    if ( cbActual != (ULONG)size )
+    {
+      /* Note : we can have an over-read here when called by the */
+      /*        function FT_Access_Compressed_Frame. This means  */
+      /*        that the following message should be a trace,    */
+      /*        rather than an error for disk-based resources..  */
+      /*                                                         */
+      /*        the function must set the value of 'read_bytes'  */
+      /*        even if it returns an error code..               */
+      PTRACE2(( "Os2File_Read: FAILED!  Read %ld bytes from '%s'\n",
+               size, STREAM_Name( stream ) ));
+
+      return FT_Err_Invalid_Stream_Read;
+    }
+
+    PTRACE2(( "Os2File_Read: Read %ld bytes to buffer 0x%08lx from `%s'\n",
+              size, (long)buffer, STREAM_Name( stream ) ));
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The following table is the `virtual method table' for the `OS/2       */
+  /* resource class', which methods are defined above.  Its address is set */
+  /* in the `interface' field of all resource objects created by the       */
+  /* function FT_Create_Os2File() (see below).                             */
+  /*                                                                       */
+  static
+  FTRes_InterfaceRec  FT_Os2File_Interface =
+  {
+    (FTRes_Open_Func)        Os2File_Open,
+    (FTRes_Close_Func)       Os2File_Close,
+    (FTRes_Seek_Func)        Os2File_Seek,
+    (FTRes_Skip_Func)        Os2File_Skip,
+    (FTRes_Pos_Func)         Os2File_Pos,
+    (FTRes_Read_Func)        Os2File_Read,
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Create_Resource                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new resource object.  This function is called by the     */
+  /*    FT_New_Resource() function of the base layer.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library   :: The input library object.                             */
+  /*    pathname  :: The file's pathname as an ASCII string.               */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    aresource :: A handle to new resource object.                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This functions does not open a stream.  It simply copies the       */
+  /*    pathname within a fresh new resource object.                       */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Create_Resource( FT_Library    library,
+                                const char*   pathname,
+                                FT_Resource*  aresource )
+  {
+    FT_Int      len;
+    FT_Os2File  resource;
+    FT_Error    error;
+    FT_System   system;
+
+
+    if ( !library )
+      return FT_Err_Invalid_Library_Handle;
+
+    system = library->system;
+
+    if ( !pathname )
+      goto Fail_Null;
+
+    len = strlen( pathname );
+    if ( len == 0 )
+      goto Fail_Null;
+
+    resource = NULL;
+
+    if ( ALLOC( resource, sizeof ( *resource ) ) ||
+         ALLOC( resource->pathname, len + 1 )    )
+      goto Fail_Memory;
+
+    resource->root.library   = library;
+    resource->root.interface = &FT_Os2File_Interface;
+    resource->root.flags     = FT_RESOURCE_TYPE_DISK_BASED;
+    resource->file_size      = -1;
+    strcpy( resource->pathname, pathname );
+
+    PTRACE1(( "Create_Os2File: OS/2 resource created for '%s'\n",
+              pathname ));
+
+    *aresource = (FT_Resource)resource;
+    return FT_Err_Ok;
+
+  Fail_Null:
+    PERROR(( "Create_Os2File: Null pathname!\n" ));
+    return FT_Err_Invalid_Argument;
+
+  Fail_Memory:
+    if ( resource )
+      FREE( resource->pathname );
+    FREE( resource );
+    PERROR(( "Create_Os2File: Not enough memory to create resource!\n" ));
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Destroy_Resource                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards a given resource object explicitly.                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    resource :: The OS/2 resource object.                              */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function does not check whether runs or streams are opened    */
+  /*    for the resource (for now, we assume developer intelligence.       */
+  /*    We'll most probably lower our standard later to ease debugging :-) */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Destroy_Resource( FT_Resource  resource )
+  {
+    FT_System   system = resource->library->system;
+    FT_Os2File  ansi   = (FT_Os2File)resource;
+
+    if ( !ansi || ansi->root.interface != &FT_Os2File_Interface )
+    {
+      PERROR((
+        "Destroy_Os2File: Trying to destroy an invalid resource!\n" ));
+      return FT_Err_Invalid_Resource_Handle;
+    }
+
+    PTRACE1(( "Destroy_Os2File: Destroying resource for `%s'\n",
+              ansi->pathname ));
+
+    FREE( ansi->pathname );
+    FREE( ansi );
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                          MEMORY MANAGEMENT                            */
+  /*                                                                       */
+  /*                                                                       */
+  /*  This part copies the old FreeType 1.0 and 1.1 memory management      */
+  /*  scheme that was defined in the file `ttmemory.h'.  One can see that  */
+  /*                                                                       */
+  /*  - a set of macros is defined for the memory operations used by the   */
+  /*    engine (MEM_Copy(), MEM_Move(), MEM_Set()).  This comes from the   */
+  /*    fact that many compilers are able to inline these operations       */
+  /*    directly within the compiled code, rather than generating a call   */
+  /*    to the C library.  However, this obliges us to include the         */
+  /*    `<string.h>' header file.                                          */
+  /*                                                                       */
+  /*    If you provide your own memory operations, you can get rid of the  */
+  /*    `#include <string.h>' below.                                       */
+  /*                                                                       */
+  /*                                                                       */
+  /*  - the FT_Alloc() function has several essential properties that MUST */
+  /*    be retained by each port:                                          */
+  /*                                                                       */
+  /*    - It returns an error code, NOT the allocated block's base         */
+  /*      address.                                                         */
+  /*                                                                       */
+  /*    - It takes the address of a target pointer, where the block's base */
+  /*      address will be set.  If the size is zero, its value will be     */
+  /*      NULL, and the function returns successfully.                     */
+  /*                                                                       */
+  /*    - In case of error, the pointer's value is set to NULL and an      */
+  /*      error code is returned.                                          */
+  /*                                                                       */
+  /*    - The new allocated block MUST be zero-filled.  This is a strong   */
+  /*      convention the rest of the engine relies on.                     */
+  /*                                                                       */
+  /*                                                                       */
+  /*  - the FT_Free() function has also its essentials:                    */
+  /*                                                                       */
+  /*    - It takes the address of a pointer which value is the block's     */
+  /*      base address.  This is UNLIKE a standard `free()' which takes    */
+  /*      the block's base directly.                                       */
+  /*                                                                       */
+  /*    - It accepts successfully the address of a pointer which value is  */
+  /*      NULL, in which case it simply returns.                           */
+  /*                                                                       */
+  /*    - The pointer is always set to NULL by the function.               */
+  /*                                                                       */
+  /*                                                                       */
+  /*  - The MEM_Alloc(), ALLOC(), and ALLOC_ARRAY() macros are used by the */
+  /*    library and should NOT be modified by porters!                     */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the PTRACE() and PERROR() macros, used to print/log      */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_memory
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Alloc                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Allocates a new block of memory.  The returned area is always      */
+  /*    zero-filled, this is a strong convention in many FreeType parts.   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    system :: A handle to a given `system object' where allocation     */
+  /*              occurs.                                                  */
+  /*                                                                       */
+  /*    size   :: The size in bytes of the block to allocate.              */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+  /*              NULL if `size' is 0, or in case of error.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Alloc( FT_System  system,
+                      FT_Long    size,
+                      void**     P )
+  {
+    if ( !P )
+    {
+      PERROR(( "FT_Alloc: Invalid pointer address!\n" ));
+      return FT_Err_Invalid_Argument;
+    }
+
+    if ( size > 0 )
+    {
+      *P = malloc( size );
+      if ( !*P )
+      {
+        PERROR(( "FT_Alloc: Out of memory (%ld bytes requested)!\n",
+                 size ));
+
+        return FT_Err_Out_Of_Memory;
+      }
+
+      system->total_alloc += size;
+
+      /* ALWAYS ZERO-FILL THE BLOCK! */
+      MEM_Set( *P, 0, size );
+    }
+    else
+      *P = NULL;
+
+    PTRACE2(( "FT_Alloc: Size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
+              size, (long)P, (long)*P ));
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Realloc                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Reallocates a block of memory pointed to by `*P' to `Size' bytes   */
+  /*    from the heap, possibly changing `*P'.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    system :: A handle to a given `system object' where allocation     */
+  /*              occurs.                                                  */
+  /*                                                                       */
+  /*    size   :: The size in bytes of the block to allocate.              */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+  /*              NULL if `size' is 0, or in case of error.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Realloc( FT_System  system,
+                        FT_Long    size,
+                        void**     P )
+  {
+    void*  Q;
+
+
+    if ( !P )
+    {
+      PERROR(( "FT_Realloc: Invalid pointer address!\n" ));
+      return FT_Err_Invalid_Argument;
+    }
+
+    /* if the original pointer is NULL, call FT_Alloc() */
+    if ( !*P )
+      return FT_Alloc( system, size, P );
+
+    /* if the new block if zero-sized, clear the current one */
+    if ( size <= 0 )
+      return FT_Free( system, P );
+
+    Q = (void*)realloc( *P, size );
+    if ( !Q )
+    {
+      PERROR(( "FT_Realloc: Reallocation failed!\n" ));
+      return FT_Err_Out_Of_Memory;
+    }
+
+    *P = Q;
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Free                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given block of memory allocated through FT_Alloc().     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    system :: A handle to a given `system object' where allocation     */
+  /*              occured.                                                 */
+  /*                                                                       */
+  /*    P      :: This is the _address_ of a _pointer_ which points to the */
+  /*              allocated block.  It is always set to NULL on exit.      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    If P or *P are NULL, this function should return successfully.     */
+  /*    This is a strong convention within all of FreeType and its         */
+  /*    drivers.                                                           */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Free( FT_System  system,
+                     void*     *P )
+  {
+    UNUSED( system );
+
+    PTRACE2(( "FT_Free: Freeing pointer 0x%08lx (block 0x%08lx)\n",
+              (long)P, (P ? (long)*P : -1) ));
+
+    if ( !P || !*P )
+      return FT_Err_Ok;
+
+    free( *P );
+    *P = NULL;
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                       SYNCHRONIZATION MANAGEMENT                      */
+  /*                                                                       */
+  /*                                                                       */
+  /*   This section deals with mutexes.  The library can be compiled to    */
+  /*   two distinct thread support levels (namely single threaded and      */
+  /*   re-entrant modes).                                                  */
+  /*                                                                       */
+  /*   It protects its variables through the MUTEX_Lock() and              */
+  /*   MUTEX_Release() macros which are void in single threaded mode.      */
+  /*                                                                       */
+  /*   It defines a typeless mutex reference type, `FT_Mutex', that you're */
+  /*   free to redefine for your system's needs.                           */
+  /*                                                                       */
+  /*   The default implementation of ftsys.c contains only dummy functions */
+  /*   which always return successfully.  You NEED to specialize them in   */
+  /*   order to port ftsys.c to any multi-threaded environment.            */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the PTRACE() and PERROR() macros, used to print/log      */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_sync
+
+
+#ifdef FT_CONFIG_THREADS
+
+  BASE_FUNC
+  FT_Error  FT_Mutex_Create( FT_System  system,
+                             TMutex*    mutex )
+  {
+    UNUSED( system );
+
+    mutex = (void*)-1;
+    system->num_mutexes++;
+
+    /* Insert your own mutex creation code here */
+
+    return FT_Err_Ok;
+  }
+
+
+  BASE_FUNC
+  void  FT_Mutex_Delete( FT_System  system,
+                         TMutex*    mutex )
+  {
+    UNUSED( system );
+
+    mutex = (void*)0;
+    system->num_mutexes--;
+
+    /* Insert your own mutex destruction code here */
+  }
+
+
+  BASE_FUNC
+  void  FT_Mutex_Lock( FT_System  system,
+                       TMutex*    mutex )
+  {
+    /* NOTE: It is legal to call this function with a NULL argument */
+    /*       in which case an immediate return is appropriate.      */
+
+    UNUSED( system );
+
+    if ( !mutex )
+      return;
+
+    /* Insert your own mutex locking code here */
+  }
+
+
+  BASE_FUNC
+  void  FT_Mutex_Release( FT_System  system,
+                          TMutex*    mutex )
+  {
+    /* NOTE: It is legal to call this function with a NULL argument */
+    /*       in which case an immediate return is appropriate       */
+
+    UNUSED( system );
+
+    if ( !mutex )
+      return;
+
+    /* Insert your own mutex release code here */
+  }
+
+#endif /* FT_CONFIG_THREADS */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_System                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used to create and initialize new system objects. */
+  /*    These are mainly used to let client applications and font servers  */
+  /*    specify their own memory allocators and synchronization            */
+  /*    procedures.                                                        */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    system :: A handle to a given `system object'.                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_New_System( FT_System*  system )
+  {
+    *system = (FT_System)malloc( sizeof ( **system ) );
+
+    if ( !*system )
+      return FT_Err_Out_Of_Memory;
+
+    /* initialize memory management */
+
+    (*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
+                              FT_SYSTEM_FLAG_MUTEXES;
+    (*system)->total_alloc = 0;
+    (*system)->num_mutexes = 0;
+
+    /* initialize i/o management (nothing) */
+
+    /* initialize synchronisation (nothing) */
+
+    /* initialize streams (nothing) */
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_System                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given FreeType system object.                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    system :: A handle to a given `system object'.                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Done_System( FT_System  system )
+  {
+    /* finalize synchronization (nothing) */
+
+    /* finalize i/o management (nothing)  */
+
+    /* finalize memory management         */
+
+    free( system );
+
+    return FT_Err_Ok;
+  }
+
+
+/* END */
diff --git a/config/os2/ftsystem.c b/config/os2/ftsystem.c
new file mode 100644
index 0000000..459f668
--- /dev/null
+++ b/config/os2/ftsystem.c
@@ -0,0 +1,214 @@
+/**************************************************************************
+ *
+ *  ftsystem.h                                                        1.0
+ *
+ *    ANSI-specific FreeType low-level system interface
+ *
+ *    This file contains the definition of interface used by FreeType
+ *    to access low-level, i.e. memory management, i/o access as well
+ *    as thread synchronisation.              
+ *
+ *
+ *  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 <ftsystem.h>
+#include <fterrors.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                       MEMORY MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Alloc_Func
+ *
+ * <Description>
+ *    The memory allocator function type
+ *
+ * <Input>
+ *    system    :: pointer to the system object
+ *    size      :: requested size in bytes
+ *
+ * <Output>
+ *    block     :: address of newly allocated block
+ *
+ * <Return>  
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    If your allocation routine ALWAYS zeroes the new block, you
+ *    should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ *    object 'flags' field.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_alloc( FT_Memory  memory,
+                   long       size )
+  {
+    (void)memory;
+    return malloc(size);
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Realloc_Func
+ *
+ * <Description>
+ *    The memory reallocator function type
+ *
+ * <Input>
+ *    system   :: pointer to the system object
+ *    new_size :: new requested size in bytes
+ *
+ * <InOut>
+ *    block    :: address of block in memory
+ *
+ * <Return>
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    This function is _never_ called when the system flag 
+ *    FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ *    realloc through "alloc" and "free".
+ *
+ *    Note that this is possible due to the fact that FreeType's
+ *    "FT_Realloc" always requests the _current_ size of the reallocated
+ *    block as a parameter, thus avoiding memory leaks.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_realloc( FT_Memory  memory,
+                     long       cur_size,
+                     long       new_size,
+                     void*      block )
+  {
+    (void)memory;
+    (void)cur_size;
+
+    return realloc( block, new_size );
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Free_Func
+ *
+ * <Description>
+ *    The memory release function type
+ *
+ * <Input>
+ *    system  :: pointer to the system object
+ *    block   :: address of block in memory
+ *
+ * <Note>
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void  ft_free( FT_Memory  memory,
+                 void*      block )
+  {
+    (void)memory;
+    free( block );
+  }
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                     RESOURCE MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+
+#define STREAM_FILE(stream)  ((FILE*)stream->descriptor.pointer)
+
+  static
+  void  ft_close_stream( FT_Stream  stream )
+  {
+    fclose( STREAM_FILE(stream) );
+  }
+
+  static
+  unsigned long  ft_io_stream( FT_Stream      stream,
+                               unsigned long  offset,
+                               char*          buffer,
+                               unsigned long  count )
+  {
+    FILE*  file;
+    
+    file = STREAM_FILE(stream);
+
+    fseek( file, offset, SEEK_SET );    
+    return (unsigned long)fread( buffer, count, 1, file );
+  }
+
+
+  extern
+  int  FT_New_Stream( const char*  filepathname,
+                      FT_Stream    stream )
+  {
+    FILE*  file;
+    
+    file = fopen( filepathname, "rb" );
+    if (!file)
+      return FT_Err_Cannot_Open_Resource;
+      
+    fseek( file, 0, SEEK_END );
+    stream->size = ftell(file);
+    fseek( file, 0, SEEK_SET );
+    
+    stream->descriptor.pointer = file;
+    stream->pos                = 0;
+    
+    stream->read  = ft_io_stream;
+    stream->close = ft_close_stream;
+
+    return 0;
+  }
+
+
+  extern
+  FT_Memory  FT_New_Memory( void )
+  {
+    FT_Memory  memory;
+    
+    memory = (FT_Memory)malloc( sizeof(*memory) );
+    if (memory)
+    {
+      memory->user    = 0;
+      memory->alloc   = ft_alloc;
+      memory->realloc = ft_realloc;
+      memory->free    = ft_free;
+    }
+    return memory;
+  }
+
diff --git a/config/os2/makefile.devel b/config/os2/makefile.devel
new file mode 100644
index 0000000..f390f79
--- /dev/null
+++ b/config/os2/makefile.devel
@@ -0,0 +1,192 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for Unix + gcc
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+DELETE   := del
+SEP      := /
+BUILD    := $(TOP)/config/os2
+PLATFORM := os2
+CC       := gcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -L
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o 
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O0 -Wall
+endif
+
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	-$(DELETE) $@
+	$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
+
+# Cleaning rules
+#
+DIR_OBJ := $(subst $(SEP),\,$(OBJ_DIR))
+
+clean_freetype_objects:
+	-del $(DIR8OBJ)\*.$O
+
+clean_freetype_lib:
+	-del $(FT_LIBRARY)
+
+clean: clean_freetype_objects
+
+
+
+endif
+
+
diff --git a/config/os2/makefile.gcc b/config/os2/makefile.gcc
new file mode 100644
index 0000000..dfd041c
--- /dev/null
+++ b/config/os2/makefile.gcc
@@ -0,0 +1,190 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for Unix + gcc
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+DELETE   := del
+SEP      := /
+BUILD    := $(TOP)/config/os2
+PLATFORM := os2
+CC       := gcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -L
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o 
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O0 -Wall
+endif
+
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+# A rule used to clean all objects from OBJ_DIR
+#
+# The OS/2 command shell does not support very long list of arguments
+# so we're stuck with wildcards
+#
+
+DIR_OBJ := $(subst $(SEP),\,$(OBJ_DIR))
+
+clean_freetype_objects:
+	-del $(DIR8OBJ)\*.$O
+
+clean_freetype_lib:
+	-del $(FT_LIBRARY)
+
+clean: clean_freetype_objects
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	-$(DELETE) $@
+	$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
+endif
+
diff --git a/config/unix/Makefile b/config/unix/Makefile
new file mode 100644
index 0000000..59c08fe
--- /dev/null
+++ b/config/unix/Makefile
@@ -0,0 +1,172 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for Unix + gcc
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE   := rm -f
+SEP      := /
+BUILD    := $(TOP)/config/unix
+PLATFORM := unix
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o 
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O6 -Wall
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	-$(DELETE) $@
+	$(AR) -r $@ $(OBJECTS_LIST)
+
+endif
diff --git a/config/unix/Makefile.devel b/config/unix/Makefile.devel
new file mode 100644
index 0000000..8710a7c
--- /dev/null
+++ b/config/unix/Makefile.devel
@@ -0,0 +1,172 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for Unix + gcc
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE   := rm -f
+SEP      := /
+BUILD    := $(TOP)/config/unix
+PLATFORM := unix
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o 
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O0 -Wall
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	-$(DELETE) $@
+	$(AR) -r $@ $(OBJECTS_LIST)
+
+endif
diff --git a/config/unix/detect.mk b/config/unix/detect.mk
new file mode 100644
index 0000000..3d39c64
--- /dev/null
+++ b/config/unix/detect.mk
@@ -0,0 +1,31 @@
+#
+# This file is used to detect which Makefile to use based on the
+# value of the CC environment variable.
+#
+# Unix
+#
+#
+# This will _much_ probably change in the future if we're going to use
+# Automake/Autoconf..
+#
+
+ifeq ($(PLATFORM),ansi)
+has_inittab := $(strip $(wildcard /etc/inittab))
+ifneq ($(has_inittab),)
+
+PLATFORM := unix
+COPY     := cp
+DELETE   := rm -f
+
+CONFIG_RULES := $(BUILD)$(SEP)Makefile
+
+setup: std_setup
+
+endif # test Unix
+endif # test PLATFORM
+
+
+
+
+
+
diff --git a/config/unix/ftconfig.h b/config/unix/ftconfig.h
new file mode 100644
index 0000000..de7f6f2
--- /dev/null
+++ b/config/unix/ftconfig.h
@@ -0,0 +1,172 @@
+/*******************************************************************
+ *
+ *  ftconfig.h
+ *
+ *    Unix-specific configuration file
+ *
+ *  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.
+ *
+ *
+ *  This header file contains a number of macro definitions that are
+ *  used by the rest of the engine. Porters are free to copy this file
+ *  and adapt it to suit their own system..
+ *
+ *  IMPORTANT NOTE :
+ *
+ *    Porters, read carefully the comments in ftsys.h before trying
+ *    to port this file to your system. It contains many essential
+ *    remarks, and will ease your work greatly..
+ *
+ ******************************************************************/
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/*************************************************************************/
+/*                                                                       */
+/*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
+/*                                                                       */
+/*  These macros can be toggled to suit a specific system. The current   */
+/*  ones are defaults used to compile FreeType in a 32-bits ANSI C       */
+/*  environment. Copy this file to your own "freetype/arch/<system>"     */
+/*  directory, and edit it to port the engine..                          */
+/*                                                                       */
+/*************************************************************************/
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define if you have a working `mmap' system call.  */
+#define  HAVE_MMAP
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define if the X Window System is missing or not being used.  */
+/* #undef X_DISPLAY_MISSING */
+
+/* The number of bytes in a int.  */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long.  */
+#define SIZEOF_LONG 4
+
+/* Define if you have the getpagesize function.  */
+#define HAVE_GETPAGESIZE 1
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <locale.h> header file.  */
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the <libintl.h> header file.  */
+#undef  HAVE_LIBINTL_H  
+
+/* Define if you have the libintl library.  */
+/* #undef HAVE_LIBINTL */
+
+/* Preferred alignment of data */
+#define  FT_ALIGNMENT  8
+
+/* See the definition of the macro FT_CONFIG_OPTION_LITTLE_ENDIAN */
+/* and FT_CONFIG_OPTION_BIG_ENDIAN below, they may need to be set */
+/* according to the platform too..                                */
+
+
+#include <ftoption.h>
+
+/*************************************************************************/
+/*                                                                       */
+/*                       AUTOMATIC CONFIGURATION MACROS                  */
+/*                                                                       */
+/*  These macros are computed from the ones defined above. Don't touch   */
+/*  their definition, unless you know precisely what you're doing. No    */
+/*  porter should need to mess with them.                                */
+/*                                                                       */
+/*************************************************************************/
+
+  /* IntN types:                                                        */
+  /*                                                                    */
+  /*   Used to guarantee the size of some specific integers.            */
+  /*                                                                    */
+
+  typedef signed short    FT_Int16;
+  typedef unsigned short  FT_Word16;
+
+#if SIZEOF_INT == 4
+
+  typedef signed int      FT_Int32;
+  typedef unsigned int    FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+  typedef signed long     FT_Int32;
+  typedef unsigned long   FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+/* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64   long
+
+#else
+
+/* GCC provides the non-ANSI 'long long' 64-bit type.  You can activate it */
+/* by defining the FTCALC_USE_LONG_LONG macro in 'ftconfig.h'.  Note that  */
+/* this will produce many -ansi warnings during library compilation.       */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64   long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define  LOCAL_DEF   static
+#define  LOCAL_FUNC  static
+#else
+#define  LOCAL_DEF   extern
+#define  LOCAL_FUNC  /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define  BASE_DEF    LOCAL_DEF
+#define  BASE_FUNC   LOCAL_FUNC
+#else
+#define  BASE_DEF    extern
+#define  BASE_FUNC   /* nothing */
+#endif
+
+#ifndef  EXPORT_DEF
+#define  EXPORT_DEF   extern
+#endif
+
+#ifndef  EXPORT_FUNC
+#define  EXPORT_FUNC  /* nothing */
+#endif
+
+
+#endif /* FTCONFIG_H */
diff --git a/config/unix/ftoption.h b/config/unix/ftoption.h
new file mode 100644
index 0000000..852f65f
--- /dev/null
+++ b/config/unix/ftoption.h
@@ -0,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled by developers to enable or disable        */
+  /* certain aspects of FreeType.  This file contains macros that apply to */
+  /* all of FreeType.  Driver-specific configurations are placed in each   */
+  /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h').          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Alternate Glyph Image Format support                                  */
+  /*                                                                       */
+  /*   By default, the glyph images returned by the FreeType glyph loader  */
+  /*   can either be a pixmap or a vectorial outline defined through       */
+  /*   bezier control points. When defining the following configuration    */
+  /*   macro, some font drivers will be able to register alternate         */
+  /*   glyph image formats.                                                */
+  /*                                                                       */
+  /*   Unset this macro if you're sure that you'll never use a font driver */
+  /*   with an alternate glyph format, this will reduce the size of the    */
+  /*   base layer code.                                                    */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI `long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro here.  Note however     */
+  /* that we did not experience any improvement in speed with gcc, and     */
+  /* that the final code seems bigger when linked.                         */
+  /*                                                                       */
+#undef FTCALC_USE_LONG_LONG
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* When compiling FreeType as a DLL, some systems/compilers need a       */
+  /* special keyword in front of each function definition instead of       */
+  /* `extern'.                                                             */
+  /*                                                                       */
+  /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define         */
+  /* exported library function interfaces and exported library functions   */
+  /* implementations respectively.                                         */
+  /*                                                                       */
+  /* If not defined here, they automatically default to `extern' and void  */
+  /* later in this header file.                                            */
+  /*                                                                       */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Debug level                                                           */
+  /*                                                                       */
+  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
+  /*   errors are reported through the `ftdebug' component.  In trace      */
+  /*   mode, additional messages are sent to the standard output during    */
+  /*   execution.                                                          */
+  /*                                                                       */
+  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
+  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
+  /*                                                                       */
+  /*   Don't define any of these macros to compile in `release' mode.      */
+  /*                                                                       */
+#undef  FT_DEBUG_LEVEL_ERROR
+#undef  FT_DEBUG_LEVEL_TRACE
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Anti-aliasing support                                                 */
+  /*                                                                       */
+  /*   Undefine this macro only if you want to disable the anti-aliasing   */
+  /*   support in FreeType.  This will save you about 5 Kb of code.  It    */
+  /*   may be important for some embedded systems.                         */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Endianess performance improvement                                     */
+  /*                                                                       */
+  /*   FreeType is completely endian-independent, and can thus be compiled */
+  /*   directly on _any_ machine.  However, some components of the library */
+  /*   provide improved routines for the cases where endianess is known.   */
+  /*                                                                       */
+  /*   It usually results in speed-ups and reduced code size.  Note that   */
+  /*   you should not define both of these macros.                         */
+  /*                                                                       */
+  /*                                                                       */
+  /*   NOTE: For now, only the scan-line converter (base/ftraster.c) uses  */
+  /*         these macros to speed-up some anti-alias rendering routines.  */
+  /*                                                                       */
+#undef  FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef  FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define this configuration macro whenever you want to build a version  */
+  /* of FreeType that does not include a default `system' component.       */
+  /*                                                                       */
+  /* Note that this will prevent the compilation of `ftinit', hence the    */
+  /* function FT_Init_FreeType                                             */
+  /*                                                                       */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    The size in bytes of the render pool used by the scan-line         */
+  /*    converter to do all of its work.                                   */
+  /*                                                                       */
+  /*    This must be greater than 4 Kb                                     */
+  /*                                                                       */
+#define FT_RENDER_POOL_SIZE   32768
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_DRIVERS                                                     */
+  /*                                                                       */
+  /*    The maximum number of font drivers that can be registered in a     */
+  /*    single FreeType library object.  8 seems to be a good choice due   */
+  /*    to the relative low actual number of drivers ;-)                   */
+  /*                                                                       */
+#define FT_MAX_DRIVERS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_EXTENSIONS                                                  */
+  /*                                                                       */
+  /*    The maximum number of extensions that can be registered in a       */
+  /*    single font driver. 8 seems to be a good choice for now..          */
+  /*                                                                       */
+#define FT_MAX_EXTENSIONS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_GLYPH_FORMATS                                               */
+  /*                                                                       */
+  /*    The maximum number of glyph image formats that might be registered */
+  /*    in a given library instance. 8 seems to be a good choice due to    */
+  /*    the relatively low number of current formats ;-)                   */
+  /*                                                                       */
+
+#define FT_MAX_GLYPH_FORMATS  8
+
+
+
+#endif /* FTOPTION_H */
diff --git a/config/unix/ftsys.c b/config/unix/ftsys.c
new file mode 100644
index 0000000..2198d95
--- /dev/null
+++ b/config/unix/ftsys.c
@@ -0,0 +1,871 @@
+/*******************************************************************
+ *
+ *  ftsys.c
+ *
+ *    Unix-specific system operations.
+ *
+ *  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.
+ *
+ *
+ *  This implementation of the 'ftsys' component uses memory-mapped
+ *  files, as well as the ANSI malloc/free functions..
+ *
+ *  IMPORTANT NOTE :
+ *
+ *    Porters, read carefully the comments in ftsys.h before trying
+ *    to port this file to your system. It contains many essential
+ *    remarks, and will ease your work greatly..
+ *
+ ******************************************************************/
+
+#include "ftsys.h"
+#include "ftobjs.h"
+#include "ftstream.h"
+#include "ftdebug.h"
+
+/* Memory-mapping includes and definitions..                            */
+/*                                                                      */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sys/mman.h>
+#ifndef MAP_FILE
+#define MAP_FILE  0x00
+#endif
+
+/*
+ * The prototype for munmap() is not provided on SunOS.  This needs to
+ * have a check added later to see if the GNU C library is being used.
+ * If so, then this prototype is not needed.
+ */
+#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
+  extern int  munmap( caddr_t  addr, int  len );
+#endif
+
+#include <sys/stat.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log    */
+/* messages during execution..                                     */
+/*                                                                 */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_io
+
+
+
+
+/* To ease porting, we use the macro SYS_STREAM to name the system-specific */
+/* stream type. For example, it is a "FILE*" with the ANSI libc, it will be */
+/* a file descriptor, i.e. an integer, when using the Unix system api, etc. */
+ 
+/* we identify each memory-mapped file through its address in memory */
+/* hence the following macro definition..                            */
+ 
+#define  SYS_STREAM  void*
+
+
+/**************************************************************************/
+/*                                                                        */
+/*                      I/O ACCESS AND MANAGEMENT                         */
+/*                                                                        */
+/*  We only define the "ANSI" resource class in this class. It is         */
+/*  disk-based, and provides a MRU cache, in order to only keep the file  */
+/*  descriptors of the 10 most recently used resource files.              */
+/*                                                                        */
+/*  it simply contains two lists. One contains the "cached" resources     */
+/*  with a valid FILE* pointer, the second contains all other "flushed"   */
+/*  resource objects.                                                     */
+/*                                                                        */
+
+/* The FT_MMapFile class derives from FT_ResourceRec - description :   */
+/*                                                                     */
+/* <Struct> FT_AnsiFileRec                                             */
+/*                                                                     */
+/* <Fields>                                                            */
+/*                                                                     */
+/* root ::                                                             */
+/*    the root resource class fields.                                  */
+/*                                                                     */
+/* pathname ::                                                         */
+/*    the file's pathname. Needed because we open and close font       */
+/*    resources dynamically in order to limit the number of            */
+/*    concurrently active mappings (this saves kernel resources).      */
+/*                                                                     */
+/* file_size ::                                                        */
+/*    the size in bytes of the resource. This field should be set to   */
+/*    -1 until the resource is first opened..                          */
+/*                                                                     */
+
+#include <stdio.h>
+
+  typedef struct FT_MMapFileRec_
+  {
+    FT_ResourceRec  root;
+    const char*     pathname;
+    FT_Long         file_size;  /* file size in bytes */
+    
+  } FT_MMapFileRec, *FT_MMapFile;
+
+
+/* We use the macro STREAM_Name as a convenience to return a given  */
+/* ANSI resource's pathname. Its "stream" argument is a FT_Resource */
+/* which is typecasted to the FT_AnsiFile class                     */
+#define STREAM_Name(stream)  ((FT_MMapFile)stream->resource)->pathname
+
+/* We use the macro STREAM_File as a convenience to extract the      */
+/* system-specific stream handle from a given FreeType stream object */
+#define STREAM_File(stream)  ((void*)stream->stream_id.pointer)
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> MMapFile_Open                                                */
+/*                                                                         */
+/* <Description>                                                           */
+/*    This function is used to open a system-stream for a given resource.  */
+/*                                                                         */
+/*    Note that it must update the target FreeType stream object with the  */
+/*    system-stream handle and the resource's size.                        */
+/*                                                                         */
+/*    Also, the 'stream->base' field must be set to NULL for disk-based    */
+/*    resource, and to the address in memory of the resource's first byte  */
+/*    for a memory-based one.                                              */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   resource :: the source resource                                       */
+/*   stream   :: the target stream object                                  */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function simply opens and maps the resource's file pathname      */
+/*                                                                         */
+/*   The stream object IS NOT CREATED by this function, but by its caller. */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  MMapFile_Open( FT_MMapFile  resource,
+                           FT_Stream    stream )
+  {
+    int          file;
+    struct stat  stat_buf;
+    
+    /* open the file */
+    file = open( resource->pathname, O_RDONLY );
+    if (file < 0)
+    {
+      PERROR(( "UnixSys.MMapFile_Open : could not open '%s'\n",
+               resource->pathname ));
+      return FT_Err_Cannot_Open_Stream;
+    }
+
+    if (fstat( file, &stat_buf ) < 0)
+    {
+      PERROR(( "UnixSys.MMapFile_Open : could not 'fstat' file '%s'\n",
+               resource->pathname ));
+      goto Fail_Map;
+    }
+      
+    if ( resource->file_size < 0 )
+      resource->file_size = stat_buf.st_size;
+      
+    stream->resource          = (FT_Resource)resource;
+    stream->system            = resource->root.driver->system;
+    stream->size              = resource->file_size;
+    stream->stream_id.pointer = mmap( NULL,
+                                      resource->file_size,
+                                      PROT_READ,
+                                      MAP_FILE | MAP_PRIVATE,
+                                      file,
+                                      0 );
+
+    if ( (long)stream->stream_id.pointer == -1 )
+    {
+      PERROR(( "UnixSys.MMapFile_Open : Could not map file '%s'\n",
+               resource->pathname ));
+      goto Fail_Map;
+    }
+
+    close(file);
+    stream->base   = (FT_Byte*)stream->stream_id.pointer;
+    stream->cursor = stream->base;
+    
+    PTRACE1(( "UnixSys.MMapFile_Open: opened '%s' (%d bytes) succesfully\n",
+              resource->pathname, resource->file_size ));
+
+    return FT_Err_Ok;
+    
+  Fail_Map:
+    close(file);
+    stream->resource          = NULL;
+    stream->size              = 0;
+    stream->stream_id.pointer = NULL;
+    stream->base              = NULL;
+    stream->cursor            = NULL;
+    
+    return FT_Err_Cannot_Open_Stream;
+  }
+
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> MMapFile_Close                                               */
+/*                                                                         */
+/* <Description> Closes a given stream                                     */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function simply unmaps the resource..                            */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  MMapFile_Close( FT_Stream  stream )
+  {
+    PTRACE1(( "Closing file '%s'\n", STREAM_Name(stream) ));
+    
+    munmap ( (void*)stream->stream_id.pointer, stream->size );
+        
+    stream->resource          = NULL;
+    stream->stream_id.pointer = NULL;
+    stream->size              = 0;
+    stream->base              = NULL;
+    stream->cursor            = NULL;
+
+    return FT_Err_Ok;
+  }
+
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> MMapFile_Seek                                                */
+/*                                                                         */
+/* <Description> Seek a stream to a given position                         */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*   position :: offset in bytes from start of resource/stream             */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function should never be called for memory-based resources..     */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  MMapFile_Seek( FT_Stream  stream,
+                           FT_Long    position )
+  {
+    (void)stream;
+    (void)position;
+    return FT_Err_Invalid_Stream_Operation;
+  }
+
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> MMapFile_Skip                                                */
+/*                                                                         */
+/* <Description> Skip a given number of bytes in an MMap stream.           */
+/*               Useful to skip pad bytes, for example.                    */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*   count    :: number of bytes to skip in the stream                     */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function should never be called for memory-based resources..     */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  MMapFile_Skip( FT_Stream  stream,
+                           FT_Long    count )
+  {
+    (void)stream;
+    (void)count;
+    return FT_Err_Invalid_Stream_Operation;
+  }                        
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> MMapFile_Pos                                                 */
+/*                                                                         */
+/* <Description> Returns the current offset within an MMap stream's        */
+/*               resource.                                                 */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*                                                                         */
+/* <Output>                                                                */
+/*   position :: current offset. -1 in case of error                       */
+/*                                                                         */
+/* <Return>                                                                */
+/*   Error code.                                                           */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function should never be called for memory-based resources..     */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  MMapFile_Pos( FT_Stream  stream,
+                          FT_Long*   position )
+  {
+    (void)stream;
+    (void)position;
+    return FT_Err_Invalid_Stream_Operation;
+  }
+
+/***************************************************************************/
+/*                                                                         */
+/* <Function> MMapFile_Read                                                */
+/*                                                                         */
+/* <Description> Read a given number of bytes from an MMap stream into     */
+/*               memory.                                                   */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   stream   :: the target stream object                                  */
+/*   buffer   :: the target read buffer where data is copied               */
+/*   size     :: number of bytes to read from the stream                   */
+/*                                                                         */
+/* <Output>                                                                */
+/*   read_bytes :: the number of bytes effectively read from the stream    */
+/*                 used in case of error (i.e. FT_Err_Invalid_Stream_Read) */
+/*                 by some parts of the library..                          */
+/* <Return>                                                                */
+/*   Error code                                                            */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This function should never be called for memory-based resources..     */
+/*                                                                         */
+/***************************************************************************/
+
+  static
+  FT_Error  MMapFile_Read( FT_Stream  stream,
+                           FT_Byte*   buffer,
+                           FT_Long    size,
+                           FT_Long*   read_bytes )
+  {
+    (void)stream;
+    (void)buffer;
+    (void)size;
+    (void)read_bytes;
+    return FT_Err_Invalid_Stream_Operation;                      
+  }
+
+/* The following table is the "virtual method table" for the 'MMap  */
+/* resource class', which methods are defined above. Its address is */
+/* set in the 'interface' field of all resource objects created by  */
+/* the function FT_Create_MMapFile (see below)                      */
+
+  static
+  FTRes_InterfaceRec  FT_MMapFile_Interface =
+  {
+    (FTRes_Open_Func)  MMapFile_Open,
+    (FTRes_Close_Func) MMapFile_Close,
+    (FTRes_Seek_Func)  MMapFile_Seek,
+    (FTRes_Skip_Func)  MMapFile_Skip,
+    (FTRes_Pos_Func)   MMapFile_Pos,
+    (FTRes_Read_Func)  MMapFile_Read,
+  };
+
+
+ /************************************************************************/
+ /*                                                                      */
+ /* <Function>  FT_Create_Resource                                       */
+ /*                                                                      */
+ /* <Description>                                                        */
+ /*    Create a new resource object for a given library. Note that this  */
+ /*    function takes an ASCII 'pathname' as an argument.                */
+ /*                                                                      */
+ /* <Input>                                                              */
+ /*     library  :: handle to target library object                      */
+ /*     pathanme :: ASCII pathname of the font file                      */
+ /*                                                                      */
+ /* <Output>                                                             */
+ /*     resource :: handle to new resource object                        */
+ /*                                                                      */
+ /* <Return>                                                             */
+ /*     Error code. 0 means success                                      */
+ /*                                                                      */
+ /* <Note>                                                               */
+ /*     When porting the library to exotic environments, where an        */
+ /*     ASCII pathname isn't used to name files, developers should       */
+ /*     invoke directly their own resource creation function which       */
+ /*     must be placed in their port of the "ftsys" component.           */
+ /*                                                                      */
+ /*     See the porting guide for more information..                     */
+ /*                                                                      */
+  EXPORT_FUNC
+  FT_Error  FT_Create_Resource( FT_Library    library,
+                                const char*   pathname,
+                                FT_Resource*  aresource )
+  {
+    FT_Int       len;
+    FT_System    system;
+    FT_MMapFile  resource;
+    FT_Error     error;
+
+    *aresource = NULL;
+    
+    if (!library)
+    {
+      PERROR(( "Unix.New_Resource : null library handle\n" ));
+      return FT_Err_Invalid_Library_Handle;
+    }
+
+    system = library->system;
+
+    if ( !pathname )
+      goto Fail_Null;
+      
+    len = strlen(pathname);
+    if (len == 0)
+      goto Fail_Null;
+
+    resource = NULL;
+    
+    if ( ALLOC( resource, sizeof(*resource) ) ||
+         ALLOC( resource->pathname, len+1   ) )
+      goto Fail_Memory;
+
+    resource->root.library   = library;
+    resource->root.interface = &FT_MMapFile_Interface;
+    resource->root.flags     = FT_RESOURCE_TYPE_MEMORY_BASED;
+    resource->file_size      = -1;
+    strcpy( (char*)resource->pathname, pathname );
+
+    PTRACE1(( "Create_MMapFile : MMap resource created for '%s'\n",
+              pathname ));
+    
+    *aresource = (FT_Resource)resource;
+    return FT_Err_Ok;
+
+  Fail_Null:    
+    PERROR(( "Create_MMapFile : null pathname !!\n" ));
+    return FT_Err_Invalid_Argument;
+    
+  Fail_Memory:
+    if (resource)
+      FREE( resource->pathname );
+    FREE( resource );
+    PERROR(( "Create_MMapFile : error when creating resource !\n" ));
+    return error;
+  }
+
+  
+/***************************************************************************/
+/*                                                                         */
+/* <Function> FT_Destroy_Resource                                          */
+/*                                                                         */
+/* <Description> Destroys an MMap resource object.                         */
+/*               This function is never called directly by the font        */
+/*               drivers. Only by the higher-level part of FreeType        */
+/*               (called the HLib), or client applications                 */
+/*                                                                         */
+/* <Input>                                                                 */
+/*   resource :: the MMap resource object                                  */
+/*                                                                         */
+/* <Note>                                                                  */
+/*   This functions does not check that runs or streams are opened for     */
+/*   the resource (for now, we assume developer intelligence. We'll most   */
+/*   probably lower our standard later to ease debugging ;-)               */
+/*                                                                         */
+/***************************************************************************/
+ 
+  EXPORT_FUNC
+  FT_Error  FT_Destroy_Resource( FT_Resource  resource )
+  {
+    FT_System    system = resource->library->system;
+    FT_MMapFile  res    = (FT_MMapFile)resource;
+    
+    if ( !res || res->root.interface != &FT_MMapFile_Interface )
+    {
+      PERROR(( 
+        "Destroy_MMapFile : Trying to destroy an invalid resource !!\n" ));
+      return FT_Err_Invalid_Resource_Handle;
+    }
+    
+    PTRACE1(( "Destroy_MMapFile : destroying resource for '%s'\n",
+              res->pathname ));
+
+    FREE( res->pathname );
+    FREE( res );
+
+    return FT_Err_Ok;
+  }
+
+  
+  
+/**************************************************************************/
+/*                                                                        */
+/*                         MEMORY MANAGEMENT                              */
+/*                                                                        */
+/*                                                                        */
+/*   This part copies the old FreeType 1.0 and 1.1 memory management      */
+/*   scheme that was defined in the file "ttmemory.h". One can see that   */
+/*                                                                        */
+/*   - a set of macros is defined for the memory operations used          */
+/*     by the engine ( MEM_Copy, MEM_Move, MEM_Set ). This comes from     */
+/*     the fact that many compilers are able to inline these ops directly */
+/*     within the compiled code, rather than generating a call to the     */
+/*     C library. However, this obliges us to include the <string.h>      */
+/*     header file.                                                       */
+/*                                                                        */
+/*     If you provide your own memory operations routine, you can get     */
+/*     rid of the #include <string.h> below.                              */
+/*                                                                        */
+/*                                                                        */
+/*   - the FT_Alloc function has several essential properties that        */
+/*     MUST be retained by each port :                                    */
+/*                                                                        */
+/*      - it returns an error code, NOT the allocated block's base        */
+/*        address                                                         */
+/*                                                                        */
+/*      - it takes the address of a target pointer, where the block's     */
+/*        base address will be set. if the size is zero, its value        */
+/*        will be NULL and the function returns successfully              */
+/*                                                                        */
+/*      - in case of error, the pointer's value is set to NULL and        */
+/*        an error code is returned..                                     */
+/*                                                                        */
+/*      - the new allocated block MUST be zero-filled. This is a strong   */
+/*        convetion the rest of the engine relies on                      */
+/*                                                                        */
+/*                                                                        */
+/*                                                                        */
+/*   - the FT_Free function has also its essentials :                     */
+/*                                                                        */
+/*      - it takes the address of a pointer which value is the block's    */
+/*        base address. This is UNLIKE a standard "free" which takes the  */
+/*        the block's base directly.                                      */
+/*                                                                        */
+/*      - it accepts succesfully the address of a pointer which value     */
+/*        is NULL, in which case it simply returns.                       */
+/*                                                                        */
+/*      - the pointer is always set to NULL by the function               */
+/*                                                                        */
+/*                                                                        */
+/*   - the MEM_Alloc, ALLOC and ALLOC_ARRAY macros are used by the        */
+/*     library, and should NOT be modified by porters !!                  */
+/*                                                                        */
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log    */
+/* messages during execution..                                     */
+/*                                                                 */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_memory
+
+
+#include <stdlib.h>
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> FT_Alloc                                                    */
+/*                                                                        */
+/* <Description>                                                          */
+/*    Allocates a new bloc of memory. The returned area is always         */
+/*    zero-filled, this is a strong convention in many FreeType parts     */
+/*                                                                        */
+/* <Input>                                                                */
+/*    system    :: handle to a given 'system object' where allocation     */
+/*                 occurs..                                               */
+/*                                                                        */
+/*    size      :: size in bytes of the block to allocate                 */
+/*                                                                        */
+/* <Output>                                                               */
+/*    P         :: pointer to the fresh new block. It should be set       */
+/*                 to NULL if 'size' is 0, of in case of error..          */
+/*                                                                        */
+/* <Return>                                                               */
+/*    FreeType error code. 0 means success.                               */
+/*                                                                        */
+/**************************************************************************/
+
+  BASE_FUNC
+  FT_Error  FT_Alloc( FT_System  system,
+                      long       size, 
+                      void*     *P ) 
+  {
+  
+    if (!P)
+    {
+      PERROR(( "FT_Alloc : invalid pointer address !!\n" ));
+      return FT_Err_Invalid_Argument;
+    }
+    
+    if ( size > 0 )
+    {
+      *P = malloc( size );
+      if ( !*P )
+      {
+        PERROR(( "FT_Alloc : out of memory (%ld bytes requested) !!\n",
+                 size ));
+
+        return FT_Err_Out_Of_Memory;
+      }
+
+      system->total_alloc += size;
+
+      /* ALWAYS ZERO-FILL THE BLOCK !!!!! */   
+      MEM_Set( *P, 0, size );
+    }
+    else
+      *P = NULL;
+
+    PTRACE2(( "FT_Alloc : size = %ld, pointer = 0x%08lx, block = 0x%08lx\n",
+              size, (long)P, (long)*P ));
+
+    return FT_Err_Ok;
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> FT_Realloc                                                  */
+/*                                                                        */
+/* <Description>                                                          */
+/*    Reallocates a block of memory pointed to by '*P' to 'Size'          */
+/*    bytes from the hea^, possibly changing '*P'.                        */
+/*                                                                        */
+/* <Input>                                                                */
+/*    system    :: handle to a given 'system object' where allocation     */
+/*                 occurs..                                               */
+/*                                                                        */
+/*    size      :: size in bytes of the block to allocate                 */
+/*                                                                        */
+/* <InOut>                                                                */
+/*    P         :: pointer to the fresh new block. It should be set       */
+/*                 to NULL if 'size' is 0, of in case of error..          */
+/*                                                                        */
+/* <Return>                                                               */
+/*    FreeType error code. 0 means success.                               */
+/*                                                                        */
+
+  BASE_FUNC
+  int  FT_Realloc( FT_System  system,
+                   long       size, 
+                   void*     *P )
+  {
+    void*  Q;
+    
+    if (!P)
+    {
+      PERROR(( "FT_Realloc : invalid pointer address !!\n" ));
+      return FT_Err_Invalid_Argument;
+    }
+
+    /* if the original pointer is NULL, call FT_Alloc */    
+    if (!*P)
+      return FT_Alloc( system, size, P );
+
+    /* if the new block if zero-sized, clear the current one */    
+    if (size <= 0)
+      return FT_Free( system, P );
+    
+    Q = (void*)realloc( *P, size );
+    if (!Q)
+    {
+      PERROR(( "FT_Realloc : reallocation failed\n" ));
+      return FT_Err_Out_Of_Memory;
+    }
+
+    *P = Q;    
+    return FT_Err_Ok;
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> FT_Free                                                     */
+/*                                                                        */
+/* <Description>                                                          */
+/*    Releases a given block of memory allocated through FT_Alloc         */
+/*                                                                        */
+/* <Input>                                                                */
+/*    system    :: handle to a given 'system object' where allocation     */
+/*                 occured..                                              */
+/*                                                                        */
+/*    P         :: This is the _address_ of a _pointer_ which points to   */
+/*                 the allocated block. It is always set to NULL on exit  */
+/*                                                                        */
+/* <Return>                                                               */
+/*    FreeType error code. 0 means success.                               */
+/*                                                                        */
+/* <Note>                                                                 */
+/*    If P or *P are NULL, this function should return successfuly. This  */
+/*    is a strong convention within all of FreeType and its drivers..     */
+/*                                                                        */
+
+  BASE_FUNC
+  FT_Error  FT_Free( FT_System  system,
+                     void*     *P )
+  {
+    (void)system;  /* unused parameter. Gets rid of warnings */
+
+    PTRACE2(( "FT_Free : freeing pointer 0x%08lx (block 0x%08lx)\n",
+              (long)P, (P ? (long)*P : -1) ));
+
+    if ( !P || !*P )
+      return FT_Err_Ok;
+
+    free( *P );
+    *P = NULL;
+
+    return FT_Err_Ok;
+  }
+
+/**************************************************************************/
+/*                                                                        */
+/*                       SYNCHRONIZATION MANAGEMENT                       */
+/*                                                                        */
+/*                                                                        */
+/*   This section deals with mutexes. The library can be compiled to      */
+/*   three distinct thread-support levels ( namely single-threaded,       */
+/*   thread-safe and re-entrant modes ).                                  */
+/*                                                                        */
+/*   It protects its variables through the MUTEX_Lock and MUTEX_Release   */
+/*   macros which are void in single-threaded mode.                       */
+/*                                                                        */
+/*                                                                        */
+/*   It defines a type-less mutex reference type, "TMutex", that you're   */
+/*   free to redefine for your system's needs..                           */
+/*                                                                        */
+/*   The default implementation of ftsys.c contains only dummy functions  */
+/*   which always return succesfully. you NEED to specialize them in      */
+/*   order to port ftsys.c in any multi-threaded environment...           */
+/*                                                                        */
+
+/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
+/* parameter of the PTRACE and PERROR macros, used to print/log    */
+/* messages during execution..                                     */
+/*                                                                 */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_sync
+
+#ifdef FT_CONFIG_THREADS
+
+
+  BASE_FUNC
+  FT_Error  FT_Mutex_Create ( FT_System  system,
+                              TMutex*    mutex )
+  {
+    (void)system;  /* unused parameter. Gets rid of warnings */
+    
+    mutex = (void*)-1;
+    system->num_mutexes++;
+    return FT_Err_Ok;
+    /* Replace this line with your own mutex creation code */
+  }
+
+
+  BASE_FUNC
+  void  FT_Mutex_Delete ( FT_System  system,
+                          TMutex*    mutex )
+  {
+    (void)system; /* unused parameter. Gets rid of warnings */
+    
+    mutex = (void*)0;
+    system->num_mutexes--;
+    /* Replace this line with your own mutex destruction code */
+  }
+
+  BASE_FUNC
+  void  FT_Mutex_Lock   ( FT_System  system,
+                          TMutex*    mutex )
+  {
+    /* NOTE: It is legal to call this function with a NULL argument */
+    /*       in which case an immediate return is appropriate.      */
+    (void)system; /* unused parameter. Gets rid of warnings */
+    
+    if ( !mutex )
+      return;
+
+    ; /* Insert your own mutex locking code here */
+  }
+
+
+  void  FT_Mutex_Release( FT_System  system,
+                          TMutex*  mutex )
+  {
+    /* NOTE: It is legal to call this function with a NULL argument */
+    /*       in which case an immediate return is appropriate       */
+    (void)system; /* unused parameter. Gets rid of warnings */
+    
+    if ( !mutex )
+      return;
+    ; /* Insert your own mutex release code here */
+  }
+
+#endif /* FT_CONFIG_THREADS */
+
+
+
+
+  EXPORT_FUNC
+  FT_Error  FT_New_System( FT_System*  system )
+  {
+    *system = (FT_System)malloc( sizeof(FT_SystemRec) );
+    if ( !*system )
+      return FT_Err_Out_Of_Memory;
+
+    /* the ANSI function 'free' is unable to  return the number   */
+    /* of released bytes. Hence, the 'current_alloc' field of the */
+    /* system object cannot be used                               */
+    
+    (*system)->system_flags = FT_SYSTEM_FLAG_TOTAL_ALLOC |
+                              FT_SYSTEM_FLAG_MUTEXES;
+    (*system)->total_alloc = 0;
+    (*system)->num_mutexes = 0;
+
+    /* initialise i/o management (nothing) */
+    
+    /* initialise synchronisation (nothing) */
+    
+    /* initialise streams */
+
+    return FT_Err_Ok;
+  }
+
+
+
+  EXPORT_FUNC
+  FT_Error  FT_Done_System( FT_System  system )
+  {
+    /* finalise syncrhonisation (nothing) */
+    
+    /* finalise i/o management (nothing)  */
+    
+    /* finalise memory management         */
+    free( system );
+
+    return FT_Err_Ok;
+  }
+
diff --git a/config/unix/ftsystem.c b/config/unix/ftsystem.c
new file mode 100644
index 0000000..0f02910
--- /dev/null
+++ b/config/unix/ftsystem.c
@@ -0,0 +1,277 @@
+/**************************************************************************
+ *
+ *  ftsystem.h                                                        1.0
+ *
+ *    Unix-specific FreeType low-level system interface
+ *
+ *    This file contains the definition of interface used by FreeType
+ *    to access low-level, i.e. memory management, i/o access as well
+ *    as thread synchronisation.              
+ *
+ *
+ *  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 <ftsystem.h>
+#include <fterrors.h>
+#include <ftconfig.h>
+#include <ftdebug.h>
+
+/* Memory-mapping includes and definitions..                            */
+/*                                                                      */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sys/mman.h>
+#ifndef MAP_FILE
+#define MAP_FILE  0x00
+#endif
+
+/*
+ * The prototype for munmap() is not provided on SunOS.  This needs to
+ * have a check added later to see if the GNU C library is being used.
+ * If so, then this prototype is not needed.
+ */
+#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
+  extern int  munmap( caddr_t  addr, int  len );
+#endif
+
+#include <sys/stat.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                       MEMORY MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Alloc_Func
+ *
+ * <Description>
+ *    The memory allocator function type
+ *
+ * <Input>
+ *    system    :: pointer to the system object
+ *    size      :: requested size in bytes
+ *
+ * <Output>
+ *    block     :: address of newly allocated block
+ *
+ * <Return>  
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    If your allocation routine ALWAYS zeroes the new block, you
+ *    should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ *    object 'flags' field.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_alloc( FT_Memory  memory,
+                   long       size )
+  {
+    (void)memory;
+    return malloc(size);
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Realloc_Func
+ *
+ * <Description>
+ *    The memory reallocator function type
+ *
+ * <Input>
+ *    system   :: pointer to the system object
+ *    new_size :: new requested size in bytes
+ *
+ * <InOut>
+ *    block    :: address of block in memory
+ *
+ * <Return>
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    This function is _never_ called when the system flag 
+ *    FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ *    realloc through "alloc" and "free".
+ *
+ *    Note that this is possible due to the fact that FreeType's
+ *    "FT_Realloc" always requests the _current_ size of the reallocated
+ *    block as a parameter, thus avoiding memory leaks.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_realloc( FT_Memory  memory,
+                     long       cur_size,
+                     long       new_size,
+                     void*      block )
+  {
+    (void)memory;
+    (void)cur_size;
+
+    return realloc( block, new_size );
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Free_Func
+ *
+ * <Description>
+ *    The memory release function type
+ *
+ * <Input>
+ *    system  :: pointer to the system object
+ *    block   :: address of block in memory
+ *
+ * <Note>
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void  ft_free( FT_Memory  memory,
+                 void*      block )
+  {
+    (void)memory;
+    free( block );
+  }
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                     RESOURCE MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+/* We use the macro STREAM_File as a convenience to extract the      */
+/* system-specific stream handle from a given FreeType stream object */
+#define STREAM_File(stream)  ((void*)stream->descriptor.pointer)
+
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_io
+
+  static
+  void  ft_close_stream( FT_Stream  stream )
+  {
+    munmap ( stream->descriptor.pointer, stream->size );
+        
+    stream->descriptor.pointer = NULL;
+    stream->size               = 0;
+    stream->base               = 0;
+  }
+
+
+  extern
+  int  FT_New_Stream( const char*  filepathname,
+                      FT_Stream    stream )
+  {
+    int          file;
+    struct stat  stat_buf;
+
+    /* open the file */
+    file = open( filepathname, O_RDONLY );
+    if (file < 0)
+    {
+      FT_ERROR(( "FT.Unix.Open:" ));
+      FT_ERROR(( " could not open '%s'\n", filepathname ));
+      return FT_Err_Cannot_Open_Stream;
+    }
+
+    if (fstat( file, &stat_buf ) < 0)
+    {
+      FT_ERROR(( "FT.Unix.Open:" ));
+      FT_ERROR(( " could not 'fstat' file '%s'\n", filepathname ));
+      goto Fail_Map;
+    }
+      
+    stream->size     = stat_buf.st_size;
+    stream->pos      = 0;
+    stream->base     = mmap( NULL,
+                             stream->size,
+                             PROT_READ,
+                             MAP_FILE | MAP_PRIVATE,
+                             file,
+                             0 );
+
+    if ( (long)stream->base == -1 )
+    {
+      FT_ERROR(( "FT.Unix.Open:" ));
+      FT_ERROR(( " Could not map file '%s'\n", filepathname ));
+      goto Fail_Map;
+    }
+
+    close(file);
+
+    stream->descriptor.pointer = stream->base;
+    stream->pathname.pointer   = (char*)filepathname;
+    
+    stream->close = ft_close_stream;
+    stream->read  = 0;
+    
+    FT_TRACE1(( "FT.Unix.Open:" ));
+    FT_TRACE1(( " opened '%s' (%d bytes) succesfully\n",
+                filepathname, stream->size ));
+
+    return FT_Err_Ok;
+    
+  Fail_Map:
+    close(file);
+    stream->base      = NULL;
+    stream->size      = 0;
+    stream->pos       = 0;
+    
+    return FT_Err_Cannot_Open_Stream;
+  }
+
+
+  extern
+  FT_Memory  FT_New_Memory( void )
+  {
+    FT_Memory  memory;
+    
+    memory = (FT_Memory)malloc( sizeof(*memory) );
+    if (memory)
+    {
+      memory->user    = 0;
+      memory->alloc   = ft_alloc;
+      memory->realloc = ft_realloc;
+      memory->free    = ft_free;
+    }
+    return memory;
+  }
+
diff --git a/config/win32/Makefile.gcc b/config/win32/Makefile.gcc
new file mode 100644
index 0000000..b81a5c6
--- /dev/null
+++ b/config/win32/Makefile.gcc
@@ -0,0 +1,179 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for Unix + gcc
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE   := del
+SEP      := /
+BUILD    := $(TOP)/config/win32
+PLATFORM := win32
+CC       := gcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)/obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := o
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := a
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := libfreetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -l
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - beware, there is a space after the 'o' !!
+#
+#
+T := -o 
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g -O6 -Wall
+endif
+
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+# Librarian to use to build the static library
+#
+FT_LIBRARIAN := $(AR) -r
+
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	-$(DELETE) $@
+	$(FT_LIBRARIAN) $@ $(OBJECTS_LIST)
+
+endif
+
diff --git a/config/win32/Makefile.lcc b/config/win32/Makefile.lcc
new file mode 100644
index 0000000..d2cd03d
--- /dev/null
+++ b/config/win32/Makefile.lcc
@@ -0,0 +1,180 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for Unix + gcc
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+ifndef TOP
+TOP := .
+endif
+
+DELETE   := del
+SEP      := /
+BUILD    := $(TOP)$(SEP)config$(SEP)win32
+PLATFORM := win32
+CC       := lcc
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)$(SEP)obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := obj
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := lib
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := freetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := -I
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := -D
+
+
+# Target flag - LCC uses "-Fo" instead of "-o ", what a broken compiler
+#
+#
+T := -Fo
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := -Fl
+
+
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := -c -g2 -O
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+# The LCC-Win32 Librarian, called LCCLIB needs all object files in the current
+# directory. That _is_ stupid, but we'll have to deal with it..
+#
+
+DIR_OBJ := $(subst /,\\,$(OBJ_DIR))
+
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	@$(TOP)/config/win32/lcclib.bat
+
+endif
+
+
diff --git a/config/win32/Makefile.vcc b/config/win32/Makefile.vcc
new file mode 100644
index 0000000..eb251c6
--- /dev/null
+++ b/config/win32/Makefile.vcc
@@ -0,0 +1,174 @@
+#*******************************************************************
+#*
+#*  FreeType 2 Configuration rules for Visual C++ on Win32
+#*
+#*  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.
+#*
+#*
+#*  The purpose of this sub-Makefile is to define various build and
+#*  platform specific variables before including the sub-Makefile
+#*  containing the FreeType library rules, found in
+#*
+#*     $(TOP)/config/freetype.mk
+#*
+#*  The following variables must be defined before including this
+#*  file :
+#*
+#*     TOP          Pathname to the top of the FreeType sources
+#*                  hierarchy
+#*
+#*  This file should define the following variables before including
+#*  the FreeType library rules file :
+#*
+#*     BUILD        Pathname to the platform-specific files used
+#*                  for the build. Usually `$(TOP)/config/<system>'
+#*
+#*     SEP          Directory separator for the current platform.
+#*                  Either / or \ (maybe : on Macs)
+#* 
+#*     DELETE       The forced remove/delete command to erase one or more
+#*                  files
+#*
+#*     INCLUDE      The location of all public header files. e.g.
+#*                  `$(TOP)/include'include'                                      *
+#*                                                                          
+#*     SRC          The directory containing all sources. e.g.              
+#*                  '$(TOP)/src'                                           
+#*                                                                           
+#*     OBJ_DIR      The location where compiled object files will be         
+#*                  placed, e.g. '$(TOP)/obj'                              
+#*                                                                           
+#*     LIB_DIR      The location where the resulting library file will be    
+#*                  placed, e.g. '$(TOP)/obj'                        
+#*                                                                           
+#*     LIBRARY      The filename of the resulting library file, without      
+#*                  its extension.. e.g. 'libfreetype' or 'freetype'         
+#*                                                                           
+#*     O            The object file suffix.  Can be '.o', '.obj,' '.lo,'     
+#*                  ';coff,' etc.                                            
+#*                                                                           
+#*     A            The library file suffix.  Can be '.a' '.so,' '.lib'      
+#*                  '.dll,' etc.                                             
+#*                                                                           
+#*     I            The path inclusion flag.  Some compilers use a           
+#*                  different flag than '-I' to specify an additional        
+#*                  include path.  Examples are '/i=' or '-J ', etc.         
+#*                                                                           
+#*     D            The macro definition flag.  I haven't met compilers      
+#*                  which don't use the '-D' switch to define a macro, but   
+#*                  who knows...                                             
+#*                                                                           
+#*     T            The compilation flag used to identify the target. Some   
+#*                  compilers use a different flag than '-o ' to specify     
+#*                  the name of the target object file.                      
+#*                                                                           
+#*     CFLAGS       The set of flags used to compile object files.
+#*                  (usually contains the flag '-c').
+#*                                                                           
+#*
+#*
+#*******************************************************************
+
+DELETE   := del
+SEP      := /
+BUILD    := $(TOP)$(SEP)config$(SEP)win32
+PLATFORM := win32
+CC       := cl
+
+# the directory where all object files are placed
+#
+OBJ_DIR := $(TOP)$(SEP)obj
+
+
+# the directory where all library files are placed
+#
+#  by default, this is the same as OBJ_DIR, however, this can be
+#  changed to suit particular needs..
+#
+LIB_DIR := $(OBJ_DIR)
+
+
+# the object file extension, this can be .o, .tco, .obj, etc..
+# depending on the platform
+#
+O := obj
+
+# the library file extension, this can be .a, .lib, etc..
+# depending on the platform
+#
+A := lib
+
+
+# The name of the final library file.
+# Note that the DOS-specific Makefile uses a shorter (8.3) name
+#
+LIBRARY := freetype
+
+
+# path inclusion flag.
+#
+#  Some compilers use a different flag than '-I' to specify an
+#  additional include path. Examples are "/i=" or "-J", etc...
+#
+I := /I
+
+
+# The link flag used to specify a given library file on link.
+# Note that this is only used to compile the demo programs, not
+# the library itself.
+#
+L := /Fl
+
+
+# C flag used to define a macro before the compilation of a given
+# source object. Usually is '-D' like in "-DDEBUG"
+#
+D := /D
+
+# Target flag - LCC uses "-Fo" instead of "-o ", what a broken compiler
+#
+#
+T := /Fo
+
+# C flags
+#
+#   These should concern :
+#
+#     - debug output
+#     - optimization
+#     - warnings
+#     - ansi compliance..
+#
+ifndef CFLAGS
+CFLAGS := /nologo /c /Ox /G5 /Za /W3 /WX
+endif
+
+ifdef BUILD_FREETYPE
+
+include $(TOP)/config/freetype.mk
+
+# This final rule is used to link all object files into a single
+# library. It is part of the system-specific sub-Makefile because not
+# all librarians accept a simple syntax like :
+#
+#    librarian library_file {list of object files} 
+#
+# The LCC-Win32 Librarian, called LCCLIB needs all object files in the current
+# directory. That _is_ stupid, but we'll have to deal with it..
+#
+
+DIR_OBJ := $(subst /,\\,$(OBJ_DIR))
+
+$(FT_LIBRARY): $(OBJECTS_LIST)
+	lib /out:$@ $(OBJECTS_LIST)
+
+endif
+
+
diff --git a/config/win32/detect.mk b/config/win32/detect.mk
new file mode 100644
index 0000000..3385ab6
--- /dev/null
+++ b/config/win32/detect.mk
@@ -0,0 +1,66 @@
+#
+# This file is used to detect a Win32 host platform.
+#
+# This configuration file to be used depends on the value of the CC
+# environment variable.
+#
+#
+
+# We test for the COMSPEC environment variable, then run the 'ver'
+# command-line program to see if its output contains the word "Windows"
+#
+# If this is true, we're running a win32 platform (or an emulation)
+#
+
+ifeq ($(PLATFORM),ansi)
+ifdef COMSPEC
+
+is_windows := $(findstring Windows,$(strip $(shell ver)))
+ifneq ($(is_windows),)
+
+PLATFORM := win32
+DELETE   := del
+COPY     := copy
+
+CONFIG_FILE := Makefile.gcc  # gcc Makefile by default - aren't we biased ;-)
+SEP         := /
+ifeq ($(CC),cc)
+CC          := gcc
+endif
+
+ifneq ($(findstring visualc,$(MAKECMDGOALS)),)     # Visual C/C++
+CONFIG_FILE := Makefile.vcc
+SEP         := $(BACKSLASH)
+CC          := cl
+visualc: setup
+endif
+
+ifneq ($(findstring watcom,$(MAKECMDGOALS)),)      # Watcom C/C++
+CONFIG_FILE := Makefile.wat
+SEP         := $(BACKSLASH)
+CC          := wcc386
+watcom: setup
+endif
+
+ifneq ($(findstring visualage,$(MAKECMDGOALS)),)   # Visual Age C++
+CONFIG_FILE := Makefile.icc
+SEP         := $(BACKSLASH)
+CC          := icc
+visualage: setup
+endif
+
+ifneq ($(findstring lcc,$(MAKECMDGOALS)),)         # LCC-Win32
+CONFIG_FILE := Makefile.lcc
+SEP         := $(BACKSLASH)
+CC          := lcc
+lcc: setup
+endif
+
+CONFIG_RULES := $(TOP)\config\win32\$(CONFIG_FILE)
+
+setup: dos_setup
+
+endif #test Windows
+endif #test COMSPEC
+endif #test PLATFORM
+
diff --git a/config/win32/ftconfig.h b/config/win32/ftconfig.h
new file mode 100644
index 0000000..43a4c95
--- /dev/null
+++ b/config/win32/ftconfig.h
@@ -0,0 +1,182 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftconfig.h                                                             */
+/*                                                                         */
+/*    ANSI-specific configuration file (specification only).               */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This header file contains a number of macro definitions that are used */
+  /* by the rest of the engine.  Porters are free to copy this file and    */
+  /* adapt it to suit their own system.                                    */
+  /*                                                                       */
+  /* IMPORTANT NOTE:                                                       */
+  /*                                                                       */
+  /*    Porters, read carefully the comments in `ftsys.h' before trying to */
+  /*    port this file to your system.  It contains many essential         */
+  /*    remarks, and will ease your work greatly.                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef FTCONFIG_H
+#define FTCONFIG_H
+
+/* Include the header file containing all developer build options */
+#include <ftoption.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled to suit a specific system.  The current   */
+  /* ones are defaults used to compile FreeType in an ANSI C environment   */
+  /* (16bit compilers are also supported).  Copy this file to your own     */
+  /* `freetype/arch/<system>'  directory, and edit it to port the engine.  */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+/* Define to empty if the keyword does not work.  */
+/* #undef const */
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* We use <limits.h> values to know the sizes of the types.  */
+#include <limits.h>
+
+/* The number of bytes in an `int' type.  */
+#if   UINT_MAX == 0xFFFFFFFF
+#define SIZEOF_INT  4
+#elif UINT_MAX == 0xFFFF
+#define SIZEOF_INT  2
+#elif UINT_MAX > 0xFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_INT  8
+#else
+#error "Unsupported number of bytes in `int' type!"
+#endif
+
+/* The number of bytes in a `long' type.  */
+#if   ULONG_MAX == 0xFFFFFFFF
+#define SIZEOF_LONG  4
+#elif ULONG_MAX > 0xFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
+#define SIZEOF_LONG  8
+#else
+#error "Unsupported number of bytes in `long' type!"
+#endif
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 0
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 0
+
+
+/* Preferred alignment of data */
+#define FT_ALIGNMENT  8
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                     AUTOMATIC CONFIGURATION MACROS                    */
+  /*                                                                       */
+  /*  These macros are computed from the ones defined above.  Don't touch  */
+  /*  their definition, unless you know precisely what you're doing.  No   */
+  /*  porter should need to mess with them.                                */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* IntN types                                                            */
+  /*                                                                       */
+  /*   Used to guarantee the size of some specific integers.               */
+  /*                                                                       */
+  typedef signed short    FT_Int16;
+  typedef unsigned short  FT_Word16;
+
+#if SIZEOF_INT == 4
+
+  typedef signed int      FT_Int32;
+  typedef unsigned int    FT_Word32;
+
+#elif SIZEOF_LONG == 4
+
+  typedef signed long     FT_Int32;
+  typedef unsigned long   FT_Word32;
+
+#else
+#error "no 32bit type found - please check your configuration files"
+#endif
+
+#if SIZEOF_LONG == 8
+
+  /* LONG64 must be defined when a 64-bit type is available */
+#define LONG64
+#define INT64   long
+
+#else
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI 'long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro in `ftconfig.h'.  Note  */
+  /* that this will produce many -ansi warnings during library             */
+  /* compilation.                                                          */
+  /*                                                                       */
+#ifdef FTCALC_USE_LONG_LONG
+
+#define LONG64
+#define INT64   long long
+
+#endif /* FTCALC_USE_LONG_LONG */
+#endif
+
+
+#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
+#define  LOCAL_DEF   static
+#define  LOCAL_FUNC  static
+#else
+#define  LOCAL_DEF   extern
+#define  LOCAL_FUNC  /* nothing */
+#endif
+
+#ifdef FT_MAKE_OPTION_SINGLE_LIBRARY_OBJECT
+#define  BASE_DEF    LOCAL_DEF
+#define  BASE_FUNC   LOCAL_FUNC
+#else
+#define  BASE_DEF    extern
+#define  BASE_FUNC   /* nothing */
+#endif
+
+#ifndef  EXPORT_DEF
+#define  EXPORT_DEF   extern
+#endif
+
+#ifndef  EXPORT_FUNC
+#define  EXPORT_FUNC  /* nothing */
+#endif
+
+#endif /* FTCONFIG_H */
+
+
+/* END */
diff --git a/config/win32/ftoption.h b/config/win32/ftoption.h
new file mode 100644
index 0000000..852f65f
--- /dev/null
+++ b/config/win32/ftoption.h
@@ -0,0 +1,162 @@
+#ifndef FTOPTION_H
+#define FTOPTION_H
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
+  /*                                                                       */
+  /* These macros can be toggled by developers to enable or disable        */
+  /* certain aspects of FreeType.  This file contains macros that apply to */
+  /* all of FreeType.  Driver-specific configurations are placed in each   */
+  /* driver directory (e.g. `freetype/drivers/ttlib/ttconfig.h').          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Alternate Glyph Image Format support                                  */
+  /*                                                                       */
+  /*   By default, the glyph images returned by the FreeType glyph loader  */
+  /*   can either be a pixmap or a vectorial outline defined through       */
+  /*   bezier control points. When defining the following configuration    */
+  /*   macro, some font drivers will be able to register alternate         */
+  /*   glyph image formats.                                                */
+  /*                                                                       */
+  /*   Unset this macro if you're sure that you'll never use a font driver */
+  /*   with an alternate glyph format, this will reduce the size of the    */
+  /*   base layer code.                                                    */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GCC provides the non-ANSI `long long' 64-bit type.  You can activate  */
+  /* it by defining the FTCALC_USE_LONG_LONG macro here.  Note however     */
+  /* that we did not experience any improvement in speed with gcc, and     */
+  /* that the final code seems bigger when linked.                         */
+  /*                                                                       */
+#undef FTCALC_USE_LONG_LONG
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* When compiling FreeType as a DLL, some systems/compilers need a       */
+  /* special keyword in front of each function definition instead of       */
+  /* `extern'.                                                             */
+  /*                                                                       */
+  /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define         */
+  /* exported library function interfaces and exported library functions   */
+  /* implementations respectively.                                         */
+  /*                                                                       */
+  /* If not defined here, they automatically default to `extern' and void  */
+  /* later in this header file.                                            */
+  /*                                                                       */
+#undef EXPORT_DEF
+#undef EXPORT_FUNC
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Debug level                                                           */
+  /*                                                                       */
+  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
+  /*   errors are reported through the `ftdebug' component.  In trace      */
+  /*   mode, additional messages are sent to the standard output during    */
+  /*   execution.                                                          */
+  /*                                                                       */
+  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
+  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
+  /*                                                                       */
+  /*   Don't define any of these macros to compile in `release' mode.      */
+  /*                                                                       */
+#undef  FT_DEBUG_LEVEL_ERROR
+#undef  FT_DEBUG_LEVEL_TRACE
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Anti-aliasing support                                                 */
+  /*                                                                       */
+  /*   Undefine this macro only if you want to disable the anti-aliasing   */
+  /*   support in FreeType.  This will save you about 5 Kb of code.  It    */
+  /*   may be important for some embedded systems.                         */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_ANTI_ALIAS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Endianess performance improvement                                     */
+  /*                                                                       */
+  /*   FreeType is completely endian-independent, and can thus be compiled */
+  /*   directly on _any_ machine.  However, some components of the library */
+  /*   provide improved routines for the cases where endianess is known.   */
+  /*                                                                       */
+  /*   It usually results in speed-ups and reduced code size.  Note that   */
+  /*   you should not define both of these macros.                         */
+  /*                                                                       */
+  /*                                                                       */
+  /*   NOTE: For now, only the scan-line converter (base/ftraster.c) uses  */
+  /*         these macros to speed-up some anti-alias rendering routines.  */
+  /*                                                                       */
+#undef  FT_CONFIG_OPTION_LITTLE_ENDIAN
+#undef  FT_CONFIG_OPTION_BIG_ENDIAN
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define this configuration macro whenever you want to build a version  */
+  /* of FreeType that does not include a default `system' component.       */
+  /*                                                                       */
+  /* Note that this will prevent the compilation of `ftinit', hence the    */
+  /* function FT_Init_FreeType                                             */
+  /*                                                                       */
+#undef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    The size in bytes of the render pool used by the scan-line         */
+  /*    converter to do all of its work.                                   */
+  /*                                                                       */
+  /*    This must be greater than 4 Kb                                     */
+  /*                                                                       */
+#define FT_RENDER_POOL_SIZE   32768
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_DRIVERS                                                     */
+  /*                                                                       */
+  /*    The maximum number of font drivers that can be registered in a     */
+  /*    single FreeType library object.  8 seems to be a good choice due   */
+  /*    to the relative low actual number of drivers ;-)                   */
+  /*                                                                       */
+#define FT_MAX_DRIVERS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_EXTENSIONS                                                  */
+  /*                                                                       */
+  /*    The maximum number of extensions that can be registered in a       */
+  /*    single font driver. 8 seems to be a good choice for now..          */
+  /*                                                                       */
+#define FT_MAX_EXTENSIONS  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*    FT_MAX_GLYPH_FORMATS                                               */
+  /*                                                                       */
+  /*    The maximum number of glyph image formats that might be registered */
+  /*    in a given library instance. 8 seems to be a good choice due to    */
+  /*    the relatively low number of current formats ;-)                   */
+  /*                                                                       */
+
+#define FT_MAX_GLYPH_FORMATS  8
+
+
+
+#endif /* FTOPTION_H */
diff --git a/config/win32/ftsystem.c b/config/win32/ftsystem.c
new file mode 100644
index 0000000..459f668
--- /dev/null
+++ b/config/win32/ftsystem.c
@@ -0,0 +1,214 @@
+/**************************************************************************
+ *
+ *  ftsystem.h                                                        1.0
+ *
+ *    ANSI-specific FreeType low-level system interface
+ *
+ *    This file contains the definition of interface used by FreeType
+ *    to access low-level, i.e. memory management, i/o access as well
+ *    as thread synchronisation.              
+ *
+ *
+ *  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 <ftsystem.h>
+#include <fterrors.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                       MEMORY MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Alloc_Func
+ *
+ * <Description>
+ *    The memory allocator function type
+ *
+ * <Input>
+ *    system    :: pointer to the system object
+ *    size      :: requested size in bytes
+ *
+ * <Output>
+ *    block     :: address of newly allocated block
+ *
+ * <Return>  
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    If your allocation routine ALWAYS zeroes the new block, you
+ *    should set the flag FT_SYSTEM_FLAG_ALLOC_ZEROES in your system
+ *    object 'flags' field.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_alloc( FT_Memory  memory,
+                   long       size )
+  {
+    (void)memory;
+    return malloc(size);
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Realloc_Func
+ *
+ * <Description>
+ *    The memory reallocator function type
+ *
+ * <Input>
+ *    system   :: pointer to the system object
+ *    new_size :: new requested size in bytes
+ *
+ * <InOut>
+ *    block    :: address of block in memory
+ *
+ * <Return>
+ *    Error code. 0 means success.
+ *
+ * <Note>
+ *    This function is _never_ called when the system flag 
+ *    FT_SYSTEM_FLAG_NO_REALLOC is set. Instead, the engine will emulate
+ *    realloc through "alloc" and "free".
+ *
+ *    Note that this is possible due to the fact that FreeType's
+ *    "FT_Realloc" always requests the _current_ size of the reallocated
+ *    block as a parameter, thus avoiding memory leaks.
+ *
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void*  ft_realloc( FT_Memory  memory,
+                     long       cur_size,
+                     long       new_size,
+                     void*      block )
+  {
+    (void)memory;
+    (void)cur_size;
+
+    return realloc( block, new_size );
+  }
+
+
+/************************************************************************
+ *
+ * <FuncType>
+ *    FT_Free_Func
+ *
+ * <Description>
+ *    The memory release function type
+ *
+ * <Input>
+ *    system  :: pointer to the system object
+ *    block   :: address of block in memory
+ *
+ * <Note>
+ *    If you have set the flag FT_SYSTEM_FLAG_REPORT_CURRENT_ALLOC in
+ *    your system's "system_flags" field, this function should update
+ *    the "current_alloc" field of the system object.
+ *
+ ************************************************************************/
+
+  static
+  void  ft_free( FT_Memory  memory,
+                 void*      block )
+  {
+    (void)memory;
+    free( block );
+  }
+
+  /*********************************************************************/
+  /*                                                                   */
+  /*                     RESOURCE MANAGEMENT INTERFACE                 */
+  /*                                                                   */
+
+
+#define STREAM_FILE(stream)  ((FILE*)stream->descriptor.pointer)
+
+  static
+  void  ft_close_stream( FT_Stream  stream )
+  {
+    fclose( STREAM_FILE(stream) );
+  }
+
+  static
+  unsigned long  ft_io_stream( FT_Stream      stream,
+                               unsigned long  offset,
+                               char*          buffer,
+                               unsigned long  count )
+  {
+    FILE*  file;
+    
+    file = STREAM_FILE(stream);
+
+    fseek( file, offset, SEEK_SET );    
+    return (unsigned long)fread( buffer, count, 1, file );
+  }
+
+
+  extern
+  int  FT_New_Stream( const char*  filepathname,
+                      FT_Stream    stream )
+  {
+    FILE*  file;
+    
+    file = fopen( filepathname, "rb" );
+    if (!file)
+      return FT_Err_Cannot_Open_Resource;
+      
+    fseek( file, 0, SEEK_END );
+    stream->size = ftell(file);
+    fseek( file, 0, SEEK_SET );
+    
+    stream->descriptor.pointer = file;
+    stream->pos                = 0;
+    
+    stream->read  = ft_io_stream;
+    stream->close = ft_close_stream;
+
+    return 0;
+  }
+
+
+  extern
+  FT_Memory  FT_New_Memory( void )
+  {
+    FT_Memory  memory;
+    
+    memory = (FT_Memory)malloc( sizeof(*memory) );
+    if (memory)
+    {
+      memory->user    = 0;
+      memory->alloc   = ft_alloc;
+      memory->realloc = ft_realloc;
+      memory->free    = ft_free;
+    }
+    return memory;
+  }
+
diff --git a/config/win32/lcclib.bat b/config/win32/lcclib.bat
new file mode 100644
index 0000000..ac8f51b
--- /dev/null
+++ b/config/win32/lcclib.bat
@@ -0,0 +1,12 @@
+@cd obj
+@LCCLIB /out:freetype.lib *.obj
+@echo The library file `obj/freetype.lib' was generated.
+@exit 0
+
+; the LCC Librarian has many flaws, one of them is that it *requires* that
+; all object files be placed in the current directory. Another flaw is that
+; it cannot accept a long list of object files.
+;
+; this file is used to build the library file `obj/freetype.lib'
+; 
+
diff --git a/demos/Makefile b/demos/Makefile
new file mode 100644
index 0000000..e23d9d1
--- /dev/null
+++ b/demos/Makefile
@@ -0,0 +1,227 @@
+.PHONY: exes
+all: exes
+
+####################################################################
+#
+# TOP is the directory where the main FreeType source is found,
+# as well as the 'config.mk' file
+#
+
+ifndef TOP
+TOP := ..
+endif
+
+####################################################################
+#
+# Check that we have a working `config.mk' in the above directory.
+# If not, issue a warning message, then stop there..
+#
+ifeq ($(wildcard $(TOP)/config.mk),)
+no_config_mk := 1
+endif
+
+ifdef no_config_mk
+
+exes:
+	@echo Please compile the library before the demo programs !!
+
+else
+
+####################################################################
+#
+# Good, now include the `config.mk' in order to know how to build
+# object files from sources, as well as other things (compiler flags)
+#
+include ../config.mk
+
+####################################################################
+#
+# Detect DOS-like platforms, currently DOS, Win 3.1, Win32 & OS/2
+#
+#
+ifneq ($(findstring $(PLATFORM),os2 win16 win32 dos),)
+DOSLIKE := 1
+endif
+
+
+###################################################################
+#
+# Clean-up rules. Because the `del' command on DOS-like platforms
+# cannot take a long list of arguments, we simply erase the directory
+# contents..
+#
+.PHONY: clean  distclean
+
+ifdef DOSLIKE
+clean_demo:
+	-del obj\*.$O
+	-del src\*.bak
+
+distclean_demo: clean_demo
+	-del obj\*.*
+	-del bin\*.exe
+else
+clean_demo:
+	-$(DELETE) $(OBJ_)*.$O
+	-$(DELETE) $(SRC_)*.bak graph$(SEP)*.bak
+	-$(DELETE) $(SRC_)*~ graph$(SEP)*~
+
+
+distclean_demo: clean_demo
+	-$(DELETE) $(BIN_)*
+endif
+
+clean: clean_demo
+distclean: distclean_demo
+
+####################################################################
+#
+# Define a few important variables now
+#
+#
+TOP_ := $(TOP)$(SEP)
+SRC_ := $(TOP)$(SEP)src$(SEP)
+
+BIN_ := bin$(SEP)
+OBJ_ := obj$(SEP)
+
+GRAPH_DIR := graph
+
+SRC_DIR  := src
+SRC_DIR_ := $(SRC_DIR)$(SEP)
+
+
+FT_INCLUDES := $(BUILD) $(TOP_)include $(SRC_)base
+TT_INCLUDES := $(SRC_)shared $(SRC_)truetype
+T1_INCLUDES := $(SRC_)shared $(SRC_)type1
+
+CFLAGS    = -c -O0 -g $(INCLUDES:%=$I%) -Wall -W -ansi
+CC       := $(CC)
+LINK     := $(CC)
+FTLIB    := $(LIB_DIR)$(SEP)$(LIBRARY).$A
+
+
+####################################################################
+#
+# Compute the executable suffix to use, and put it in `E'.
+# It is ".exe" on DOS-ish platforms, and nothing otherwise
+#
+ifdef DOSLIKE
+E := .exe
+else
+E :=
+endif
+
+###################################################################
+#
+# The list of demonstration programs to build.
+#
+EXES := ftlint t1dump ftview fttimer
+
+ifneq ($(findstring $(PLATFORM),os2 unix),)
+EXES += ttdebug
+endif
+
+###################################################################
+#
+# Include the rules needed to compile the graphics sub-system.
+# This will also select which graphics driver to compile to the
+# sub-system..
+#
+include $(GRAPH_DIR)/rules.mk
+
+exes: $(EXES:%=$(BIN_)%$E)
+
+
+INCLUDES := $(FT_INCLUDES)
+
+####################################################################
+#
+# Rules for compiling object files for text-only demos
+#
+
+COMMON_OBJ := $(OBJ_)common.o
+$(COMMON_OBJ): $(SRC_DIR_)common.c
+	$(CC) $(CFLAGS) $T$@ $<
+
+$(OBJ_)%.$O: $(SRC_DIR_)%.c $(FTLIB)
+	$(CC) $(CFLAGS) $T$@ $<
+
+$(OBJ_)ftlint.$O: $(SRC_DIR_)ftlint.c
+	$(CC) $(CFLAGS) $T$@ $<
+
+$(OBJ_)fttry.$O: $(SRC_DIR_)fttry.c
+	$(CC) $(CFLAGS) $T$@ $<
+
+
+$(OBJ_)ftview.$O: $(SRC_DIR_)ftview.c $(GRAPH_LIB)
+	$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
+
+$(OBJ_)fttimer.$O: $(SRC_DIR_)fttimer.c $(GRAPH_LIB)
+	$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
+
+#$(OBJ_)ftsbit.$O: $(SRC_DIR)/ftsbit.c $(GRAPH_LIB)
+#	$(CC) $(CFLAGS) $T$@ $<
+
+
+####################################################################
+#
+# Special rule to compile the `t1dump' program as it includes
+# the Type1 source path
+#
+$(OBJ_)t1dump.$O: $(SRC_DIR)/t1dump.c
+	$(CC) $(CFLAGS) $(T1_INCLUDES:%=$I%) $T$@ $<
+
+
+####################################################################
+#
+# Special rule to compile the `ttdebug' program as it includes
+# the TrueType source path and needs extra flags for correct keyboard
+# handling on Unix
+#
+
+# POSIX TERMIOS: Do not define if you use OLD U*ix like 4.2BSD.
+#
+# detect a Unix system
+ifeq ($(PLATFORM),unix)
+EXTRAFLAGS = $DUNIX $DHAVE_POSIX_TERMIOS
+endif
+
+$(OBJ_)ttdebug.$O: $(SRC_DIR)/ttdebug.c
+	$(CC) $(CFLAGS) $(TT_INCLUDES:%=$I%) $T$@ $< $(EXTRAFLAGS)
+
+
+####################################################################
+#
+# Rules used to link the executables. Note that they could be
+# over-ridden by system-specific things..
+#
+
+$(BIN_)ftlint$E: $(OBJ_)ftlint.$O $(FTLIB)
+	$(LINK) $(LFLAGS) $T$@ $<  $(FTLIB) $(EFENCE)
+
+
+$(BIN_)fttry$E: $(OBJ_)fttry.$O $(FTLIB)
+	$(LINK) $(LFLAGS) $T$@ $<  $(FTLIB) $(EFENCE)
+
+
+$(BIN_)ftsbit$E: $(OBJ_)ftsbit.$O $(FTLIB)
+	$(LINK) $(LFLAGS) $T$@ $<  $(FTLIB) $(EFENCE)
+
+
+$(BIN_)t1dump$E: $(OBJ_)t1dump.$O $(FTLIB)
+	$(LINK)  $(LFLAGS) $T$@ $<  $(FTLIB) $(EFENCE)
+
+$(BIN_)ttdebug$E: $(OBJ_)ttdebug.$O $(FTLIB)
+	$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(EFENCE)
+
+
+$(BIN_)ftview$E: $(OBJ_)ftview.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
+	$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(GRAPH_LINK) $(COMMON_OBJ) $(EFENCE)
+
+$(BIN_)fttimer$E: $(OBJ_)fttimer.$O $(FTLIB) $(GRAPH_LIB) $(COMMON_OBJ)
+	$(LINK) $(LFLAGS) $T$@ $< $(FTLIB) $(GRAPH_LINK) $(EFENCE)
+
+endif
+
+
diff --git a/demos/config/os2/gros2pm.c b/demos/config/os2/gros2pm.c
new file mode 100644
index 0000000..976f58d
--- /dev/null
+++ b/demos/config/os2/gros2pm.c
@@ -0,0 +1,887 @@
+#include "gros2pm.h"
+#include "grdevice.h"
+
+#define INCL_DOS
+#define INCL_WIN
+#define INCL_GPI
+#define INCL_SUB
+
+#include <os2.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+  static void Panic( const char* message )
+  {
+    fprintf( stderr, "%s", message );
+    exit(1);
+  }
+
+  typedef struct Translator
+  {
+    ULONG   os2key;
+    grKey   grkey;
+    
+  } Translator;
+  
+
+  static
+  Translator  key_translators[] =
+  {
+    { VK_BACKSPACE, grKeyBackSpace },
+    { VK_TAB,       grKeyTab       },
+    { VK_ENTER,     grKeyReturn    },
+    { VK_ESC,       grKeyEsc       },
+    { VK_HOME,      grKeyHome      },
+    { VK_LEFT,      grKeyLeft      },
+    { VK_UP,        grKeyUp        },
+    { VK_RIGHT,     grKeyRight     },
+    { VK_DOWN,      grKeyDown      },
+    { VK_PAGEUP,    grKeyPageUp    },
+    { VK_PAGEDOWN,  grKeyPageDown  },
+    { VK_END,       grKeyEnd       },
+    { VK_F1,        grKeyF1        },
+    { VK_F2,        grKeyF2        },
+    { VK_F3,        grKeyF3        },
+    { VK_F4,        grKeyF4        },
+    { VK_F5,        grKeyF5        },
+    { VK_F6,        grKeyF6        },
+    { VK_F7,        grKeyF7        },
+    { VK_F8,        grKeyF8        },
+    { VK_F9,        grKeyF9        },
+    { VK_F10,       grKeyF10       },
+    { VK_F11,       grKeyF11       },
+    { VK_F12,       grKeyF12       }
+  };
+
+
+#define MAX_PIXEL_MODES  32
+
+  static int           num_pixel_modes = 0;
+  static grPixelMode   pixel_modes[ MAX_PIXEL_MODES ];  
+  static int           pixel_depth[ MAX_PIXEL_MODES ];
+
+  static  HAB   gr_anchor;   /* device anchor block */
+
+  typedef POINTL  PMBlitPoints[4];
+
+
+  typedef struct grPMSurface_
+  {
+    grSurface  root;
+    grBitmap   image;
+
+    HAB        anchor;         /* handle to anchor block for surface's window */
+    HWND       frame_window;   /* handle to window's frame                    */
+    HWND       client_window;  /* handle to window's client                   */
+    HWND       title_window;   /* handle to window's title bar                */
+
+    HPS        image_ps;       /* memory presentation space used to hold */
+                               /* the surface's content under PM         */
+    HDC        image_dc;       /* memory device context for the image    */
+
+    HEV        event_lock;     /* semaphore used in listen_surface   */
+    HMTX       image_lock;     /* a mutex used to synchronise access */
+                               /* to the memory presentation space   */
+                               /* used to hold the surface           */
+
+    TID        message_thread; /* thread used to process this surface's */
+                               /* messages..                            */
+
+    PBITMAPINFO2 bitmap_header;/* os/2 bitmap descriptor                   */
+    HBITMAP      os2_bitmap;   /* Handle to OS/2 bitmap contained in image */
+    BOOL         ready;        /* ??? */
+
+    long         shades[256];  /* indices of gray levels in pixel_mode_gray */
+
+    POINTL       surface_blit[4];  /* surface blitting table   */
+    POINTL       magnify_blit[4];  /* magnifier blitting table */
+    int          magnification;    /* level of magnification   */
+    POINTL       magnify_center;
+    SIZEL        magnify_size;
+
+    grEvent      event;
+
+    PMBlitPoints blit_points;
+
+  } grPMSurface;
+
+
+
+  static
+  void  enable_os2_iostreams( void )
+  {
+    PTIB  thread_block;
+    PPIB  process_block;
+
+    /* XXX : This is a very nasty hack, it fools OS/2 and let the program */
+    /*       call PM functions, even though stdin/stdout/stderr are still */
+    /*       directed to the standard i/o streams..                       */
+    /*       The program must be compiled with WINDOWCOMPAT               */
+    /*                                                                    */
+    /*   Credits go to Michal for finding this !!                         */
+    /*                                                                    */
+    DosGetInfoBlocks( &thread_block, &process_block );
+    process_block->pib_ultype = 3;
+  }
+
+
+
+  static
+  int  init_device( void )
+  {
+    enable_os2_iostreams();
+
+    /* create an anchor block. This will allow this thread (i.e. the */
+    /* main one) to call Gpi functions..                             */
+    gr_anchor = WinInitialize(0);
+    if (!gr_anchor)
+    {
+      /* could not initialise Presentation Manager */
+      return -1;
+    }
+
+    return 0;
+  }
+
+
+
+  static
+  void  done_device( void )
+  {
+    /* Indicates that we do not use the Presentation Manager, this */
+    /* will also release all associated resources..                */
+    WinTerminate( gr_anchor );
+  }
+
+
+
+  /* close a given window */
+  static
+  void  done_surface( grPMSurface*  surface )
+  {
+    if ( surface->frame_window )
+      WinDestroyWindow( surface->frame_window );
+
+    WinReleasePS( surface->image_ps );
+
+    grDoneBitmap( &surface->image );
+    grDoneBitmap( &surface->root.bitmap );
+  }
+
+
+
+
+
+  static
+  void add_pixel_mode( grPixelMode  pixel_mode,
+                       int          depth )
+  {
+    if ( num_pixel_modes >= MAX_PIXEL_MODES )
+      Panic( "X11.Too many pixel modes\n" );
+      
+    pixel_modes[ num_pixel_modes ] = pixel_mode;
+    pixel_depth[ num_pixel_modes ] = depth;
+    
+    num_pixel_modes++;
+  }
+
+
+#define LOCK(x)    DosRequestMutexSem( x, SEM_INDEFINITE_WAIT );
+#define UNLOCK(x)  DosReleaseMutexSem( x )
+
+
+  static
+  const int  pixel_mode_bit_count[] =
+  {
+    0,
+    1,   /* mono  */
+    4,   /* pal4  */
+    8,   /* pal8  */
+	8,   /* grays */
+    15,  /* rgb15 */
+    16,  /* rgb16 */
+    24,  /* rgb24 */
+    32   /* rgb32 */
+  };
+
+
+ /************************************************************************
+  *
+  * Technical note : how the OS/2 Presntation Manager driver works
+  *
+  * PM is, in my opinion, a bloated and over-engineered graphics
+  * sub-system, even though it has lots of nice features. Here are
+  * a few tidbits about it :
+  *
+  *
+  * - under PM, a "bitmap" is a device-specific object whose bits are
+  *   not directly accessible to the client application. This means
+  *   that we must use a scheme like the following to display our
+  *   surfaces :
+  *
+  *     - hold, for each surface, its own bitmap buffer where the
+  *       rest of MiGS writes directly.
+  *
+  *     - create a PM bitmap object with the same dimensions (and
+  *       possibly format).
+  *
+  *     - copy the content of each updated rectangle into the
+  *       PM bitmap with the function 'GpiSetBitmapBits'.
+  *
+  *     - finally, "blit" the PM bitmap to the screen calling
+  *       'GpiBlitBlt'
+  *
+  * - but there is more : you cannot directly blit a PM bitmap to the
+  *   screen with PM. The 'GpiBlitBlt' only works with presentation
+  *   spaces. This means that we also need to create, for each surface :
+  *
+  *     - a memory presentation space, used to hold the PM bitmap
+  *     - a "memory device context" for the presentation space
+  *
+  *   The blit is then performed from the memory presentation space
+  *   to the screen's presentation space..
+  *
+  *
+  * - because each surface creates its own event-handling thread,
+  *   we must protect the surface's presentation space from concurrent
+  *   accesses (i.e. calls to 'GpiSetBitmapBits' when drawing to the
+  *   surface, and calls to 'GpiBlitBlt' when drawing it on the screen
+  *   are performed in two different threads).
+  *
+  *   we use a simple mutex to do this.
+  *
+  *
+  * - we also use a semaphore to perform a rendez-vous between the
+  *   main and event-handling threads (needed in "listen_event").
+  *
+  ************************************************************************/
+
+  static
+  void  RunPMWindow( grPMSurface*  surface );
+
+
+
+
+  static
+  void  convert_gray_to_pal8( grPMSurface* surface,
+                              int          x,
+                              int          y,
+                              int          w,
+                              int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    long*      palette = surface->shades;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + w;
+      
+      for ( ; _write < limit; _write++, _read++ )
+        *_write = (byte) palette[ *_read ];
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_16( grPMSurface* surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 2*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    long*           palette = surface->shades;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 2*w;
+      
+      for ( ; _write < limit; _write += 2, _read++ )
+        *(short*)_write = (short)palette[ *_read ];
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_24( grPMSurface* surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 3*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 3*w;
+      
+      for ( ; _write < limit; _write += 3, _read++ )
+      {
+        byte  color = *_read;
+        
+        _write[0] =
+        _write[1] =
+        _write[2] = color;
+      }
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_32( grPMSurface* surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 4*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 4*w;
+      
+      for ( ; _write < limit; _write += 4, _read++ )
+      {
+        byte  color = *_read;
+        
+        _write[0] =
+        _write[1] =
+        _write[2] =
+        _write[3] = color;
+      }
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_rectangle( grPMSurface* surface,
+                           int          x,
+                           int          y,
+                           int          w,
+                           int          h )
+  {
+    int  z;
+    
+    /* first of all, clip to the surface's area */
+    if ( x   >= surface->image.width ||
+         x+w <= 0                    ||
+         y   >= surface->image.rows  ||
+         y+h <= 0 )
+      return;
+ 
+    if ( x < 0 )
+    {
+      w += x;
+      x  = 0;
+    }
+ 
+    z = (x + w) - surface->image.width;
+    if (z > 0)
+      w -= z;
+      
+    z = (y + h) - surface->image.rows;
+    if (z > 0)
+      h -= z;
+      
+    /* convert the rectangle to the target depth for gray surfaces */
+    if (surface->root.bitmap.mode == gr_pixel_mode_gray)
+    {
+      switch (surface->image.mode)
+      {
+        case gr_pixel_mode_pal8  :
+          convert_gray_to_pal8( surface, x, y, w, h );
+          break;
+
+        case gr_pixel_mode_rgb555:
+        case gr_pixel_mode_rgb565:
+          convert_gray_to_16  ( surface, x, y, w, h );
+          break;
+
+        case gr_pixel_mode_rgb24:
+          convert_gray_to_24  ( surface, x, y, w, h );
+          break;
+
+        case gr_pixel_mode_rgb32:
+          convert_gray_to_32  ( surface, x, y, w, h );
+          break;
+
+        default:
+          ;
+      }
+    }
+  } 
+
+
+  static
+  void  refresh_rectangle( grPMSurface* surface,
+                           int          x,
+                           int          y,
+                           int          w,
+                           int          h )
+  {
+    convert_rectangle( surface, x, y, w, h );
+
+    WinInvalidateRect( surface->client_window, NULL, FALSE );
+    WinUpdateWindow( surface->frame_window );
+  }
+
+  
+  static
+  void  set_title( grPMSurface* surface,
+                   const char*  title )
+  {
+    WinSetWindowText( surface->title_window, (PSZ)title );
+  }
+
+
+
+  static  
+  void  listen_event( grPMSurface* surface,
+                      int          event_mask,
+                      grEvent*     grevent )
+  {
+    ULONG  ulRequestCount;
+
+    (void) event_mask;   /* ignored for now */
+
+    /* the listen_event function blocks until there is an event to process */
+    DosWaitEventSem( surface->event_lock, SEM_INDEFINITE_WAIT );
+    DosQueryEventSem( surface->event_lock, &ulRequestCount );
+    *grevent = surface->event;
+    DosResetEventSem( surface->event_lock, &ulRequestCount );
+
+    return;
+  }
+
+
+  static
+  grPMSurface*  init_surface( grPMSurface*  surface,
+                              grBitmap*     bitmap )
+  {
+    PBITMAPINFO2  bit;
+    SIZEL         sizl = { 0, 0 };
+    LONG          palette[256];
+
+    /* create the bitmap - under OS/2, we support all modes as PM */
+    /* handles all conversions automatically..                    */
+    if ( grNewBitmap( bitmap->mode,
+                      bitmap->grays,
+					  bitmap->width,
+					  bitmap->rows,
+                      bitmap ) )
+      return 0;
+
+    surface->root.bitmap = *bitmap;
+
+    /* create the image and event lock */
+    DosCreateEventSem( NULL, &surface->event_lock, 0, TRUE  );
+    DosCreateMutexSem( NULL, &surface->image_lock, 0, FALSE );
+
+    /* create the image's presentation space */
+    surface->image_dc = DevOpenDC( gr_anchor,
+                                   OD_MEMORY, (PSZ)"*", 0L, 0L, 0L );
+
+    surface->image_ps = GpiCreatePS( gr_anchor,
+                                     surface->image_dc,
+                                     &sizl,
+                                     PU_PELS    | GPIT_MICRO |
+                                     GPIA_ASSOC | GPIF_DEFAULT );
+
+    GpiSetBackMix( surface->image_ps, BM_OVERPAINT );
+
+    /* create the image's PM bitmap */
+    bit = (PBITMAPINFO2)grAlloc( sizeof(BITMAPINFO2) + 256*sizeof(RGB2) );
+    surface->bitmap_header = bit;
+
+    bit->cbFix   = sizeof( BITMAPINFOHEADER2 );
+    bit->cx      = surface->root.bitmap.width;
+    bit->cy      = surface->root.bitmap.rows;
+    bit->cPlanes = 1;
+
+    bit->argbColor[0].bBlue  = 0;
+    bit->argbColor[0].bGreen = 0;
+    bit->argbColor[0].bRed   = 0;
+
+    bit->argbColor[1].bBlue  = 255;
+    bit->argbColor[1].bGreen = 255;
+    bit->argbColor[1].bRed   = 255;
+
+    bit->cBitCount = pixel_mode_bit_count[ surface->root.bitmap.mode ];
+
+    surface->os2_bitmap = GpiCreateBitmap( surface->image_ps,
+                                           (PBITMAPINFOHEADER2)bit,
+                                           0L, NULL, NULL );
+
+    GpiSetBitmap( surface->image_ps, surface->os2_bitmap );
+
+    bit->cbFix = sizeof( BITMAPINFOHEADER2 );
+    GpiQueryBitmapInfoHeader( surface->os2_bitmap,
+                              (PBITMAPINFOHEADER2)bit );
+
+    /* for gr_pixel_mode_gray, create a gray-levels logical palette */
+    if ( bitmap->mode == gr_pixel_mode_gray )
+    {
+      int     x, count;
+
+      count = bitmap->grays;
+      for ( x = 0; x < count; x++ )
+        palette[x] = (((count-x)*255)/count) * 0x010101;
+
+      /* create logical color table */
+      GpiCreateLogColorTable( surface->image_ps,
+                              (ULONG) LCOL_PURECOLOR,
+                              (LONG)  LCOLF_CONSECRGB,
+                              (LONG)  0L,
+                              (LONG)  count,
+                              (PLONG) palette );
+
+      /* now, copy the color indexes to surface->shades */
+      for ( x = 0; x < count; x++ )
+        surface->shades[x] = GpiQueryColorIndex( surface->image_ps,
+                                                 0, palette[x] );
+    }
+
+    /* set up the blit points array */
+    surface->blit_points[1].x = surface->root.bitmap.width;
+    surface->blit_points[1].y = surface->root.bitmap.rows;
+    surface->blit_points[3]   = surface->blit_points[1];
+
+    /* Finally, create the event handling thread for the surface's window */
+    DosCreateThread( &surface->message_thread,
+                     (PFNTHREAD) RunPMWindow,
+                     (ULONG)     surface,
+                     0UL,
+                     32920 );
+
+    surface->root.done         = (grDoneSurfaceFunc) done_surface;
+    surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
+    surface->root.set_title    = (grSetTitleFunc)    set_title;
+    surface->root.listen_event = (grListenEventFunc) listen_event;
+    
+    convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
+    return surface;
+  }
+
+
+
+  MRESULT EXPENTRY  Message_Process( HWND    handle,
+                                     ULONG   mess,
+                                     MPARAM  parm1,
+                                     MPARAM  parm2 );
+
+
+  static
+  void  RunPMWindow( grPMSurface*  surface )
+  {
+    unsigned char   class_name[] = "DisplayClass";
+             ULONG  class_flags;
+
+    static   HMQ    queue;
+             QMSG   message;
+
+    /* create an anchor to allow this thread to use PM */
+    surface->anchor = WinInitialize(0);
+    if (!surface->anchor)
+    {
+      printf( "Error doing WinInitialize()\n" );
+      return;
+    }
+
+    /* create a message queue */
+    queue = WinCreateMsgQueue( surface->anchor, 0 );
+    if (!queue)
+    {
+      printf( "Error doing >inCreateMsgQueue()\n" );
+      return;
+    }
+
+    /* register the window class */
+    if ( !WinRegisterClass( surface->anchor,
+                            (PSZ)   class_name,
+                            (PFNWP) Message_Process,
+                            CS_SIZEREDRAW,
+                            0 ) )
+    {
+      printf( "Error doing WinRegisterClass()\n" );
+      return;
+    }
+
+    /* create the PM window */
+    class_flags = FCF_TITLEBAR | FCF_MINBUTTON | FCF_DLGBORDER | 
+                  FCF_TASKLIST | FCF_SYSMENU; 
+
+    surface->frame_window = WinCreateStdWindow(
+                                HWND_DESKTOP,
+                                WS_VISIBLE,
+                                &class_flags,
+                                (PSZ) class_name,
+                                (PSZ) "FreeType PM Graphics",
+                                WS_VISIBLE,
+                                0, 0,
+                                &surface->client_window );
+    if (!surface->frame_window)
+    {
+      printf( "Error doing WinCreateStdWindow()\n" );
+      return;
+    }
+
+    /* find the title window handle */
+    surface->title_window = WinWindowFromID( surface->frame_window,
+                                             FID_TITLEBAR );
+
+    /* set Window size and position */
+    WinSetWindowPos( surface->frame_window,
+                     0L,
+                     (SHORT) 60,
+                     (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) -
+                             surface->root.bitmap.rows + 100,
+
+                     (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
+                             surface->root.bitmap.width,
+
+                     (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) +
+                             WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
+                             surface->root.bitmap.rows,
+
+                     SWP_SIZE | SWP_MOVE );
+
+    /* save the handle to the current surface within the window words */
+    WinSetWindowPtr( surface->frame_window,QWL_USER, surface );
+
+    /* run the message queue till the end */
+    while ( WinGetMsg( surface->anchor, &message, (HWND)NULL, 0, 0 ) )
+      WinDispatchMsg( surface->anchor, &message );
+
+    /* clean-up */
+    WinDestroyWindow( surface->frame_window );
+    surface->frame_window = 0;
+
+    WinDestroyMsgQueue( queue );
+    WinTerminate( surface->anchor );
+
+    /* await death... */
+    while ( 1 )
+      DosSleep( 100 );
+  }
+
+
+
+
+  /* Message processing for our PM Window class */
+  MRESULT EXPENTRY  Message_Process( HWND    handle,
+                                     ULONG   mess,
+                                     MPARAM  parm1,
+                                     MPARAM  parm2 )
+  {
+     static HDC     screen_dc;
+     static HPS     screen_ps;
+     static BOOL    minimized;
+
+     SIZEL   sizl;
+     SWP     swp;
+
+     grPMSurface*  surface;
+
+    /* get the handle to the window's surface */
+    surface = (grPMSurface*)WinQueryWindowPtr( handle, QWL_USER );
+
+    switch( mess )
+    {
+    case WM_DESTROY:
+      /* warn the main thread to quit if it didn't know */
+      surface->event.type = gr_event_key;
+      surface->event.key  = grKeyEsc;
+      DosPostEventSem( surface->event_lock );
+      break;
+
+    case WM_CREATE:
+      /* set original magnification */
+      minimized = FALSE;
+
+      /* create Device Context and Presentation Space for screen. */
+      screen_dc = WinOpenWindowDC( handle );
+      screen_ps = GpiCreatePS( surface->anchor,
+                               screen_dc,
+                               &sizl,
+                               PU_PELS | GPIT_MICRO |
+                               GPIA_ASSOC | GPIF_DEFAULT );
+
+      /* take the input focus */
+      WinFocusChange( HWND_DESKTOP, handle, 0L );
+      break;
+
+    case WM_MINMAXFRAME:
+      /* to update minimized if changed */
+      swp = *((PSWP) parm1);
+      if ( swp.fl & SWP_MINIMIZE ) 
+        minimized = TRUE;
+      if ( swp.fl & SWP_RESTORE )
+        minimized = FALSE;
+      return WinDefWindowProc( handle, mess, parm1, parm2 );
+      break;
+
+    case WM_ERASEBACKGROUND:
+    case WM_PAINT:  
+      /* copy the memory image of the screen out to the real screen */
+      DosRequestMutexSem( surface->image_lock, SEM_INDEFINITE_WAIT );
+      WinBeginPaint( handle, screen_ps, NULL );
+      
+      /* main image and magnified picture */
+      GpiBitBlt( screen_ps,
+                 surface->image_ps,
+                 4L,
+                 surface->blit_points,
+                 ROP_SRCCOPY, BBO_AND );
+
+      WinEndPaint( screen_ps );
+      DosReleaseMutexSem( surface->image_lock );   
+      break;
+
+    case WM_CHAR:
+      if ( CHARMSG( &mess )->fs & KC_KEYUP )
+        break;
+
+      /* look for a specific vkey */
+      {
+        int          count = sizeof( key_translators )/sizeof( key_translators[0] );
+        Translator*  trans = key_translators;
+        Translator*  limit = trans + count;
+
+        for ( ; trans < limit; trans++ )
+          if ( CHARMSG(&mess)->vkey == trans->os2key )
+          {
+            surface->event.key = trans->grkey;
+            goto Do_Key_Event;
+          }
+      }
+
+      /* otherwise, simply record the character code */
+      if ( (CHARMSG( &mess )->fs & KC_CHAR) == 0 )
+        break;
+
+      surface->event.key = CHARMSG(&mess)->chr;
+
+    Do_Key_Event:
+      surface->event.type = gr_event_key;
+      DosPostEventSem( surface->event_lock );
+      break;
+
+    default:
+      return WinDefWindowProc( handle, mess, parm1, parm2 );
+    }
+
+    return (MRESULT) FALSE;
+  }
+
+
+
+
+
+
+
+#if 0
+  static
+  grKey  KeySymTogrKey(   key )
+  {
+    grKey        k;
+    int          count = sizeof(key_translators)/sizeof(key_translators[0]);
+    Translator*  trans = key_translators;
+    Translator*  limit = trans + count;
+
+    k = grKeyNone;
+
+    while ( trans < limit )
+    {
+      if ( trans->xkey == key )
+      {
+        k = trans->grkey;
+        break;
+      }
+      trans++;
+    }
+
+    return k;
+  }
+
+
+
+  static  
+  void  listen_event( grPMSurface* surface,
+                      int          event_mask,
+                      grEvent*     grevent )
+  {
+    grKey           grkey;
+
+    /* XXXX : For now, ignore the event mask, and only exit when */
+    /*        a key is pressed..                                 */
+    (void)event_mask;
+
+
+    /* Now, translate the keypress to a grKey */
+    /* If this wasn't part of the simple translated keys, simply get the charcode */
+    /* from the character buffer                                                  */
+    grkey = grKEY(key_buffer[key_cursor++]);
+      
+  Set_Key:
+    grevent->type = gr_key_down;
+    grevent->key  = grkey;
+  }
+
+#endif
+
+
+
+  grDevice  gr_os2pm_device =
+  {
+    sizeof( grPMSurface ),
+    "os2pm",
+    
+    init_device,
+    done_device,
+    
+    (grDeviceInitSurfaceFunc) init_surface,
+    
+    0,
+    0
+    
+  };
+
+
diff --git a/demos/config/os2/gros2pm.def b/demos/config/os2/gros2pm.def
new file mode 100644
index 0000000..4a77c63
--- /dev/null
+++ b/demos/config/os2/gros2pm.def
@@ -0,0 +1,5 @@
+NAME        WINDOWCOMPAT
+
+DESCRIPTION 'FreeType Graphics'
+HEAPSIZE    8192
+STACKSIZE   40888
diff --git a/demos/config/os2/gros2pm.h b/demos/config/os2/gros2pm.h
new file mode 100644
index 0000000..2293580
--- /dev/null
+++ b/demos/config/os2/gros2pm.h
@@ -0,0 +1,23 @@
+#ifndef GROS2PM_H
+#define GROS2PM_H
+
+#include "grobjs.h"
+
+  extern
+  grDevice  gr_os2pm_device;
+
+#ifdef GR_INIT_BUILD
+  static
+  grDeviceChain  gr_os2pm_device_chain =
+  {
+    "os2pm",
+    &gr_os2pm_device,
+    GR_INIT_DEVICE_CHAIN
+  };
+
+#undef GR_INIT_DEVICE_CHAIN
+#define GR_INIT_DEVICE_CHAIN  &gr_os2pm_device_chain
+
+#endif  /* GR_INIT_BUILD */
+
+#endif /* GROS2PM_H */
diff --git a/demos/config/os2/rules.mk b/demos/config/os2/rules.mk
new file mode 100644
index 0000000..537034d
--- /dev/null
+++ b/demos/config/os2/rules.mk
@@ -0,0 +1,32 @@
+#**************************************************************************
+#*
+#*  OS/2 specific rules file, used to compile the OS/2 graphics driver
+#*  to the graphics subsystem
+#*
+#**************************************************************************
+
+ifeq ($(PLATFORM),os2)
+
+GR_OS2  := config$(SEP)os2
+GR_OS2_ := $(GR_OS2)$(SEP)
+
+# the GRAPH_LINK is expanded each time an executable is linked with the
+# graphics library.
+#
+GRAPH_LINK     += $(GR_OS2_)gros2pm.def
+
+# Add the OS/2 driver object file to the graphics library "graph.a"
+#
+GRAPH_OBJS += $(OBJ_)gros2pm.$O
+
+DEVICES         += OS2_PM
+DEVICE_INCLUDES += $(GR_OS2)
+
+# the rule used to compile the graphics driver
+#
+$(OBJ_)gros2pm.$O: $(GR_OS2_)gros2pm.c $(GR_OS2_)gros2pm.h
+	$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(GR_OS2) $T$@ $<
+
+endif
+
+
diff --git a/demos/config/x11/grx11.c b/demos/config/x11/grx11.c
new file mode 100644
index 0000000..99d8538
--- /dev/null
+++ b/demos/config/x11/grx11.c
@@ -0,0 +1,936 @@
+#include "grx11.h"
+
+
+#ifdef TEST
+#include "grfont.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+
+  static void Panic( const char* message )
+  {
+    fprintf( stderr, "%s", message );
+    exit(1);
+  }
+
+  typedef struct Translator
+  {
+    KeySym  xkey;
+    grKey   grkey;
+    
+  } Translator;
+  
+  static
+  Translator  key_translators[] =
+  {
+    { XK_BackSpace, grKeyBackSpace },
+    { XK_Tab,       grKeyTab       },
+    { XK_Return,    grKeyReturn    },
+    { XK_Escape,    grKeyEsc       },
+    { XK_Home,      grKeyHome      },
+    { XK_Left,      grKeyLeft      },
+    { XK_Up,        grKeyUp        },
+    { XK_Right,     grKeyRight     },
+    { XK_Down,      grKeyDown      },
+    { XK_Page_Up,   grKeyPageUp    },
+    { XK_Page_Down, grKeyPageDown  },
+    { XK_End,       grKeyEnd       },
+    { XK_Begin,     grKeyHome      },
+    { XK_F1,        grKeyF1        },
+    { XK_F2,        grKeyF2        },
+    { XK_F3,        grKeyF3        },
+    { XK_F4,        grKeyF4        },
+    { XK_F5,        grKeyF5        },
+    { XK_F6,        grKeyF6        },
+    { XK_F7,        grKeyF7        },
+    { XK_F8,        grKeyF8        },
+    { XK_F9,        grKeyF9        },
+    { XK_F10,       grKeyF10       },
+    { XK_F11,       grKeyF11       },
+    { XK_F12,       grKeyF12       }
+  };
+
+
+#ifdef TEST
+  
+#define grAlloc  malloc
+  
+#endif
+
+
+  static Display*  display;
+  static char*     displayname = "";
+
+  static Cursor  idle;
+  static Cursor  busy;
+
+#define MAX_PIXEL_MODES  32
+
+  typedef XPixmapFormatValues  XDepth;
+
+  static int           num_pixel_modes = 0;
+  static grPixelMode   pixel_modes[ MAX_PIXEL_MODES ];  
+  static XDepth        pixel_depth[ MAX_PIXEL_MODES ];
+
+  typedef struct grXSurface_
+  {
+    grSurface      root;
+    grBitmap       image;
+
+    Window         win;
+    Visual*        visual;
+    Colormap       colormap;
+    int            depth;
+    Bool           gray;
+    
+    GC             gc;
+    
+    XColor         color[256];   /* gray levels palette for 8-bit modes */
+    XImage*        ximage;
+
+    int            win_org_x;
+    int            win_org_y;
+    int            win_width;
+    int            win_height;
+    
+    int            image_width;
+    int            image_height;
+    
+  } grXSurface;
+
+
+
+
+  /* close a given window */
+  static
+  void  done_surface( grXSurface*  surface )
+  {
+    XUnmapWindow( display, surface->win );
+  }
+
+
+
+  /* close the device, i.e. the display connection */
+  static
+  void  done_device( void )
+  {
+    XCloseDisplay( display );
+  }
+
+
+
+  static
+  void add_pixel_mode( grPixelMode  pixel_mode,
+                       XDepth*      depth )
+  {
+    if ( num_pixel_modes >= MAX_PIXEL_MODES )
+      Panic( "X11.Too many pixel modes\n" );
+      
+    pixel_modes[ num_pixel_modes ] = pixel_mode;
+    pixel_depth[ num_pixel_modes ] = *depth;
+    
+    num_pixel_modes++;
+  }
+
+
+
+  static
+  int  init_device( void )
+  {
+    XDepth  dummy;
+  
+    XrmInitialize();
+    
+    display = XOpenDisplay( displayname );
+    if (!display)
+    {
+      return -1;
+     /* Panic( "Gr:error: cannot open X11 display\n" ); */
+    }
+      
+    idle = XCreateFontCursor( display, XC_left_ptr );
+    busy = XCreateFontCursor( display, XC_watch );
+    
+    num_pixel_modes = 0;
+    
+    /* always enable the 8-bit gray levels pixel mode                */
+    /* even if its display is emulated through a constrained palette */
+    /* or another color mode                                         */
+    dummy.depth          = 8;
+    dummy.bits_per_pixel = 8;
+    dummy.scanline_pad   = 8;
+    add_pixel_mode( gr_pixel_mode_gray, &dummy );
+
+    {
+      int          count;
+      XDepth*      format;
+      XDepth*      formats;
+      XVisualInfo  template;
+
+      formats = XListPixmapFormats( display, &count );
+      format  = formats;
+       
+#ifdef TEST
+      printf( "available pixmap formats\n" );
+      printf( "depth  pixbits  scanpad\n" );
+#endif
+       
+      while ( count-- > 0 )
+      {
+#ifdef TEST 
+        printf( " %3d     %3d      %3d\n",
+                format->depth,
+                format->bits_per_pixel,
+                format->scanline_pad );
+#endif
+      
+        if ( format->depth == 1 )
+          /* usually, this should be the first format */
+          add_pixel_mode( gr_pixel_mode_mono, format );
+          
+        else if ( format->depth == 8 )
+          add_pixel_mode( gr_pixel_mode_pal8, format );
+
+        /* note, the 32-bit modes return a depth of 24, and 32 bits per pixel */          
+        else if ( format->depth == 24 )
+        {
+          if ( format->bits_per_pixel == 24 )
+            add_pixel_mode( gr_pixel_mode_rgb24, format );
+            
+          else if ( format->bits_per_pixel == 32 )
+            add_pixel_mode( gr_pixel_mode_rgb32, format );
+        }
+          
+        else if ( format->depth == 16 )
+        {
+          int           count2;
+          XVisualInfo*  visuals;
+          XVisualInfo*  visual;
+
+          template.depth = format->depth;
+          visuals        = XGetVisualInfo( display,
+                                           VisualDepthMask,
+                                           &template,
+                                           &count2 );
+          visual = visuals;
+          
+          while ( count2-- > 0 )
+          {
+#ifdef TEST 
+            const char*  string = "unknown";
+            
+            switch (visual->class)
+            {
+              case TrueColor:   string = "TrueColor";    break;
+              case DirectColor: string = "DirectColor";  break;
+              case PseudoColor: string = "PseudoColor";  break;
+              case StaticGray : string = "StaticGray";   break;
+              case StaticColor: string = "StaticColor";  break;
+              case GrayScale:   string = "GrayScale";    break;
+            }
+
+            printf( ">   RGB %02x:%02x:%02x, colors %3d, bits %2d  %s\n",
+                    visual->red_mask,
+                    visual->green_mask,
+                    visual->blue_mask,
+                    visual->colormap_size,
+                    visual->bits_per_rgb,
+                    string );
+#endif
+            if ( visual->red_mask   == 0xf800 &&
+                 visual->green_mask == 0x07e0 &&
+                 visual->blue_mask  == 0x001f )
+              add_pixel_mode( gr_pixel_mode_rgb565, format );
+              
+            else if ( visual->red_mask   == 0x7c00 &&
+                      visual->green_mask == 0x03e0 &&
+                      visual->blue_mask  == 0x001f )
+              add_pixel_mode( gr_pixel_mode_rgb555, format );
+              
+            /* other 16-bit modes are ignored */  
+            visual++;
+          }
+          
+          XFree( visuals );
+        }
+        
+        format++;
+      }
+      
+      XFree( formats );
+    }
+    
+    gr_x11_device.num_pixel_modes = num_pixel_modes;
+    gr_x11_device.pixel_modes     = pixel_modes;
+    
+    return 0;
+  }
+
+
+
+
+
+
+
+
+
+
+
+
+  static
+  void  convert_gray_to_pal8( grXSurface*  surface,
+                              int          x,
+                              int          y,
+                              int          w,
+                              int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    XColor*    palette = surface->color;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + w;
+      
+      for ( ; _write < limit; _write++, _read++ )
+        *_write = (byte) palette[ *_read ].pixel;
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_16( grXSurface*  surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 2*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    XColor*    palette = surface->color;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 2*w;
+      
+      for ( ; _write < limit; _write += 2, _read++ )
+        *(short*)_write = (short)palette[ *_read ].pixel;
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_24( grXSurface*  surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 3*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 3*w;
+      
+      for ( ; _write < limit; _write += 3, _read++ )
+      {
+        byte  color = *_read;
+        
+        _write[0] =
+        _write[1] =
+        _write[2] = color;
+      }
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_32( grXSurface*  surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 4*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 4*w;
+      
+      for ( ; _write < limit; _write += 4, _read++ )
+      {
+        byte  color = *_read;
+        
+        _write[0] =
+        _write[1] =
+        _write[2] =
+        _write[3] = color;
+      }
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_rectangle( grXSurface*  surface,
+                           int          x,
+                           int          y,
+                           int          w,
+                           int          h )
+  {
+    int  z;
+    
+    /* first of all, clip to the surface's area */
+    if ( x   >= surface->image.width ||
+         x+w <= 0                    ||
+         y   >= surface->image.rows  ||
+         y+h <= 0 )
+      return;
+ 
+    if ( x < 0 )
+    {
+      w += x;
+      x  = 0;
+    }
+ 
+    z = (x + w) - surface->image.width;
+    if (z > 0)
+      w -= z;
+      
+    z = (y + h) - surface->image.rows;
+    if (z > 0)
+      h -= z;
+      
+    /* convert the rectangle to the target depth for gray surfaces */
+    if (surface->gray)
+    {
+      switch (surface->depth)
+      {
+        case 8 : convert_gray_to_pal8( surface, x, y, w, h ); break;
+        case 16: convert_gray_to_16  ( surface, x, y, w, h ); break;
+        case 24: convert_gray_to_24  ( surface, x, y, w, h ); break;
+        case 32: convert_gray_to_32  ( surface, x, y, w, h ); break;
+      }
+    }
+  } 
+
+
+  static
+  void  refresh_rectangle( grXSurface*  surface,
+                           int          x,
+                           int          y,
+                           int          w,
+                           int          h )
+  {
+    if (surface->gray)
+      convert_rectangle( surface, x, y, w, h );
+    
+    XPutImage( display,
+               surface->win,
+               surface->gc,
+               surface->ximage,
+               x, y, x, y, w, h );
+  }
+
+  
+  static
+  void  set_title( grXSurface*  surface,
+                   const char*  title )
+  {
+    XStoreName( display, surface->win, title );
+  }
+
+
+
+  static
+  grKey  KeySymTogrKey( KeySym  key )
+  {
+    grKey        k;
+    int          count = sizeof(key_translators)/sizeof(key_translators[0]);
+    Translator*  trans = key_translators;
+    Translator*  limit = trans + count;
+
+    k = grKeyNone;
+
+    while ( trans < limit )
+    {
+      if ( trans->xkey == key )
+      {
+        k = trans->grkey;
+        break;
+      }
+      trans++;
+    }
+
+    return k;
+  }
+
+
+
+  static  
+  void  listen_event( grXSurface*  surface,
+                      int          event_mask,
+                      grEvent*     grevent )
+  {
+    static char     key_buffer[10];
+    static int      key_cursor = 0;
+    static int      key_number = 0;
+    static XEvent   x_event;
+           KeySym   key;
+
+    int             bool_exit;
+    grKey           grkey;
+
+    XComposeStatus  compose;
+
+    /* XXXX : For now, ignore the event mask, and only exit when */
+    /*        a key is pressed..                                 */
+    (void)event_mask;
+
+    bool_exit = key_cursor < key_number;
+
+    XDefineCursor( display, surface->win, idle );
+
+    while ( !bool_exit )
+    {
+      XNextEvent( display, &x_event );
+
+      switch ( x_event.type )
+      {
+      case KeyPress: 
+        key_number = XLookupString( &x_event.xkey,
+                                    key_buffer,
+                                    sizeof ( key_buffer ),
+                                    &key,
+                                    &compose );
+        key_cursor = 0;
+
+        if ( key_number == 0 ||
+             key > 512       )
+        {
+          /* this may be a special key like F1, F2, etc.. */
+          grkey = KeySymTogrKey(key);
+          if (grkey != grKeyNone)
+            goto Set_Key;  
+        }
+        else
+          bool_exit = 1;
+        break;
+
+      case MappingNotify:
+        XRefreshKeyboardMapping( &x_event.xmapping );
+        break;
+      
+      case Expose:
+        refresh_rectangle( surface,
+                           x_event.xexpose.x,
+                           x_event.xexpose.y,
+                           x_event.xexpose.width,
+                           x_event.xexpose.height );
+        break;
+
+      /* You should add more cases to handle mouse events, etc. */
+      }
+    }
+
+    XDefineCursor( display, surface->win, busy );
+    XFlush       ( display );
+
+    /* Now, translate the keypress to a grKey */
+    /* If this wasn't part of the simple translated keys, simply get the charcode */
+    /* from the character buffer                                                  */
+    grkey = grKEY(key_buffer[key_cursor++]);
+      
+  Set_Key:
+    grevent->type = gr_key_down;
+    grevent->key  = grkey;
+  }
+
+
+
+
+  grXSurface*  init_surface( grXSurface*  surface,
+                             grBitmap*    bitmap )
+  {
+    int        screen;
+    grBitmap*  image;
+    char       grays;
+    XDepth*    format;
+    int        image_depth;
+    
+    screen = DefaultScreen( display );
+    
+    surface->colormap = DefaultColormap( display, screen );
+    surface->depth    = DefaultDepth( display, screen );
+    surface->visual   = DefaultVisual( display, screen ); 
+
+    image  = &surface->image;
+
+    /* force the surface image depth to 1 if necessary */
+    /* as this should be supported by all windows      */
+    image_depth = surface->depth;
+    if (bitmap->mode == gr_pixel_mode_mono)
+      image_depth = 1;
+
+    grays = ( bitmap->mode == gr_pixel_mode_gray &&
+              bitmap->grays >= 2 );
+
+    surface->gray = grays;
+ 
+    /* copy dimensions */
+    image->width  = bitmap->width;
+    image->rows   = bitmap->rows;
+    image->mode   = bitmap->mode;
+    image->pitch  = 0;
+    image->grays  = 0;
+    image->buffer = 0;
+
+    /* find the supported format corresponding to the request */
+    format = 0;
+
+    if (grays)    
+    {
+      /* choose the default depth in case of grays rendering */
+      int  i;
+      for ( i = 0; i < num_pixel_modes; i++ )
+        if ( image_depth == pixel_depth[i].depth )
+        {
+          format = pixel_depth + i;
+          break;
+        }
+    }
+    else
+    {
+      /* otherwise, select the format depending on the pixel mode */
+      int  i;
+      
+      format = 0;
+      for ( i = 0; i < num_pixel_modes; i++ )
+        if ( pixel_modes[i] == bitmap->mode )
+        {
+          format = pixel_depth + i;
+          break;
+        }
+    }
+    
+    if (!format)
+    {
+      grError = gr_err_bad_argument;
+      return 0;
+    }
+
+
+    /* correct surface.depth. This is required because in the case    */
+    /* of 32-bits pixels, the value of "format.depth" is 24 under X11 */
+    if ( format->depth          == 24 &&
+         format->bits_per_pixel == 32 )
+      image_depth = 32;
+     
+    /* allocate surface image */
+    {
+      int  bits, over;
+
+      bits = image->width * format->bits_per_pixel;
+      over = bits % format->scanline_pad;
+          
+      if (over)
+        bits += format->scanline_pad - over;
+      
+      if (!grays)
+      {
+        image->width  = bits;
+        bitmap->width = bits;
+      }
+      image->pitch  = bits >> 3;
+    }
+
+    image->buffer = grAlloc( image->pitch * image->rows );
+    if (!image->buffer) return 0;
+
+    /* now, allocate a gray pal8 pixmap, only when we asked */
+    /* for an 8-bit pixmap                                  */
+    if ( grays )
+    {
+      /* pad pitch to 32 bits */
+      bitmap->pitch  = (bitmap->width + 3) & -4;
+      bitmap->buffer = grAlloc( bitmap->pitch * bitmap->rows );
+      if (!bitmap->buffer)
+        Panic( "grX11: could not allocate surface bitmap!\n" );
+    }
+    else  /* otherwise */
+    {
+      *bitmap = *image;
+    }
+
+    surface->root.bitmap = *bitmap;
+ 
+    /* Now create the surface X11 image */
+    surface->ximage = XCreateImage( display, 
+                                    surface->visual,
+                                    format->depth,
+                                    format->depth == 1 ? XYBitmap : ZPixmap,
+                                    0,
+                                    (char*)image->buffer,
+                                    image->width,
+                                    image->rows,
+                                    8,
+                                    0 );
+    if ( !surface->ximage )
+      Panic( "grX11: cannot create surface X11 image\n" );
+ 
+
+    /* allocate gray levels in the case of gray surface */
+    if ( grays )
+    {
+      XColor*  color = surface->color;
+      int      i;
+      
+      for ( i = 0; i < bitmap->grays; i++, color++ )
+      {
+        color->red   =
+        color->green =
+        color->blue  = 65535 - ( i * 65535 ) / bitmap->grays;
+  
+        if ( !XAllocColor( display, surface->colormap, color ) )
+          Panic( "ERROR: cannot allocate Color\n" );
+      }
+    }
+    else if ( image_depth == 1 )
+    {
+      surface->ximage->byte_order       = MSBFirst;
+      surface->ximage->bitmap_bit_order = MSBFirst;
+    }
+
+    {
+        XTextProperty         xtp;
+        XSizeHints            xsh;
+        XSetWindowAttributes  xswa;
+    
+        xswa.border_pixel     = BlackPixel( display, screen );
+        xswa.background_pixel = WhitePixel( display, screen );
+        xswa.cursor           = busy;
+    
+        xswa.event_mask = KeyPressMask | ExposureMask;
+    
+        surface->win = XCreateWindow( display,
+                                      RootWindow( display, screen ),
+                                      0,
+                                      0,
+                                      image->width,
+                                      image->rows,
+                                      10,
+                                      surface->depth,
+                                      InputOutput, 
+                                      surface->visual,
+                                      CWBackPixel | CWBorderPixel |
+                                        CWEventMask | CWCursor,
+                                      &xswa );
+    
+        XMapWindow( display, surface->win );
+ 
+        surface->gc = XCreateGC( display, RootWindow( display, screen ), 0L, NULL );
+        XSetForeground( display, surface->gc, xswa.border_pixel     );
+        XSetBackground( display, surface->gc, xswa.background_pixel );
+    
+    
+        /* make window manager happy :-) */
+        xtp.value    = (unsigned char*)"FreeType";
+        xtp.encoding = 31;
+        xtp.format   = 8;
+        xtp.nitems   = strlen( (char*)xtp.value );
+    
+        xsh.x = 0;
+        xsh.y = 0;
+    
+        xsh.width  = image->width;
+        xsh.height = image->rows;
+        xsh.flags  = (PPosition | PSize);
+        xsh.flags  = 0;
+    
+        XSetWMProperties( display, surface->win, &xtp, &xtp, NULL, 0, &xsh, NULL, NULL );
+    }
+    
+    surface->root.done         = (grDoneSurfaceFunc) done_surface;
+    surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
+    surface->root.set_title    = (grSetTitleFunc)    set_title;
+    surface->root.listen_event = (grListenEventFunc) listen_event;
+    
+    convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
+    return surface;
+  }
+  
+
+
+
+  grDevice  gr_x11_device =
+  {
+    sizeof( grXSurface ),
+    "x11",
+    
+    init_device,
+    done_device,
+    
+    (grDeviceInitSurfaceFunc) init_surface,
+    
+    0,
+    0
+    
+  };
+
+#ifdef TEST
+
+typedef struct grKeyName
+{
+  grKey       key;
+  const char* name;
+
+} grKeyName;
+
+
+static
+const grKeyName  key_names[] =
+{
+  { grKeyF1,   "F1"  },
+  { grKeyF2,   "F2"  },
+  { grKeyF3,   "F3"  },
+  { grKeyF4,   "F4"  },
+  { grKeyF5,   "F5"  },
+  { grKeyF6,   "F6"  },
+  { grKeyF7,   "F7"  },
+  { grKeyF8,   "F8"  },
+  { grKeyF9,   "F9"  },
+  { grKeyF10,  "F10" },
+  { grKeyF11,  "F11" },
+  { grKeyF12,  "F12" },
+  { grKeyEsc,  "Esc" },
+  { grKeyHome, "Home" },
+  { grKeyEnd,  "End"  },
+    
+  { grKeyPageUp,   "Page_Up" },
+  { grKeyPageDown, "Page_Down" },
+  { grKeyLeft,     "Left" },
+  { grKeyRight,    "Right" },
+  { grKeyUp,       "Up" },
+  { grKeyDown,     "Down" },
+  { grKeyBackSpace, "BackSpace" },
+  { grKeyReturn,   "Return" }
+};
+
+int  main( void )
+{
+  grSurface*  surface;
+  int         n;
+  
+  grInit();
+  surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
+  if (!surface)
+    Panic("Could not create window\n" );
+  else
+  {
+    grColor      color;
+    grEvent      event;
+    const char*  string;
+    int          x;
+    
+    grSetSurfaceRefresh( surface, 1 );
+    grSetTitle(surface,"X11 driver demonstration" );
+    
+    for ( x = -10; x < 10; x++ )
+    {
+      for ( n = 0; n < 128; n++ )
+      {
+        color.value = (n*3) & 127;
+        grWriteCellChar( surface,
+                         x + ((n % 60) << 3),
+                         80 + (x+10)*8*3 + ((n/60) << 3), n, color );
+      }
+
+    }
+    color.value = 64;
+    grWriteCellString( surface, 0, 0, "just an example", color );
+    
+    do
+    {
+      listen_event((grXSurface*)surface, 0, &event);
+    
+      /* return if ESC was pressed */
+      if ( event.key == grKeyEsc )
+        return 0;
+      
+      /* otherwise, display key string */
+      color.value = (color.value + 8) & 127;
+      {
+        int         count = sizeof(key_names)/sizeof(key_names[0]);
+        grKeyName*  name  = key_names;
+        grKeyName*  limit = name + count;
+        const char* kname  = 0;
+        char        kname_temp[16];
+      
+        while (name < limit)
+        {
+          if ( name->key == event.key )
+          {
+            kname = name->name;
+            break;
+          }
+          name++;
+        }
+      
+        if (!kname)
+        {
+          sprintf( kname_temp, "char '%c'", (char)event.key );
+          kname = kname_temp;
+        }
+        
+        grWriteCellString( surface, 30, 30, kname, color );
+        grRefreshSurface(surface);
+        paint_rectangle( surface, 0, 0, surface->bitmap.width, surface->bitmap.rows );
+      }
+    } while (1);
+  }
+    
+  return 0;
+  
+  
+}
+#endif /* TEST */
+
diff --git a/demos/config/x11/grx11.h b/demos/config/x11/grx11.h
new file mode 100644
index 0000000..cd77112
--- /dev/null
+++ b/demos/config/x11/grx11.h
@@ -0,0 +1,24 @@
+#ifndef GRX11_H
+#define GRX11_H
+
+#include "grobjs.h"
+#include "grdevice.h"
+
+  extern
+  grDevice  gr_x11_device;
+
+#ifdef GR_INIT_BUILD
+  static
+  grDeviceChain  gr_x11_device_chain =
+  {
+    "x11",
+    &gr_x11_device,
+    GR_INIT_DEVICE_CHAIN
+  };
+
+#undef GR_INIT_DEVICE_CHAIN
+#define GR_INIT_DEVICE_CHAIN  &gr_x11_device_chain
+
+#endif  /* GR_INIT_BUILD */
+
+#endif /* GRX11_H */
diff --git a/demos/config/x11/rules.mk b/demos/config/x11/rules.mk
new file mode 100644
index 0000000..ee616e9
--- /dev/null
+++ b/demos/config/x11/rules.mk
@@ -0,0 +1,69 @@
+#**************************************************************************
+#*
+#*  X11-specific rules files, used to compile the X11 graphics driver
+#*  when supported by the current platform
+#*
+#**************************************************************************
+
+#########################################################################
+#
+# Try to detect an X11 setup.
+#
+# We simply try to detect a `X11R6/bin', `X11R5/bin' or `X11/bin' in
+# the current path.
+#
+ifneq ($(findstring X11R6$(SEP)bin,$(PATH)),)
+xversion := X11R6
+endif
+
+ifneq ($(findstring X11R5$(SEP)bin,$(PATH)),)
+xversion := X11R5
+endif
+
+ifneq ($(findstring X11$(SEP)bin,$(PATH)),)
+xversion := X11
+endif
+
+ifdef xversion
+X11_PATH := $(subst ;, ,$(PATH)) $(subst :, ,$(PATH))
+X11_PATH := $(filter %$(xversion)$(SEP)bin,$(X11_PATH))
+X11_PATH := $(X11_PATH:%$(SEP)bin=%)
+endif
+
+##########################################################################
+#
+# Update some variables to compile the X11 graphics module. Note that
+# X11 is available on Unix, or on OS/2. However, it only compiles with
+# gcc on the latter platform, which is why it is safe to use the flags
+# `-L' and `-l'
+#
+ifneq ($(X11_PATH),)
+
+X11_INCLUDE    := $(X11_PATH)$(SEP)include
+X11_LIB        := $(X11_PATH)$(SEP)lib
+
+# the GRAPH_LINK variable is expanded each time an executable is linked against
+# the graphics library..
+#
+GRAPH_LINK     += -L$(X11_LIB) -lX11
+
+# add the X11 driver object file to the graphics library
+#
+GRAPH_OBJS += $(OBJ_)grx11.$O
+
+GR_X11  := config$(SEP)x11
+GR_X11_ := $(GR_X11)$(SEP)
+
+DEVICES         += X11
+DEVICE_INCLUDES += $(GR_X11)
+
+# the rule used to compile the X11 driver
+#
+$(OBJ_)grx11.$O: $(GR_X11_)grx11.c $(GR_X11_)grx11.h
+	$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(GR_X11) \
+              $(X11_INCLUDE:%=$I%) $T$@ $<
+endif
+
+
+
+
diff --git a/demos/graph/gpm_os2.def b/demos/graph/gpm_os2.def
new file mode 100644
index 0000000..4a77c63
--- /dev/null
+++ b/demos/graph/gpm_os2.def
@@ -0,0 +1,5 @@
+NAME        WINDOWCOMPAT
+
+DESCRIPTION 'FreeType Graphics'
+HEAPSIZE    8192
+STACKSIZE   40888
diff --git a/demos/graph/graph.h b/demos/graph/graph.h
new file mode 100644
index 0000000..e5f3b32
--- /dev/null
+++ b/demos/graph/graph.h
@@ -0,0 +1,632 @@
+/***************************************************************************
+ *
+ *  graph.h
+ *
+ *    Graphics Subsystem interface
+ *
+ *  Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GRAPH_H
+#define GRAPH_H
+
+#include "grevents.h"
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /********                                                         ********/
+ /********         GENERAL DEFINITIONS AND BLITTING ROUTINES       ********/
+ /********                                                         ********/
+ /********                                                         ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+  /* define the global error variable */
+  extern int  grError;
+
+  /* initialisation */
+  extern int  grInit( void );
+  
+  /* finalisation */
+  extern void grDone( void );
+
+
+  /* pixel mode constants */
+  typedef enum grPixelMode
+  {
+    gr_pixel_mode_none = 0,
+    gr_pixel_mode_mono,        /* monochrome bitmaps               */
+    gr_pixel_mode_pal4,        /* 4-bit paletted - 16 colors       */
+    gr_pixel_mode_pal8,        /* 8-bit paletted - 256 colors      */
+    gr_pixel_mode_gray,        /* 8-bit gray levels                */
+    gr_pixel_mode_rgb555,      /* 15-bits mode - 32768 colors      */
+    gr_pixel_mode_rgb565,      /* 16-bits mode - 65536 colors      */
+    gr_pixel_mode_rgb24,       /* 24-bits mode - 16 million colors */
+    gr_pixel_mode_rgb32,       /* 32-bits mode - 16 million colors */
+
+    gr_pixel_mode_max          /* don't remove */
+  
+  } grPixelMode;
+
+
+  /* forward declaration of the surface class */
+  typedef struct grSurface_     grSurface;
+  
+
+ /*********************************************************************
+  *
+  * <Struct>
+  *   grBitmap
+  *
+  * <Description>
+  *   a simple bitmap descriptor
+  *
+  * <Fields>
+  *   rows   :: height in pixels
+  *   width  :: width in pixels
+  *   pitch  :: + or - the number of bytes per row
+  *   mode   :: pixel mode of bitmap buffer
+  *   grays  :: number of grays in palette for PAL8 mode. 0 otherwise
+  *   buffer :: pointer to pixel buffer
+  *
+  * <Note>
+  *   the 'pitch' is positive for downward flows, and negative otherwise
+  *   Its absolute value is always the number of bytes taken by each
+  *   bitmap row.
+  *
+  *   All drawing operations will be performed within the first
+  *   "width" pixels of each row (clipping is always performed).
+  *
+  ********************************************************************/
+
+  typedef struct grBitmap_
+  {
+    int          rows;
+    int          width;
+    int          pitch;
+    grPixelMode  mode;
+    int          grays;
+    char*        buffer;
+
+  } grBitmap;
+
+
+
+  typedef long   grPos;
+  typedef char   grBool;
+
+  typedef struct grVector_
+  {
+    grPos  x;
+    grPos  y;
+    
+  } grVector;
+
+
+  typedef union grColor_
+  {
+    long           value;
+    unsigned char  chroma[4];
+    
+  } grColor;
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grNewBitmap
+  *
+  * <Description>
+  *    creates a new bitmap    
+  *
+  * <Input>
+  *    pixel_mode   :: the target surface's pixel_mode
+  *    num_grays    :: number of grays levels for PAL8 pixel mode
+  *    width        :: width in pixels
+  *    height       :: height in pixels
+  *
+  * <Output>
+  *    bit          :: descriptor of the new bitmap
+  *
+  * <Return>
+  *    Error code. 0 means success.
+  *
+  * <Note>
+  *    This function really allocates a pixel buffer, zero it, then
+  *    returns a descriptor for it.
+  *
+  *    Call grDoneBitmap when you're done with it..
+  *
+  **********************************************************************/
+
+  extern  int  grNewBitmap( grPixelMode  pixel_mode,
+                            int          num_grays,
+                            int          width,
+                            int          height,
+                            grBitmap    *bit );
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grBlitGlyphToBitmap
+  *
+  * <Description>
+  *    writes a given glyph bitmap to a target surface.
+  *
+  * <Input>
+  *    target  :: handle to target bitmap 
+  *    glyph   :: handle to source glyph bitmap
+  *    x       :: position of left-most pixel of glyph image in target surface
+  *    y       :: position of top-most pixel of glyph image in target surface
+  *    color   :: color to be used to draw a monochrome glyph
+  *
+  * <Return>
+  *   Error code. 0 means success
+  *
+  * <Note>
+  *   There are only two supported source pixel modes : monochrome
+  *   and gray. The 8-bit images can have any number of grays between
+  *   2 and 128, and conversions to the target surface is handled
+  *   _automatically_.
+  *
+  *   Note however that you should avoid blitting a gray glyph to a gray
+  *   bitmap with fewer levels of grays, as this would much probably
+  *   give unpleasant results..
+  *
+  *   This function performs clipping
+  *
+  **********************************************************************/
+    
+  extern int   grBlitGlyphToBitmap( grBitmap*  target,
+                                    grBitmap*  glyph,
+                                    grPos      x,
+                                    grPos      y,
+                                    grColor    color );
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grFillRectangle
+  *
+  * <Description>
+  *    this function is used to fill a given rectangle on a surface   
+  *
+  * <Input>
+  *    surface :: handle to target surface
+  *    x       :: x coordinate of the top-left corner of the rectangle
+  *    y       :: y coordinate of the top-left corner of the rectangle
+  *    width   :: rectangle width in pixels
+  *    height  :: rectangle height in pixels
+  *    color   :: fill color
+  *
+  **********************************************************************/
+    
+  extern void  grFillRectangle( grBitmap*  surface,
+                                grPos      x,
+                                grPos      y,
+                                grPos      width,
+                                grPos      height,
+                                grColor    color );
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grWriteCellChar
+  *
+  * <Description>
+  *    The graphics sub-system contains an internal Latin1 8x8 font
+  *    which can be used to display simple strings of text without
+  *    using FreeType.
+  *
+  *    This function writes a single 8x8 character on the target bitmap.
+  *
+  * <Input>
+  *    target   :: handle to target surface
+  *    x        :: x pixel position of character cell's top left corner
+  *    y        :: y pixel position of character cell's top left corner
+  *    charcode :: Latin-1 character code
+  *    color    :: color to be used to draw the character
+  *
+  **********************************************************************/
+  
+  extern
+  void  grWriteCellChar( grBitmap*  target,
+                         int        x,
+                         int        y,
+                         int        charcode,
+                         grColor    color );
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grWriteCellString
+  *
+  * <Description>
+  *    The graphics sub-system contains an internal Latin1 8x8 font
+  *    which can be used to display simple strings of text without
+  *    using FreeType.
+  *
+  *    This function writes a string with the internal font
+  *
+  * <Input>
+  *    target       :: handle to target bitmap  
+  *    x            :: x pixel position of string's top left corner
+  *    y            :: y pixel position of string's top left corner
+  *    string       :: Latin-1 text string
+  *    color        :: color to be used to draw the character
+  *
+  **********************************************************************/
+  
+  extern
+  void  grWriteCellString( grBitmap*   target,
+                           int         x,
+                           int         y,
+                           const char* string,
+                           grColor     color );
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grDoneBitmap
+  *
+  * <Description>
+  *    destroys a bitmap    
+  *
+  * <Input>
+  *    bitmap :: handle to bitmap descriptor
+  *
+  * <Note>
+  *    This function does NOT release the bitmap descriptor, only
+  *    the pixel buffer.
+  *
+  **********************************************************************/
+
+  extern  void  grDoneBitmap( grBitmap*  bit );
+
+
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+ /********                                                         ********/
+ /********         DEVICE-SPECIFIC DEFINITIONS AND ROUTINES        ********/
+ /********                                                         ********/
+ /********                                                         ********/
+ /*************************************************************************/
+ /*************************************************************************/
+ /*************************************************************************/
+
+
+  /* forward declaration - the definition of grDevice is not visible */
+  /* to clients..                                                    */
+  typedef struct grDevice_  grDevice;
+
+
+ /**********************************************************************
+  *
+  * <Struct>
+  *    grDeviceChain
+  *
+  * <Description>
+  *    a simple structure used to implement a linked list of
+  *    graphics device descriptors. The list is called a
+  *    "device chain"
+  *
+  * <Fields>
+  *    name   :: ASCII name of the device, e.g. "x11", "os2pm", etc..
+  *    device :: handle to the device descriptor.
+  *    next   :: next element in chain
+  *
+  * <Note>
+  *    the 'device' field is a blind pointer; it is thus unusable by
+  *    client applications..
+  *
+  **********************************************************************/
+    
+  typedef struct grDeviceChain_  grDeviceChain;
+
+  struct grDeviceChain_
+  {
+    const char*     name;
+    grDevice*       device;
+    grDeviceChain*  next;
+  };
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grInitDevices
+  *
+  * <Description>
+  *    This function is in charge of initialising all system-specific
+  *    devices. A device is responsible for creating and managing one
+  *    or more "surfaces". A surface is either a window or a screen,
+  *    depending on the system.
+  *
+  * <Return>
+  *    a pointer to the first element of a device chain. The chain can
+  *    be parsed to find the available devices on the current system
+  *
+  * <Note>
+  *    If a device cannot be initialised correctly, it is not part of
+  *    the device chain returned by this function. For example, if an
+  *    X11 device was compiled in the library, it will be part of
+  *    the returned device chain only if a connection to the display
+  *    could be establisged
+  *
+  *    If no driver could be initialised, this function returns NULL.
+  *
+  **********************************************************************/
+    
+  extern
+  grDeviceChain*  grInitDevices( void );
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grGetDeviceModes
+  *
+  * <Description>
+  *    queries the available pixel modes for a device.
+  *
+  * <Input>
+  *    device_name  :: name of device to be used. 0 for the default
+  *                    device. For a list of available devices, see
+  *                    grInitDevices.
+  *
+  * <Output>
+  *    num_modes    :: number of available modes. 0 in case of error,
+  *                    which really is an invalid device name.
+  *
+  *    pixel_modes  :: array of available pixel modes for this device
+  *                    this table is internal to the device and should
+  *                    not be freed by client applications.
+  *
+  * <Return>
+  *    error code. 0 means success. invalid device name otherwise
+  *
+  * <Note>
+  *    All drivers are _required_ to support at least the following
+  *    pixel formats :
+  *
+  *    - gr_pixel_mode_mono : i.e. monochrome bitmaps
+  *    - gr_pixel_mode_gray : with any number of gray levels between
+  *                           2 and 256.
+  *
+  *    the pixel modes do not provide the number of grays in the case
+  *    of "gray" devices. You should try to create a surface with the 
+  *    maximal number (256, that is) and see the value returned in
+  *    the bitmap descriptor.
+  *
+  **********************************************************************/
+ 
+  extern void  grGetDeviceModes( const char*    device_name,
+                                 int           *num_modes,
+                                 grPixelMode*  *pixel_modes );
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grNewSurface
+  *
+  * <Description>
+  *    creates a new device-specific surface. A surface is either
+  *    a window or a screen, depending on the device.
+  *
+  * <Input>
+  *    device  :: name of the device to use. A value of NULL means
+  *               the default device (which depends on the system).
+  *               for a list of available devices, see grInitDevices.
+  *
+  * <InOut>
+  *    bitmap  :: handle to a bitmap descriptor containing the
+  *               requested pixel mode, number of grays and dimensions
+  *               for the surface. the bitmap's 'pitch' and 'buffer'
+  *               fields are ignored on input.
+  *
+  *               On output, the bitmap describes the surface's image
+  *               completely. It is possible to write directly in it
+  *               with grBlitGlyphToBitmap, even though the use of
+  *               grBlitGlyphToSurface is recommended.
+  *
+  * <Return>
+  *    handle to the corresponding surface object. 0 in case of error
+  *
+  * <Note>
+  *    All drivers are _required_ to support at least the following
+  *    pixel formats :
+  *
+  *    - gr_pixel_mode_mono : i.e. monochrome bitmaps
+  *    - gr_pixel_mode_gray : with any number of gray levels between
+  *                           2 and 256.
+  *
+  *    This function might change the bitmap descriptor's fields. For
+  *    example, when displaying a full-screen surface, the bitmap's
+  *    dimensions will be set to those of the screen (e.g. 640x480
+  *    or 800x600); also, the bitmap's 'buffer' field might point to
+  *    the Video Ram depending on the mode requested..
+  *
+  *    The surface contains a copy of the returned bitmap descriptor,
+  *    you can thus discard the 'bitmap' parameter after the call.
+  *
+  **********************************************************************/
+    
+  extern grSurface*  grNewSurface( const char*  device,
+                                   grBitmap*    bitmap );
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grRefreshRectangle
+  *
+  * <Description>
+  *    this function is used to indicate that a given surface rectangle
+  *    was modified and thus needs re-painting. It really is useful for
+  *    windowed or gray surfaces.
+  *
+  * <Input>
+  *    surface :: handle to target surface
+  *    x       :: x coordinate of the top-left corner of the rectangle
+  *    y       :: y coordinate of the top-left corner of the rectangle
+  *    width   :: rectangle width in pixels
+  *    height  :: rectangle height in pixels
+  *
+  **********************************************************************/
+    
+  extern void  grRefreshRectangle( grSurface*  surface,
+                                   grPos       x,
+                                   grPos       y,
+                                   grPos       width,
+                                   grPos       height );
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grRefreshSurface
+  *
+  * <Description>
+  *    a variation of grRefreshRectangle which repaints the whole surface
+  *    to the screen.                                                    
+  *
+  * <Input>
+  *    surface :: handle to target surface
+  *
+  **********************************************************************/
+
+  extern void  grRefreshSurface( grSurface*  surface );
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grWriteSurfaceChar
+  *
+  * <Description>
+  *    This function is equivalent to calling grWriteCellChar on the
+  *    surface's bitmap, then invoking grRefreshRectangle.
+  *
+  *    The graphics sub-system contains an internal Latin1 8x8 font
+  *    which can be used to display simple strings of text without
+  *    using FreeType.
+  *
+  *    This function writes a single 8x8 character on the target bitmap.
+  *
+  * <Input>
+  *    target   :: handle to target surface
+  *    x        :: x pixel position of character cell's top left corner
+  *    y        :: y pixel position of character cell's top left corner
+  *    charcode :: Latin-1 character code
+  *    color    :: color to be used to draw the character
+  *
+  **********************************************************************/
+  
+  extern
+  void  grWriteSurfaceChar( grSurface* target,
+                            int        x,
+                            int        y,
+                            int        charcode,
+                            grColor    color );
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grWriteSurfaceString
+  *
+  * <Description>
+  *    This function is equivalent to calling grWriteCellString on the
+  *    surface's bitmap, then invoking grRefreshRectangle.
+  *
+  *    The graphics sub-system contains an internal Latin1 8x8 font
+  *    which can be used to display simple strings of text without
+  *    using FreeType.
+  *
+  *    This function writes a string with the internal font
+  *
+  * <Input>
+  *    target       :: handle to target bitmap  
+  *    x            :: x pixel position of string's top left corner
+  *    y            :: y pixel position of string's top left corner
+  *    string       :: Latin-1 text string
+  *    color        :: color to be used to draw the character
+  *
+  **********************************************************************/
+  
+  extern
+  void  grWriteSurfaceString( grSurface*  target,
+                              int         x,
+                              int         y,
+                              const char* string,
+                              grColor     color );
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grSetTitle
+  *
+  * <Description>
+  *    set the window title of a given windowed surface.
+  *
+  * <Input>
+  *    surface      :: handle to target surface
+  *    title_string :: the new title
+  *
+  **********************************************************************/
+
+  extern void  grSetTitle( grSurface*  surface,
+                           const char* title_string );
+
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grListenSurface
+  *
+  * <Description>
+  *    listen the events for a given surface
+  *
+  * <Input>
+  *    surface    :: handle to target surface
+  *    event_mask :: the event mask (mode)
+  *
+  * <Output>
+  *    event  :: the returned event
+  *
+  * <Note>
+  *    XXX : For now, only keypresses are supported.
+  *
+  **********************************************************************/
+  
+  extern
+  int   grListenSurface( grSurface*  surface,
+                         int         event_mask,
+                         grEvent    *event );
+
+
+#endif /* GRAPH_H */
diff --git a/demos/graph/grblit.c b/demos/graph/grblit.c
new file mode 100644
index 0000000..f0346e1
--- /dev/null
+++ b/demos/graph/grblit.c
@@ -0,0 +1,1268 @@
+/****************************************************************************/
+/*                                                                          */
+/*  The FreeType project -- a free and portable quality TrueType renderer.  */
+/*                                                                          */
+/*  Copyright 1996-1999 by                                                  */
+/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
+/*                                                                          */
+/*  blitter.c: Support for blitting of bitmaps with various depth.          */
+/*                                                                          */
+/****************************************************************************/
+
+#include "grblit.h"
+#include "grobjs.h"
+
+  static
+  int  compute_clips( grBlitter*  blit,
+                      int         x_offset,
+                      int         y_offset )
+  {
+    int  xmin, ymin, xmax, ymax, width, height, target_width;
+
+    /* perform clipping and setup variables */
+    width  = blit->source.width;
+    height = blit->source.rows;
+
+    switch ( blit->source.mode )
+    {
+    case gr_pixel_mode_mono:
+      width = (width + 7) & -8;
+      break;
+
+    case gr_pixel_mode_pal4:
+      width = (width + 1) & -2;
+      break;
+      
+    default:
+      ;
+    }
+
+    xmin = x_offset;
+    ymin = y_offset;
+    xmax = xmin + width-1;
+    ymax = ymin + height-1;
+
+    /* clip if necessary */
+    if ( width == 0 || height == 0                ||
+         xmax < 0   || xmin >= blit->target.width ||
+         ymax < 0   || ymin >= blit->target.rows  )
+      return 1;
+
+    /* set up clipping and cursors */
+    blit->yread = 0;
+    if ( ymin < 0 )
+    {
+      blit->yread  -= ymin;
+      height       += ymin;
+      blit->ywrite  = 0;
+    }
+    else
+      blit->ywrite  = ymin;
+
+    if ( ymax >= blit->target.rows )
+      height -= ymax - blit->target.rows + 1;
+
+    blit->xread = 0;
+    if ( xmin < 0 )
+    {
+      blit->xread  -= xmin;
+      width        += xmin;
+      blit->xwrite  = 0;
+    }
+    else
+      blit->xwrite  = xmin;
+
+    target_width = blit->target.width;
+
+    switch ( blit->target.mode )
+    {
+    case gr_pixel_mode_mono:
+      target_width = (target_width + 7) & -8;
+      break;
+    case gr_pixel_mode_pal4:
+      target_width = (target_width + 1) & -2;
+      break;
+      
+    default:
+      ;
+    }
+
+    blit->right_clip = xmax - target_width + 1;
+    if ( blit->right_clip > 0 )
+      width -= blit->right_clip;
+    else
+      blit->right_clip = 0;
+
+    blit->width  = width;
+    blit->height = height;
+
+    /* set read and write to the top-left corner of the read */
+    /* and write areas before clipping.                      */
+
+    blit->read  = (unsigned char*)blit->source.buffer;
+    blit->write = (unsigned char*)blit->target.buffer;
+
+    blit->read_line  = blit->source.pitch;
+    blit->write_line = blit->target.pitch;
+    
+    if ( blit->read_line < 0 )
+      blit->read -= (blit->source.rows-1) * blit->read_line;
+
+    if ( blit->write_line < 0 )
+      blit->write -= (blit->target.rows-1) * blit->write_line;
+
+    /* now go to the start line. Note that we do not move the   */
+    /* x position yet, as this is dependent on the pixel format */
+    blit->read  += blit->yread * blit->read_line;
+    blit->write += blit->ywrite * blit->write_line;
+
+    return 0;
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_mono_to_mono                                           */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_mono_to_mono( grBlitter*  blit,
+                           grColor     color )
+  {
+    int    shift, left_clip, x, y;
+    byte*  read;
+    byte*  write;
+
+    (void)color;   /* unused argument */
+
+    left_clip = ( blit->xread > 0 );
+    shift     = ( blit->xwrite - blit->xread ) & 7;
+
+    read  = blit->read  + (blit->xread >> 3);
+    write = blit->write + (blit->xwrite >> 3);
+
+    if ( shift == 0 )
+    {
+      y = blit->height;
+      do
+      {
+        byte*  _read  = read;
+        byte*  _write = write;
+
+        x = blit->width;
+
+        do
+        {
+          *_write++ |= *_read++;
+          x -= 8;
+        } while ( x > 0 );
+
+        read  += blit->read_line;
+        write += blit->write_line;
+        y--;
+      } while ( y > 0 );
+    }
+    else
+    {
+      int  first, last, count;
+
+
+      first = blit->xwrite >> 3;
+      last  = (blit->xwrite + blit->width-1) >> 3;
+
+      count = last - first;
+
+      if ( blit->right_clip )
+        count++;
+
+      y = blit->height;
+
+      do
+      {
+        unsigned char*  _read  = read;
+        unsigned char*  _write = write;
+        unsigned char   old;
+        int             shift2 = (8-shift);
+
+        if ( left_clip )
+          old = (*_read++) << shift2;
+        else
+          old = 0;
+
+        x = count;
+        while ( x > 0 )
+        {
+          unsigned char val;
+
+          val = *_read++;
+          *_write++ |= ( (val >> shift) | old );
+          old = val << shift2;
+          x--;
+        }
+
+        if ( !blit->right_clip )
+          *_write |= old;
+
+        read  += blit->read_line;
+        write += blit->write_line;
+        y--;
+
+      } while ( y > 0 );
+    }
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_mono_to_pal8                                           */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_mono_to_pal8( grBlitter*  blit,
+                           grColor     color )
+  {
+    int             x, y;
+    unsigned int    left_mask;
+    unsigned char*  read;
+    unsigned char*  write;
+
+    read  = blit->read  + (blit->xread >> 3);
+    write = blit->write +  blit->xwrite;
+
+    left_mask = 0x80 >> (blit->xread & 7);
+
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      unsigned int    mask   = left_mask;
+      unsigned int    val    = *_read;
+
+
+      x = blit->width;
+      do
+      {
+        if ( mask == 0x80 )
+          val = *_read++;
+          
+        if ( val & mask )
+          *_write = (unsigned char)color.value;
+
+        mask >>= 1;
+        if ( mask == 0 )
+          mask = 0x80;
+
+        _write++;
+        x--;
+      } while ( x > 0 );
+
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    } while ( y > 0 );
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_mono_to_pal4                                           */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_mono_to_pal4( grBlitter*  blit,
+                           grColor     color )
+  {
+    int             x, y, phase;
+    unsigned int    left_mask;
+    unsigned char*  read;
+    unsigned char*  write;
+    unsigned char   col;
+
+
+    col   = color.value & 15;
+    read  = blit->read  + (blit->xread >> 3);
+    write = blit->write + (blit->xwrite >> 1);
+
+    /* now begin blit */
+    left_mask = 0x80 >> (blit->xread & 7);
+    phase     = blit->xwrite & 1;
+
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      unsigned int    mask   = left_mask;
+      int             _phase = phase;
+      unsigned int    val    = *_read;
+
+      x = blit->width;
+      do
+      {
+        if ( mask == 0x80 )
+          val = *_read++;
+
+        if ( val & mask )
+        {
+          if ( _phase )
+            *_write = (*_write & 0xF0) | col;
+          else
+            *_write = (*_write & 0x0F) | (col << 4);
+        }
+
+        mask >>= 1;
+        if ( mask == 0 )
+          mask = 0x80;
+
+        _write += _phase;
+        _phase ^= 1;
+        x--;
+      } while ( x > 0 );
+
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    } while ( y > 0 );
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_mono_to_rgb16                                          */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_mono_to_rgb16( grBlitter*  blit,
+                            grColor     color )
+  {
+    int              x, y;
+    unsigned int     left_mask;
+    unsigned char*   read;
+    unsigned char*   write;
+    
+    read  = blit->read + (blit->xread >> 3);
+    write = blit->write + blit->xwrite*2;
+
+    left_mask = 0x80 >> (blit->xread & 7);
+
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      unsigned int    mask   = left_mask;
+      unsigned int    val    = *_read;
+
+      x = blit->width;
+      do
+      {
+        if ( mask == 0x80 )
+          val = *_read++;
+
+        if ( val & mask )
+          *(short*)_write = (short)color.value;
+
+        mask >>= 1;
+        if ( mask == 0 )
+          mask = 0x80;
+
+        _write +=2;
+        x--;
+      } while ( x > 0 );
+
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    } while ( y > 0 );
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_mono_to_rgb24                                          */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_mono_to_rgb24( grBlitter*  blit,
+                            grColor     color )
+  {
+    int             x, y;
+    unsigned int    left_mask;
+    unsigned char*  read;
+    unsigned char*  write;
+    
+    read  = blit->read  + (blit->xread >> 3);
+    write = blit->write + blit->xwrite*3;
+
+    left_mask = 0x80 >> (blit->xread & 7);
+
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      unsigned int    mask   = left_mask;
+      unsigned int    val    = *_read;
+
+      x = blit->width;
+      do
+      {
+        if ( mask == 0x80 )
+          val = *_read++;
+
+        if ( val & mask )
+        {
+          _write[0] = color.chroma[0];
+          _write[1] = color.chroma[1];
+          _write[2] = color.chroma[2];
+        }
+
+        mask >>= 1;
+        if ( mask == 0 )
+          mask = 0x80;
+
+        _write += 3;
+        x--;
+      } while ( x > 0 );
+
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    } while ( y > 0 );
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_mono_to_rgb32                                          */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_mono_to_rgb32( grBlitter*  blit,
+                            grColor     color )
+  {
+    int             x, y;
+    unsigned int    left_mask;
+    unsigned char*  read;
+    unsigned char*  write;
+     
+    read  = blit->read  + (blit->xread >> 3);
+    write = blit->write + blit->xwrite*4;
+
+    left_mask = 0x80 >> (blit->xread & 7);
+
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      unsigned int    mask   = left_mask;
+      unsigned int    val    = *_read;
+
+      x = blit->width;
+      do
+      {
+        if ( mask == 0x80 )
+          val = *_read++;
+
+        if ( val & mask )
+        {
+   /* this could be greatly optimised as a *(long*)_write = color.value */
+   /* but this wouldn't work on 64-bits systems... stupid C types!      */
+          _write[0] = color.chroma[0];
+          _write[1] = color.chroma[1];
+          _write[2] = color.chroma[2];
+          _write[3] = color.chroma[3];
+        }
+
+        mask >>= 1;
+        if ( mask == 0 )
+          mask = 0x80;
+
+        _write += 4;
+        x--;
+      } while ( x > 0 );
+
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    } while ( y > 0 );
+  }
+
+
+
+  static
+  const grBlitterFunc  gr_mono_blitters[gr_pixel_mode_max] =
+  {
+    0,
+    blit_mono_to_mono,
+    blit_mono_to_pal4,
+    blit_mono_to_pal8,
+    blit_mono_to_pal8,
+    blit_mono_to_rgb16,
+    blit_mono_to_rgb16,
+    blit_mono_to_rgb24,
+    blit_mono_to_rgb32
+  };
+
+
+  /*******************************************************************/
+  /*                                                                 */
+  /*                    Saturation tables                            */
+  /*                                                                 */
+  /*******************************************************************/
+
+  typedef struct grSaturation_
+  {
+    int          count;
+    const byte*  table;
+  
+  } grSaturation;
+  
+  
+  static
+  const byte  gr_saturation_5[8] = { 0, 1, 2, 3, 4, 4, 4, 4 };
+  
+
+  static
+  const byte  gr_saturation_17[32] =
+  {
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
+  };
+
+
+  static
+  grSaturation  gr_saturations[ GR_MAX_SATURATIONS ] =
+  {
+    {  5, gr_saturation_5  },
+    { 17, gr_saturation_17 }
+  };
+
+  static
+  int  gr_num_saturations = 2;
+
+  static
+  grSaturation*  gr_last_saturation = gr_saturations;
+
+
+  extern
+  const byte*  grGetSaturation( int  num_grays )
+  {
+    /* first of all, scan the current saturations table */
+    grSaturation*  sat   = gr_saturations;
+    grSaturation*  limit = sat + gr_num_saturations;
+
+    if ( num_grays < 2 )
+    {
+      grError = gr_err_bad_argument;
+      return 0;
+    }
+     
+    for ( ; sat < limit; sat++ )
+    {
+      if ( sat->count == num_grays )
+      {
+        gr_last_saturation = sat;
+        return sat->table;
+      }
+    }
+    
+    /* not found, simply create a new entry if there is room */
+    if (gr_num_saturations < GR_MAX_SATURATIONS)
+    {
+      int          i;
+      const byte*  table;
+      
+      table = (const byte*)grAlloc( (3*num_grays-1)*sizeof(byte) );
+      if (!table) return 0;
+        
+      sat->count = num_grays;
+      sat->table = table;
+      
+      for ( i = 0; i < num_grays; i++, table++ )
+        *(unsigned char*)table = (unsigned char)i;  
+      
+      for ( i = 2*num_grays-1; i > 0; i--, table++ )
+        *(unsigned char*)table = (unsigned char)(num_grays-1);   
+        
+      gr_num_saturations++;
+      gr_last_saturation = sat;
+      return sat->table;
+    }
+    grError = gr_err_saturation_overflow;
+    return 0;
+  }
+
+
+
+  /*******************************************************************/
+  /*                                                                 */
+  /*                    conversion tables                            */
+  /*                                                                 */
+  /*******************************************************************/
+
+  typedef struct grConversion_
+  {
+    int          target_grays;
+    int          source_grays;
+    const byte*  table;
+  
+  } grConversion;
+  
+  
+  
+  static
+  const byte  gr_gray5_to_gray17[5] = { 0, 4, 8, 12, 16 };
+
+
+  static
+  const byte  gr_gray5_to_gray128[5] = { 0, 32, 64, 96, 127 };
+
+
+  static
+  const unsigned char  gr_gray17_to_gray128[17] =
+  {
+    0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 127
+  };
+
+  static
+  grConversion  gr_conversions[ GR_MAX_CONVERSIONS ] =
+  {
+    {  17,  5, gr_gray5_to_gray17   },
+    { 128,  5, gr_gray5_to_gray128  },
+    { 128, 17, gr_gray17_to_gray128 }
+  };
+
+  static
+  int  gr_num_conversions = 3;
+
+  static
+  grConversion*  gr_last_conversion = gr_conversions;
+
+
+  extern
+  const byte*  grGetConversion( int  target_grays,
+                                int  source_grays )
+  {
+    grConversion*  conv  = gr_conversions;
+    grConversion*  limit = conv + gr_num_conversions;
+   
+    if ( target_grays < 2 || source_grays < 2 )
+    {
+      grError = gr_err_bad_argument;
+      return 0;
+    }
+    
+    /* otherwise, scan table */
+    for ( ; conv < limit; conv++ )
+    {
+      if ( conv->target_grays == target_grays &&
+           conv->source_grays == source_grays )
+      {
+        gr_last_conversion = conv;
+        return conv->table;
+      }
+    }
+    
+    /* not found, add a new conversion to the table */
+    if (gr_num_conversions < GR_MAX_CONVERSIONS)
+    {
+      const byte*  table;
+      int          n;
+
+      table = (const byte*)grAlloc( source_grays*sizeof(byte) );
+      if (!table)
+        return 0;
+        
+      conv->target_grays = target_grays;
+      conv->source_grays = source_grays;
+      conv->table        = table;
+
+      for ( n = 0; n < source_grays; n++ )
+        ((unsigned char*)table)[n] = (unsigned char)(n*(target_grays-1)) / 
+                                         (source_grays-1);
+            
+      gr_num_conversions++;
+      gr_last_conversion = conv;
+      return table;
+    }
+    grError = gr_err_conversion_overflow;
+    return 0;
+  }
+
+
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_gray_to_gray                                           */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_gray_to_gray( grBlitter*   blit,
+                           const byte*  saturation,
+                           const byte*  conversion )
+  {
+    int             y;
+    unsigned char*  read;
+    unsigned char*  write;
+    unsigned char   max1;
+    unsigned char   max2;
+
+    max1  = (unsigned char)(blit->source.grays-1);
+    max2  = (unsigned char)(blit->target.grays-1);
+    
+    read  = (unsigned char*)blit->read  + blit->xread;
+    write = (unsigned char*)blit->write + blit->xwrite;
+
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      int             x      = blit->width;
+
+      while (x > 0)
+      {
+#ifdef GR_CONFIG_GRAY_SKIP_WHITE
+        unsigned char val = *_read;
+        
+        if (val)
+        {
+          if (val == max)
+            *_write = max2;
+          else
+            *_write = saturation[ (int)*_write + conversion[ *_read ] ];
+        }
+#else
+        *_write = saturation[ (int)*_write + conversion[ *_read ] ];
+#endif
+        _write++;
+        _read++;
+        x--;
+      }
+      
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    }
+    while (y > 0);
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_gray_to_gray_simple                                    */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_gray_to_gray_simple( grBlitter*   blit,
+                                  const byte*  saturation )
+  {
+    int             y;
+    unsigned char*  read;
+    unsigned char*  write;
+    unsigned char   max;
+
+    max   = (unsigned char)(blit->source.grays-1);
+    
+    read  = (unsigned char*)blit->read  + blit->xread;
+    write = (unsigned char*)blit->write + blit->xwrite;
+
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      int             x      = blit->width;
+
+      while (x > 0)
+      {
+#ifdef GR_CONFIG_GRAY_SKIP_WHITE
+        unsigned char val = *_read;
+        
+        if (val)
+        {
+          if (val == max)
+            *_write = val;
+          else
+            *_write = saturation[ (int)*_write + *_read ];
+        }
+#else
+        *_write = saturation[ (int)*_write + *_read ];
+#endif
+        _write++;
+        _read++;
+        x--;
+      }
+      
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    }
+    while (y > 0);
+  }
+
+
+
+#define  compose_pixel( a, b, n, max )       \
+   {                                         \
+     int  d, half = max >> 1;                \
+                                             \
+     d = (int)b.chroma[0] - a.chroma[0]; \
+     a.chroma[0] += (n*d + half)/max;      \
+                                             \
+     d = (int)b.chroma[1] - a.chroma[1]; \
+     a.chroma[1] += (n*d + half)/max;      \
+                                             \
+     d = (int)b.chroma[2] - a.chroma[2]; \
+     a.chroma[2] += (n*d + half)/max;      \
+   }
+
+
+#define  extract555( pixel, color )           \
+   color.chroma[0] = (pixel >> 10) & 0x1F;  \
+   color.chroma[1] = (pixel >>  5) & 0x1F;  \
+   color.chroma[2] = (pixel      ) & 0x1F;
+   
+
+#define  extract565( pixel, color )           \
+   color.chroma[0] = (pixel >> 11) & 0x1F;  \
+   color.chroma[1] = (pixel >>  5) & 0x3F;  \
+   color.chroma[2] = (pixel      ) & 0x1F;
+
+
+#define  inject555( color )                           \
+   ( ( (unsigned short)color.chroma[0] << 10 ) |    \
+     ( (unsigned short)color.chroma[1] <<  5 ) |    \
+       color.chroma[2]                         )
+      
+
+#define  inject565( color )         \
+   ( ( (unsigned short)color.chroma[0] << 11 ) |    \
+     ( (unsigned short)color.chroma[1] <<  5 ) |    \
+       color.chroma[2]                         )
+      
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_gray_to_555                                            */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_gray_to_555( grBlitter*  blit,
+                          grColor     color,
+                          int         max )
+  {
+    int             y;
+    unsigned char*  read;
+    unsigned char*  write;
+    long            color2;
+
+    read   = blit->read  + blit->xread;
+    write  = blit->write + 2*blit->xwrite;
+    
+    /* convert color to R:G:B triplet */
+    color2 = color.value;
+    extract555( color2, color );
+
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      int             x      = blit->width;
+
+      while (x > 0)
+      {
+        unsigned char   val;
+        
+        val = *_read;
+        if (val)
+        {
+          unsigned short* pixel = (unsigned short*)_write;
+          
+          if (val == max)
+          {
+            pixel[0] = (short)color2;
+          }
+          else
+          {
+            /* compose gray value */
+            unsigned short  pix16 = *pixel;
+            grColor         pix;
+            
+            extract555( pix16, pix );
+
+            compose_pixel( pix, color, val, max );
+            *pixel = inject555(pix);
+          }  
+        }
+        _write += 2;
+        _read  ++;
+        x--;
+      }
+      
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    }
+    while (y > 0);
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_gray_to_565                                            */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_gray_to_565( grBlitter*  blit,
+                          grColor     color,
+                          int         max )
+  {
+    int             y;
+    unsigned char*  read;
+    unsigned char*  write;
+    long            color2;
+
+    read   = blit->read  + blit->xread;
+    write  = blit->write + 2*blit->xwrite;
+    
+    color2 = color.value;
+    extract565( color2, color );
+
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      int             x      = blit->width;
+
+      while (x > 0)
+      {
+        unsigned char    val;
+        
+        val = *_read;
+        if (val)
+        {
+          unsigned short* pixel = (unsigned short*)_write;
+          
+          if (val == max)
+          {
+            pixel[0] = (short)color2;
+          }
+          else
+          {
+            /* compose gray value */
+            unsigned short  pix16 = *pixel;
+            grColor         pix;
+
+            extract565( pix16, pix );            
+
+            compose_pixel( pix, color, val, max );
+            *pixel = inject565( pix );
+          }  
+        }
+        _write +=2;
+        _read  ++;
+        x--;
+      }
+      
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    }
+    while (y > 0);
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_gray_to_24                                             */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_gray_to_24( grBlitter*  blit,
+                         grColor     color,
+                         int         max )
+  {
+    int             y;
+    unsigned char*  read;
+    unsigned char*  write;
+
+    read   = blit->read  + blit->xread;
+    write  = blit->write + 3*blit->xwrite;
+    
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      int             x      = blit->width;
+
+      while (x > 0)
+      {
+        unsigned char    val;
+        
+        val = *_read;
+        if (val)
+        {
+          if (val == max)
+          {
+            _write[0] = color.chroma[0];
+            _write[1] = color.chroma[1];
+            _write[2] = color.chroma[2];
+          }
+          else
+          {
+            /* compose gray value */
+            grColor pix;
+            
+            pix.chroma[0] = _write[0];
+            pix.chroma[1] = _write[1];
+            pix.chroma[2] = _write[2];
+
+            compose_pixel( pix, color, val, max );
+            
+            _write[0] = pix.chroma[0];
+            _write[1] = pix.chroma[1];
+            _write[2] = pix.chroma[2];
+          }  
+        }
+        _write += 3;
+        _read  ++;
+        x--;
+      }
+      
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    }
+    while (y > 0);
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> blit_gray_to_32                                             */
+/*                                                                        */
+/**************************************************************************/
+
+  static
+  void  blit_gray_to_32( grBlitter*  blit,
+                         grColor     color,
+                         int         max )
+  {
+    int             y;
+    unsigned char*  read;
+    unsigned char*  write;
+
+    read   = blit->read  + blit->xread;
+    write  = blit->write + 4*blit->xwrite;
+    
+    y = blit->height;
+    do
+    {
+      unsigned char*  _read  = read;
+      unsigned char*  _write = write;
+      int             x      = blit->width;
+
+      while (x > 0)
+      {
+        unsigned char  val;
+        
+        val = *_read;
+        if (val)
+        {
+          if (val == max)
+          {
+            _write[0] = color.chroma[0];
+            _write[1] = color.chroma[1];
+            _write[2] = color.chroma[2];
+            _write[3] = color.chroma[3];
+          }
+          else
+          {
+            /* compose gray value */
+            grColor pix;
+            
+            pix.chroma[0] = _write[0];
+            pix.chroma[1] = _write[1];
+            pix.chroma[2] = _write[2];
+
+            compose_pixel( pix, color, val, max );
+            
+            _write[0] = pix.chroma[0];
+            _write[1] = pix.chroma[1];
+            _write[2] = pix.chroma[2];
+          }  
+        }
+        _write += 4;
+        _read  ++;
+        x--;
+      }
+      
+      read  += blit->read_line;
+      write += blit->write_line;
+      y--;
+    }
+    while (y > 0);
+  }
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grBlitGlyphBitmap
+  *
+  * <Description>
+  *    writes a given glyph bitmap to a target surface.
+  *
+  * <Input>
+  *    surface :: handle to target surface
+  *    x       :: position of left-most pixel of glyph image in surface
+  *    y       :: position of top-most pixel of glyph image in surface
+  *    bitmap  :: source glyph image
+  *
+  * <Return>
+  *   Error code. 0 means success
+  *
+  **********************************************************************/
+    
+  typedef  void (*grColorGlyphBlitter)( grBlitter*  blit,
+                                        grColor     color,
+                                        int         max_gray );
+
+  static
+  const grColorGlyphBlitter  gr_color_blitters[gr_pixel_mode_max] =
+  {
+    0,
+    0,
+    0,
+    0,
+    blit_gray_to_555,
+    blit_gray_to_565,
+    blit_gray_to_24,
+    blit_gray_to_32
+  };  
+
+   
+  extern int  grBlitGlyphToBitmap( grBitmap*  target,
+                                   grBitmap*  glyph,
+                                   grPos      x,
+                                   grPos      y,
+                                   grColor    color )
+  {
+    grBlitter    blit;
+    grPixelMode  mode;
+  
+    /* check arguments */
+    if (!target || !glyph)
+    {
+      grError = gr_err_bad_argument;
+      return -1;
+    }
+    
+
+    /* set up blitter and compute clipping. Return immediately if needed */
+    blit.source = *glyph;
+    blit.target = *target;
+    mode        = target->mode;
+
+    if ( compute_clips( &blit, x, y ) )
+      return 0;
+    
+
+    /* handle monochrome bitmap blitting */
+    if (glyph->mode == gr_pixel_mode_mono)
+    {
+      if ( mode <= gr_pixel_mode_none || mode >= gr_pixel_mode_max )
+      {
+        grError = gr_err_bad_source_depth;
+        return -1;
+      }
+      
+      gr_mono_blitters[mode]( &blit, color );
+      goto End;     
+    }
+    
+    /* handle gray bitmap composition */
+    if (glyph->mode == gr_pixel_mode_gray &&
+        glyph->grays > 1                  )
+    {
+      int          target_grays = target->grays;
+      int          source_grays = glyph->grays;
+      const byte*  saturation;
+      
+      if ( mode == gr_pixel_mode_gray && target_grays > 1 )
+      {
+        /* rendering into a gray target - use special composition */
+        /* routines..                                             */
+        if ( gr_last_saturation->count == target_grays )
+          saturation = gr_last_saturation->table;
+        else
+        {
+          saturation = grGetSaturation( target_grays );
+          if (!saturation) return -3;
+        }
+
+
+        if ( target_grays == source_grays )
+          blit_gray_to_gray_simple( &blit, saturation );
+        else
+        {
+          const byte*  conversion;
+
+          if ( gr_last_conversion->target_grays == target_grays &&
+               gr_last_conversion->source_grays == source_grays )
+            conversion = gr_last_conversion->table;
+          else
+          {
+            conversion = grGetConversion( target_grays, source_grays );
+            if (!conversion) return -3;
+          };
+              
+          blit_gray_to_gray( &blit, saturation, conversion );
+        }
+      }
+      else
+      {
+        /* rendering into a color target */
+        if ( mode <= gr_pixel_mode_gray ||
+             mode >= gr_pixel_mode_max  )
+        {
+          grError = gr_err_bad_target_depth;
+          return -1;
+        }
+        
+        gr_color_blitters[mode]( &blit, color, source_grays-1 );
+      }
+      goto End;      
+    }
+    
+    /* we don't support the blitting of bitmaps of the following  */
+    /* types : pal4, pal8, rgb555, rgb565, rgb24, rgb32           */
+    /*                                                            */
+    grError = gr_err_bad_source_depth;
+    return -2;
+    
+  End:
+    return 0;
+  }
+
+
+/* End */
diff --git a/demos/graph/grblit.h b/demos/graph/grblit.h
new file mode 100644
index 0000000..4d0b6e5
--- /dev/null
+++ b/demos/graph/grblit.h
@@ -0,0 +1,25 @@
+/****************************************************************************/
+/*                                                                          */
+/*  The FreeType project -- a free and portable quality TrueType renderer.  */
+/*                                                                          */
+/*  Copyright 1996-1999 by                                                  */
+/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
+/*                                                                          */
+/*  blitter.h: Support for blitting of bitmaps with various depth.          */
+/*                                                                          */
+/****************************************************************************/
+
+#ifndef GRBLIT_H
+#define GRBLIT_H
+
+#include "grobjs.h"
+
+  int  grBlitMono( grBitmap*  target,
+                   grBitmap*  source,
+                   int        x_offset,
+                   int        y_offset,
+                   grColor    color );
+
+
+#endif /* GRBLIT_H */
+/* End */
diff --git a/demos/graph/grconfig.h b/demos/graph/grconfig.h
new file mode 100644
index 0000000..02d8f4d
--- /dev/null
+++ b/demos/graph/grconfig.h
@@ -0,0 +1,9 @@
+#ifndef GRCONFIG_H
+#define GRCONFIG_H
+
+#define GR_MAX_SATURATIONS  8
+#define GR_MAX_CONVERSIONS  16
+
+#define GR_MAX_DEVICES  8
+
+#endif /* GRCONFIG_H */
diff --git a/demos/graph/grdevice.c b/demos/graph/grdevice.c
new file mode 100644
index 0000000..3d2eb28
--- /dev/null
+++ b/demos/graph/grdevice.c
@@ -0,0 +1,361 @@
+#include "grobjs.h"
+#include "grdevice.h"
+#include <stdlib.h>
+
+  grDeviceChain   gr_device_chain[ GR_MAX_DEVICES ];
+  int             gr_num_devices = 0;
+
+  static
+  grDevice*  find_device( const char*  device_name )
+  {
+    int  index = 0;
+    
+    if (device_name)
+    {
+      for ( index = gr_num_devices-1; index > 0; index-- )
+        if ( strcmp( device_name, gr_device_chain[index].name ) == 0 )
+          break;
+    }
+    
+    if ( index < 0 || gr_num_devices <= 0 || !gr_device_chain[index].device )
+    {
+      grError = gr_err_invalid_device;
+      return 0;
+    }
+    
+    return gr_device_chain[index].device;
+  }
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grGetDeviceModes
+  *
+  * <Description>
+  *    queries the available pixel modes for a device.
+  *
+  * <Input>
+  *    device_name  :: name of device to be used. 0 for the default
+  *                    device. For a list of available devices, see
+  *                    grInitDevices.
+  *
+  * <Output>
+  *    num_modes    :: number of available modes. 0 in case of error,
+  *                    which really is an invalid device name.
+  *
+  *    pixel_modes  :: array of available pixel modes for this device
+  *                    this table is internal to the device and should
+  *                    not be freed by client applications.
+  *
+  * <Return>
+  *    error code. 0 means success. invalid device name otherwise
+  *
+  * <Note>
+  *    All drivers are _required_ to support at least the following
+  *    pixel formats :
+  *
+  *    - gr_pixel_mode_mono : i.e. monochrome bitmaps
+  *    - gr_pixel_mode_gray : with any number of gray levels between
+  *                           2 and 256.
+  *
+  *    the pixel modes do not provide the number of grays in the case
+  *    of "gray" devices. You should try to create a surface with the 
+  *    maximal number (256, that is) and see the value returned in
+  *    the bitmap descriptor.
+  *
+  **********************************************************************/
+ 
+  extern void grGetDeviceModes( const char*    device_name,
+                                int           *num_modes,
+                                grPixelMode*  *pixel_modes )
+  {
+    grDevice*  device;
+    
+    *num_modes   = 0;
+    *pixel_modes = 0;
+
+    device = find_device( device_name );
+    if (device)
+    {
+      *num_modes   = device->num_pixel_modes;
+      *pixel_modes = device->pixel_modes;
+    }
+  }
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grNewSurface
+  *
+  * <Description>
+  *    creates a new device-specific surface. A surface is either
+  *    a window or a screen, depending on the device.
+  *
+  * <Input>
+  *    device  :: name of the device to use. A value of NULL means
+  *               the default device (which depends on the system).
+  *               for a list of available devices, see grInitDevices.
+  *
+  * <InOut>
+  *    bitmap  :: handle to a bitmap descriptor containing the
+  *               requested pixel mode, number of grays and dimensions
+  *               for the surface. the bitmap's 'pitch' and 'buffer'
+  *               fields are ignored on input.
+  *
+  *               On output, the bitmap describes the surface's image
+  *               completely. It is possible to write directly in it
+  *               with grBlitGlyphToBitmap, even though the use of
+  *               grBlitGlyphToSurface is recommended.
+  *
+  * <Return>
+  *    handle to the corresponding surface object. 0 in case of error
+  *
+  * <Note>
+  *    All drivers are _required_ to support at least the following
+  *    pixel formats :
+  *
+  *    - gr_pixel_mode_mono : i.e. monochrome bitmaps
+  *    - gr_pixel_mode_gray : with any number of gray levels between
+  *                           2 and 256.
+  *
+  *    This function might change the bitmap descriptor's fields. For
+  *    example, when displaying a full-screen surface, the bitmap's
+  *    dimensions will be set to those of the screen (e.g. 640x480
+  *    or 800x600); also, the bitmap's 'buffer' field might point to
+  *    the Video Ram depending on the mode requested..
+  *
+  *    The surface contains a copy of the returned bitmap descriptor,
+  *    you can thus discard the 'bitmap' parameter after the call.
+  *
+  **********************************************************************/
+    
+  extern grSurface*  grNewSurface( const char*  device_name,
+                                   grBitmap*    bitmap )
+  {
+    grDevice*   device;
+    grSurface*  surface;
+
+    /* Now find the device */
+    device = find_device( device_name );
+    if (!device) return 0;
+
+    surface = (grSurface*)grAlloc( device->surface_objsize );
+    if (!surface) return 0;
+    
+    if ( !device->init_surface( surface, bitmap ) )
+    {
+      grFree( surface );
+      surface = 0;
+    }
+    return surface;
+  }
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grRefreshRectangle
+  *
+  * <Description>
+  *    this function is used to indicate that a given surface rectangle
+  *    was modified and thus needs re-painting. It really is useful for
+  *    windowed or gray surfaces.
+  *
+  * <Input>
+  *    surface :: handle to target surface
+  *    x       :: x coordinate of the top-left corner of the rectangle
+  *    y       :: y coordinate of the top-left corner of the rectangle
+  *    width   :: rectangle width in pixels
+  *    height  :: rectangle height in pixels
+  *
+  **********************************************************************/
+    
+  extern void  grRefreshRectangle( grSurface*  surface,
+                                   grPos       x,
+                                   grPos       y,
+                                   grPos       width,
+                                   grPos       height )
+  {
+    if (surface->refresh_rect)
+      surface->refresh_rect( surface, x, y, width, height );
+  }
+
+
+ 
+ /**********************************************************************
+  *
+  * <Function>
+  *    grWriteSurfaceChar
+  *
+  * <Description>
+  *    This function is equivalent to calling grWriteCellChar on the
+  *    surface's bitmap, then invoking grRefreshRectangle.
+  *
+  *    The graphics sub-system contains an internal Latin1 8x8 font
+  *    which can be used to display simple strings of text without
+  *    using FreeType.
+  *
+  *    This function writes a single 8x8 character on the target bitmap.
+  *
+  * <Input>
+  *    target   :: handle to target surface
+  *    x        :: x pixel position of character cell's top left corner
+  *    y        :: y pixel position of character cell's top left corner
+  *    charcode :: Latin-1 character code
+  *    color    :: color to be used to draw the character
+  *
+  **********************************************************************/
+  
+  extern
+  void  grWriteSurfaceChar( grSurface* target,
+                            int        x,
+                            int        y,
+                            int        charcode,
+                            grColor    color )
+  {
+    grWriteCellChar( &target->bitmap, x, y, charcode, color );
+    if (target->refresh_rect)
+      target->refresh_rect( target, x, y, 8, 8 );
+  }
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grWriteSurfaceString
+  *
+  * <Description>
+  *    This function is equivalent to calling grWriteCellString on the
+  *    surface's bitmap, then invoking grRefreshRectangle.
+  *
+  *    The graphics sub-system contains an internal Latin1 8x8 font
+  *    which can be used to display simple strings of text without
+  *    using FreeType.
+  *
+  *    This function writes a string with the internal font
+  *
+  * <Input>
+  *    target       :: handle to target bitmap  
+  *    x            :: x pixel position of string's top left corner
+  *    y            :: y pixel position of string's top left corner
+  *    string       :: Latin-1 text string
+  *    color        :: color to be used to draw the character
+  *
+  **********************************************************************/
+  
+  extern
+  void  grWriteSurfaceString( grSurface*  target,
+                              int         x,
+                              int         y,
+                              const char* string,
+                              grColor     color )
+  {
+    int  len;
+
+    len = strlen(string);
+    grWriteCellString( &target->bitmap, x, y, string, color );
+    if (target->refresh_rect)
+      target->refresh_rect( target, x, y, 8*len, 8 );
+  }
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grRefreshSurface
+  *
+  * <Description>
+  *    a variation of grRefreshRectangle which repaints the whole surface
+  *    to the screen.                                                    
+  *
+  * <Input>
+  *    surface :: handle to target surface
+  *
+  **********************************************************************/
+
+  extern void  grRefreshSurface( grSurface*  surface )
+  {
+    if (surface->refresh_rect)
+      surface->refresh_rect( surface, 0, 0,
+                             surface->bitmap.width,
+                             surface->bitmap.rows );
+  }
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grSetTitle
+  *
+  * <Description>
+  *    set the window title of a given windowed surface.
+  *
+  * <Input>
+  *    surface      :: handle to target surface
+  *    title_string :: the new title
+  *
+  **********************************************************************/
+
+  extern void  grSetTitle( grSurface*  surface,
+                           const char* title_string )
+  {
+    if (surface->set_title)
+      surface->set_title( surface, title_string );
+  }
+
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grListenSurface
+  *
+  * <Description>
+  *    listen the events for a given surface
+  *
+  * <Input>
+  *    surface    :: handle to target surface
+  *    event_mask :: the event mask (mode)
+  *
+  * <Output>
+  *    event  :: the returned event
+  *
+  * <Note>
+  *    XXX : For now, only keypresses are supported.
+  *
+  **********************************************************************/
+  
+  extern
+  int   grListenSurface( grSurface*  surface,
+                         int         event_mask,
+                         grEvent    *event )
+  {
+    return surface->listen_event( surface, event_mask, event );
+  }
+
+
+#if 0
+  static
+  void  gr_done_surface( grSurface*  surface )
+  {
+    if (surface)
+    {
+      /* first of all, call the device-specific destructor */
+      surface->done(surface);
+      
+      /* then remove the bitmap if we're owner */
+      if (surface->owner)
+        grFree( surface->bitmap.buffer );
+        
+      surface->owner         = 0;  
+      surface->bitmap.buffer = 0;
+      grFree( surface );
+    }
+  }
+#endif
+
diff --git a/demos/graph/grdevice.h b/demos/graph/grdevice.h
new file mode 100644
index 0000000..a434609
--- /dev/null
+++ b/demos/graph/grdevice.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ *
+ *  grdevice.h
+ *
+ *    Graphics device interface
+ *
+ *  Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GRDEVICE_H
+#define GRDEVICE_H
+
+#include "graph.h"
+
+
+ /********************************************************************
+  *
+  * <FuncType>
+  *   grDeviceInitFunc
+  *
+  * <Description>
+  *   Simple device initialiser function
+  *
+  * <Return>
+  *   error code. 0 means success
+  *
+  ********************************************************************/
+
+  typedef int  (*grDeviceInitFunc)( void );
+
+
+ /********************************************************************
+  *
+  * <FuncType>
+  *   grDeviceDoneFunc
+  *
+  * <Description>
+  *   Simple device finaliser function
+  *
+  * <Return>
+  *   error code. 0 means success
+  *
+  ********************************************************************/
+
+  typedef void (*grDeviceDoneFunc)( void );
+
+
+ /********************************************************************
+  *
+  * <FuncType>
+  *   grDeviceInitSurfaceFunc
+  *
+  * <Description>
+  *   initializes a new surface for the device. This may be a window
+  *   or a video screen, depending on the device.
+  *
+  * <Input>
+  *   surface  :: handle to target surface
+  *
+  * <InOut>
+  *   bitmap   :: handle to bitmap descriptor
+  *
+  ********************************************************************/
+
+  typedef int  (*grDeviceInitSurfaceFunc)( grSurface*   surface,
+                                           grBitmap*    bitmap );
+
+
+ /********************************************************************
+  *
+  * <Struct>
+  *   grDevice
+  *
+  * <Description>
+  *   Simple device interface structure
+  *
+  * <Fields>
+  *   surface_objsize :: size in bytes of a single surface object for
+  *                      this device.
+  *
+  *   device_name :: name of device, e.g. "x11", "os2pm", "directx" etc..
+  *   init        :: device initialisation routine
+  *   done        :: device finalisation
+  *   new_surface :: function used to create a new surface (screen or
+  *                  window) from the device
+  *
+  *   num_pixel_modes :: the number of pixel modes supported by this
+  *                      device. This value _must_ be set to -1
+  *                      default, unless the device provides a
+  *                      static set of pixel modes (fullscreen).
+  *
+  *   pixel_modes     :: an array of pixel modes supported by this
+  *                      device
+  *
+  * <Note>
+  *   the fields "num_pixel_modes" and "pixel_modes" must be
+  *   set by the "init" function.
+  *
+  *   This allows windowed devices to "discover" at run-time the
+  *   available pixel modes they can provide depending on the
+  *   current screen depth.
+  *
+  ********************************************************************/
+
+  struct grDevice_
+  {
+    int          surface_objsize;
+    const char*  device_name;  /* name of device                 */
+  
+    grDeviceInitFunc        init;
+    grDeviceDoneFunc        done;
+
+    grDeviceInitSurfaceFunc init_surface;
+
+    int                     num_pixel_modes;
+    grPixelMode*            pixel_modes; 
+  };
+
+
+  extern grDeviceChain   gr_device_chain[];
+  extern int             gr_num_devices;
+
+
+#endif /* GRDEVICE_H */
diff --git a/demos/graph/grevents.h b/demos/graph/grevents.h
new file mode 100644
index 0000000..c32f75b
--- /dev/null
+++ b/demos/graph/grevents.h
@@ -0,0 +1,117 @@
+#ifndef GREVENTS_H
+#define GREVENTS_H
+
+
+#define gr_event_none  0
+#define gr_event_wait  1
+#define gr_event_poll  2
+#define gr_event_flush 3
+
+#define gr_mouse_down  0x04
+#define gr_mouse_move  0x08
+#define gr_mouse_up    0x10
+#define gr_mouse_drag  0x20
+
+#define gr_key_down 0x40
+#define gr_key_up   0x80
+
+
+#define gr_event_mouse 0x3C
+#define gr_event_key   0xC0
+
+#define gr_event_type  (gr_event_mouse | gr_event_key)  
+
+
+  typedef enum grKey_
+  {
+    grKeyNone = 0,
+    
+    grKeyF1,
+    grKeyF2,
+    grKeyF3,
+    grKeyF4,
+    grKeyF5,
+    grKeyF6,
+    grKeyF7,
+    grKeyF8,
+    grKeyF9,
+    grKeyF10,
+    grKeyF11,
+    grKeyF12,
+    
+    grKeyLeft,
+    grKeyRight,
+    grKeyUp,
+    grKeyDown,
+    
+    grKeyIns,
+    grKeyDel,
+    grKeyHome,
+    grKeyEnd,
+    grKeyPageUp,
+    grKeyPageDown,
+
+    grKeyEsc,    
+    grKeyTab,
+    grKeyBackSpace,
+    grKeyReturn,
+
+    grKeyMax,
+    grKeyForceShort = 0x7FFF  /* this forces the grKey to be stored */
+                              /* on at least one short !            */
+    
+  } grKey;
+
+#define  grKEY(c)    ((grKey)(c))
+
+#define  grKeyAlt    ((grKey)0x8000)
+#define  grKeyCtrl   ((grKey)0x4000)
+#define  grKeyShift  ((grKey)0x2000)
+
+#define  grKeyModifiers ((grKey)0xE000)
+
+#define  grKey0       grKEY('0')
+#define  grKey1       grKEY('1')
+#define  grKey2       grKEY('2')
+#define  grKey3       grKEY('3')
+#define  grKey4       grKEY('4')
+#define  grKey5       grKEY('5')
+#define  grKey6       grKEY('6')
+#define  grKey7       grKEY('7')
+#define  grKey8       grKEY('8')
+#define  grKey9       grKEY('9')
+
+
+#define  grKeyPlus        grKEY('+')
+#define  grKeyLess        grKEY('-')
+#define  grKeyEqual       grKEY('=')
+#define  grKeyMult        grKEY('*')
+#define  grKeyDollar      grKEY('$')
+#define  grKeySmaller     grKEY('<')
+#define  grKeyGreater     grKEY('>')
+#define  grKeyQuestion    grKEY('?')
+#define  grKeyComma       grKEY(',')
+#define  grKeyDot         grKEY('.')
+#define  grKeySemiColumn  grKEY(';')
+#define  grKeyColumn      grKEY(':')
+#define  grKeyDiv         grKEY('/')
+#define  grKeyExclam      grKEY('!')
+#define  grKeyPercent     grKEY('%')
+#define  grKeyLeftParen   grKEY('(')
+#define  grKeyRightParen  grKEY('(')
+#define  grKeyAt          grKEY('@')
+#define  grKeyUnder       grKEY('_')
+
+  
+  typedef struct grEvent_
+  {
+    int    type;
+    grKey  key;
+    int    x, y;
+
+  } grEvent;
+
+
+
+#endif /* GREVENTS_H */
+
diff --git a/demos/graph/grfont.c b/demos/graph/grfont.c
new file mode 100644
index 0000000..8b9df37
--- /dev/null
+++ b/demos/graph/grfont.c
@@ -0,0 +1,354 @@
+#include "grfont.h"
+
+  /* font characters */
+
+  const unsigned char  font_8x8[2048] =
+  {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
+    0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
+    0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
+    0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
+    0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C,
+    0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C,
+    0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
+    0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
+    0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
+    0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF,
+    0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
+    0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
+    0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0,
+    0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0,
+    0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99,
+    0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
+    0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
+    0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18,
+    0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
+    0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00,
+    0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC,
+    0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
+    0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF,
+    0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
+    0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00,
+    0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
+    0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
+    0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
+    0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00,
+    0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00,
+    0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,
+    0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
+    0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00,
+    0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
+    0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
+    0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
+    0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
+    0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
+    0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
+    0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
+    0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
+    0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00,
+    0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00,
+    0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00,
+    0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00,
+    0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
+    0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
+    0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00,
+    0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
+    0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+    0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00,
+    0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
+    0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
+    0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00,
+    0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00,
+    0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
+    0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00,
+    0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00,
+    0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00,
+    0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
+    0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
+    0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
+    0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
+    0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
+    0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00,
+    0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00,
+    0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
+    0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
+    0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
+    0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
+    0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
+    0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
+    0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
+    0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00,
+    0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
+    0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00,
+    0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00,
+    0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
+    0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
+    0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00,
+    0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
+    0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
+    0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
+    0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
+    0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
+    0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+    0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+    0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00,
+    0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
+    0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00,
+    0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+    0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00,
+    0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+    0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
+    0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78,
+    0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
+    0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00,
+    0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
+    0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
+    0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0,
+    0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
+    0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00,
+    0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00,
+    0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00,
+    0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+    0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
+    0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
+    0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
+    0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+    0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00,
+    0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00,
+    0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
+    0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00,
+    0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
+    0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C,
+    0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+    0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+    0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00,
+    0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+    0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+    0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+    0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38,
+    0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
+    0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+    0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
+    0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00,
+    0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
+    0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00,
+    0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00,
+    0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00,
+    0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00,
+    0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+    0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+    0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+    0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+    0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+    0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
+    0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00,
+    0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
+    0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18,
+    0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00,
+    0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30,
+    0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3,
+    0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70,
+    0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
+    0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+    0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
+    0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
+    0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00,
+    0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00,
+    0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00,
+    0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00,
+    0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00,
+    0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00,
+    0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F,
+    0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03,
+    0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00,
+    0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00,
+    0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00,
+    0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
+    0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
+    0xDB, 0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED,
+    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
+    0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36,
+    0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36,
+    0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
+    0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00,
+    0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00,
+    0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00,
+    0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18,
+    0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
+    0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
+    0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
+    0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
+    0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36,
+    0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
+    0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18,
+    0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00,
+    0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
+    0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36,
+    0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+    0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00,
+    0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0,
+    0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
+    0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00,
+    0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00,
+    0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00,
+    0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0,
+    0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00,
+    0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC,
+    0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00,
+    0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00,
+    0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00,
+    0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00,
+    0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0,
+    0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00,
+    0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
+    0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00,
+    0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00,
+    0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00,
+    0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00,
+    0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18,
+    0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70,
+    0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00,
+    0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00,
+    0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
+    0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C,
+    0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00,
+    0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+  };
+
+
+  static
+  grBitmap  gr_charcell =
+  {
+    8,                    /* rows  */
+    8,                    /* width */
+    gr_pixel_mode_mono,   /* mode  */
+    1,                    /* pitch */
+    0,                    /* grays */
+    0                     /* buffer */
+  };
+
+  void  grWriteCellChar( grBitmap*  target,
+                         int        x,
+                         int        y,
+                         int        charcode,
+                         grColor    color )
+  {
+    if (charcode < 0 || charcode > 255)
+      return;
+      
+    gr_charcell.buffer = (char*)font_8x8 + 8*charcode;
+    grBlitGlyphToBitmap( target, &gr_charcell, x, y, color );
+  }
+  
+  
+  void  grWriteCellString( grBitmap*   target,
+                           int         x,
+                           int         y,
+                           const char* string,
+                           grColor     color )
+  {
+    while (*string)
+    {
+      gr_charcell.buffer = (char*)font_8x8 + 8*(int)(unsigned char)*string++;
+      grBlitGlyphToBitmap( target, &gr_charcell, x, y, color );
+      x += 8;
+    }
+  }
+  
+  static int        gr_cursor_x     = 0;
+  static int        gr_cursor_y     = 0;
+  static grBitmap*  gr_text_bitmap  = 0;
+  static int        gr_margin_right = 0;
+  static int        gr_margin_top   = 0;
+
+  extern void grGotobitmap( grBitmap*  bitmap )
+  {
+    gr_text_bitmap = bitmap;
+  }
+  
+  extern void grSetMargin( int right, int top )
+  {
+    gr_margin_top   = top << 3;
+    gr_margin_right = right << 3;
+  }
+ 
+  extern void grGotoxy ( int x, int y )
+  {
+    gr_cursor_x = x;
+    gr_cursor_y = y;
+  }
+ 
+  extern void grWrite  ( const char*  string )
+  {
+    if (string)
+    {
+      grWriteCellString( gr_text_bitmap,
+                         gr_margin_right + (gr_cursor_x << 3),
+                         gr_margin_top   + (gr_cursor_y << 3),
+                         string,
+                         (grColor)127L );
+ 
+      gr_cursor_x += strlen(string);
+    }
+  }
+  
+  extern void grLn()
+  {
+    gr_cursor_y ++;
+    gr_cursor_x = 0;
+  }
+
+  extern void grWriteln( const char* string )
+  {
+    grWrite( string );
+    grLn();
+  }
+
+  
diff --git a/demos/graph/grfont.h b/demos/graph/grfont.h
new file mode 100644
index 0000000..1456af2
--- /dev/null
+++ b/demos/graph/grfont.h
@@ -0,0 +1,16 @@
+#ifndef GRFONT_H
+#define GRFONT_H
+
+#include "graph.h"
+
+  extern const unsigned char  font_8x8[];
+
+  extern void grGotobitmap( grBitmap*  bitmap );
+  extern void grSetMargin( int right, int top );
+  extern void grGotoxy ( int x, int y );
+
+  extern void grWrite  ( const char*  string );
+  extern void grWriteln( const char* string );
+  extern void grLn(); 
+
+#endif /* GRFONT_H */
diff --git a/demos/graph/grinit.c b/demos/graph/grinit.c
new file mode 100644
index 0000000..2237106
--- /dev/null
+++ b/demos/graph/grinit.c
@@ -0,0 +1,78 @@
+#include "grobjs.h"
+#include "grdevice.h"
+#include <stdio.h>
+
+#define GR_INIT_DEVICE_CHAIN   ((grDeviceChain*)0)
+#define GR_INIT_BUILD
+
+#ifdef DEVICE_X11
+#include "grx11.h"
+#endif
+
+#ifdef DEVICE_OS2_PM
+#include "gros2pm.h"
+#endif
+
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grInitDevices
+  *
+  * <Description>
+  *    This function is in charge of initialising all system-specific
+  *    devices. A device is responsible for creating and managing one
+  *    or more "surfaces". A surface is either a window or a screen,
+  *    depending on the system.
+  *
+  * <Return>
+  *    a pointer to the first element of a device chain. The chain can
+  *    be parsed to find the available devices on the current system
+  *
+  * <Note>
+  *    If a device cannot be initialised correctly, it is not part of
+  *    the device chain returned by this function. For example, if an
+  *    X11 device was compiled in the library, it will be part of
+  *    the returned device chain only if a connection to the display
+  *    could be establisged
+  *
+  *    If no driver could be initialised, this function returns NULL.
+  *
+  **********************************************************************/
+
+  extern
+  grDeviceChain*  grInitDevices( void )
+  {
+    grDeviceChain*  chain = GR_INIT_DEVICE_CHAIN;
+    grDeviceChain*  cur   = gr_device_chain;
+
+    while (chain)
+    {
+      /* initialie the device */
+      grDevice*  device;
+
+      device = chain->device;
+      if ( device->init() == 0             &&
+           gr_num_devices < GR_MAX_DEVICES )
+          
+      {
+        /* successful device initialisation - add it to our chain */
+        cur->next   = 0;
+        cur->device = device;
+        cur->name   = device->device_name;
+
+        if (cur > gr_device_chain)
+          cur[-1].next = cur;
+
+        cur++;
+        gr_num_devices++;
+      }
+      chain = chain->next;
+    }
+
+    return (gr_num_devices > 0 ? gr_device_chain : 0 );
+  }
+
+
+
diff --git a/demos/graph/grobjs.c b/demos/graph/grobjs.c
new file mode 100644
index 0000000..7ebdb27
--- /dev/null
+++ b/demos/graph/grobjs.c
@@ -0,0 +1,213 @@
+#include "grobjs.h"
+#include <stdlib.h>
+
+
+  int  grError = 0;
+
+
+ /********************************************************************
+  *
+  * <Function>
+  *   grRealloc
+  *
+  * <Description>
+  *   Simple memory re-allocation.
+  *
+  * <Input>
+  *   block :: original memory block address
+  *   size  :: new requested block size in bytes
+  *
+  * <Return>
+  *   the memory block address. 0 in case of error
+  *
+  ********************************************************************/
+
+  char*  grAlloc( long size )
+  {
+    char*  p;
+     
+    p = (char*)malloc(size);
+    if (!p && size > 0)
+    {
+      grError = gr_err_memory; 
+    }
+    
+    if (p)
+      memset( p, 0, size );
+    
+    return p;
+  }
+
+
+ /********************************************************************
+  *
+  * <Function>
+  *   grRealloc
+  *
+  * <Description>
+  *   Simple memory re-allocation.
+  *
+  * <Input>
+  *   block :: original memory block address
+  *   size  :: new requested block size in bytes
+  *
+  * <Return>
+  *   the memory block address. 0 in case of error
+  *
+  ********************************************************************/
+
+  char*  grRealloc( const char*  block, long size )
+  {
+    char*  p;
+    
+    p = realloc( (char*)block, size );
+    if (!p && size > 0)
+    {
+      grError = gr_err_memory;
+    }
+    return p;
+  }
+
+
+ /********************************************************************
+  *
+  * <Function>
+  *   grFree
+  *
+  * <Description>
+  *   Simple memory release
+  *
+  * <Input>
+  *   block :: target block
+  *
+  ********************************************************************/
+
+  void  grFree( const void*  block )
+  {
+    if (block)
+      free( (char*)block );
+  }
+
+
+
+  static
+  int  check_mode( grPixelMode  pixel_mode,
+                   int          num_grays )
+  {
+    if ( pixel_mode <= gr_pixel_mode_none ||
+         pixel_mode >= gr_pixel_mode_max  )
+      goto Fail;
+   
+    if ( pixel_mode != gr_pixel_mode_gray      ||
+         ( num_grays >= 2 && num_grays < 256 ) )
+      return 0;
+
+  Fail:
+    grError = gr_err_bad_argument;
+    return grError;
+  }
+
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grNewBitmap
+  *
+  * <Description>
+  *    creates a new bitmap    
+  *
+  * <Input>
+  *    pixel_mode   :: the target surface's pixel_mode
+  *    num_grays    :: number of grays levels for PAL8 pixel mode
+  *    width        :: width in pixels
+  *    height       :: height in pixels
+  *
+  * <Output>
+  *    bit  :: descriptor of the new bitmap
+  *
+  * <Return>
+  *    Error code. 0 means success.
+  *
+  **********************************************************************/
+
+  extern  int  grNewBitmap( grPixelMode  pixel_mode,
+                            int          num_grays,
+                            int          width,
+                            int          height,
+                            grBitmap    *bit )
+  {
+    int  pitch;
+
+    /* check mode */
+    if (check_mode(pixel_mode,num_grays))
+      goto Fail;
+
+    /* check dimensions */
+    if (width < 0 || height < 0)
+    {
+      grError = gr_err_bad_argument;
+      goto Fail;
+    }
+
+    bit->width = width;
+    bit->rows  = height;
+    bit->mode  = pixel_mode;
+    bit->grays = num_grays;
+
+    pitch = width;
+
+    switch (pixel_mode)
+    {
+      case gr_pixel_mode_mono  : pitch = (width+7) >> 3; break;
+      case gr_pixel_mode_pal4  : pitch = (width+3) >> 2; break;
+      
+      case gr_pixel_mode_pal8  :
+      case gr_pixel_mode_gray  : pitch = width; break;
+      
+      case gr_pixel_mode_rgb555:
+      case gr_pixel_mode_rgb565: pitch = width*2; break;
+      
+      case gr_pixel_mode_rgb24 : pitch = width*3; break;
+      
+      case gr_pixel_mode_rgb32 : pitch = width*4; break;
+      
+      default:
+        grError = gr_err_bad_target_depth;
+        return 0;
+    }
+    
+    bit->pitch  = pitch;
+    bit->buffer = grAlloc( (long)bit->pitch * bit->rows );
+    if (!bit->buffer) goto Fail;
+    
+    return 0;
+    
+  Fail:
+    return grError;
+  }
+
+ /**********************************************************************
+  *
+  * <Function>
+  *    grDoneBitmap
+  *
+  * <Description>
+  *    destroys a bitmap    
+  *
+  * <Input>
+  *    bitmap :: handle to bitmap descriptor
+  *
+  * <Note>
+  *    This function does NOT release the bitmap descriptor, only
+  *    the pixel buffer.
+  *
+  **********************************************************************/
+
+  extern  void  grDoneBitmap( grBitmap*  bit )
+  {
+    grFree( bit->buffer );
+    bit->buffer = 0;
+  }
+
+
+
diff --git a/demos/graph/grobjs.h b/demos/graph/grobjs.h
new file mode 100644
index 0000000..79eb31d
--- /dev/null
+++ b/demos/graph/grobjs.h
@@ -0,0 +1,186 @@
+/***************************************************************************
+ *
+ *  grobjs.h
+ *
+ *    basic object classes defintions
+ *
+ *  Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GROBJS_H
+#define GROBJS_H
+
+#include "graph.h"
+#include "grconfig.h"
+#include "grtypes.h"
+
+
+  typedef struct grBiColor_
+  {
+    grColor   foreground;
+    grColor   background;
+    
+    int       num_levels;
+    int       max_levels;
+    grColor*  levels;
+
+  } grBiColor;
+
+
+
+ /**********************************************************************
+  *
+  * Technical note : explaining how the blitter works.
+  *
+  *   The blitter is used to "draw" a given source bitmap into
+  *   a given target bitmap.
+  *
+  *   The function called 'compute_clips' is used to compute clipping
+  *   constraints. These lead us to compute two areas :
+  *
+  *   - the read area : is the rectangle, within the source bitmap,
+  *                     which will be effectively "drawn" in the
+  *                     target bitmap.
+  *
+  *   - the write area : is the rectangle, within the target bitmap,
+  *                      which will effectively "receive" the pixels
+  *                      from the read area
+  *
+  *   Note that both areas have the same dimensions, but are
+  *   located in distinct surfaces.
+  *
+  *   These areas are computed by 'compute_clips' which is called
+  *   by each blitting function.
+  *
+  *   Note that we use the Y-downwards convention within the blitter
+  *
+  **********************************************************************/
+
+  typedef struct grBlitter_
+  {
+    int  width;   /* width in pixels of the areas  */
+    int  height;  /* height in pixels of the areas */
+
+    int  xread;   /* x position of start point in read area */
+    int  yread;   /* y position of start point in read area */
+
+    int  xwrite;  /* x position of start point in write area */
+    int  ywrite;  /* y position of start point in write area */
+
+    int  right_clip;   /* amount of right clip               */
+
+    unsigned char*  read;   /* top left corner of read area in source map  */
+    unsigned char*  write;  /* top left corner of write area in target map */
+
+    int    read_line;  /* byte increment to go down one row in read area  */
+    int    write_line; /* byte increment to go down one row in write area */
+
+    grBitmap  source;  /* source bitmap descriptor */
+    grBitmap  target;  /* target bitmap descriptor */
+
+  } grBlitter;
+
+
+
+  typedef void (*grBlitterFunc)( grBlitter*  blitter,
+                                 grColor     color );
+
+  typedef void (*grSetTitleFunc)( grSurface*   surface,
+                                  const char*  title_string );
+
+  typedef void (*grRefreshRectFunc)( grSurface*  surface,
+                                     int         x,
+                                     int         y,
+                                     int         width,
+                                     int         height );
+                                    
+  typedef void (*grDoneSurfaceFunc)( grSurface*  surface );
+
+  typedef int  (*grListenEventFunc)( grSurface* surface,
+                                     int        event_mode,
+                                     grEvent   *event );
+ 
+
+
+  struct grSurface_
+  {
+    grDevice*          device;
+    grBitmap           bitmap;
+    grBool             refresh;
+    grBool             owner;
+     
+    const byte*        saturation;  /* used for gray surfaces only   */
+    grBlitterFunc      blit_mono;   /* 0 by default, set by grBlit.. */
+
+    grRefreshRectFunc  refresh_rect;
+    grSetTitleFunc     set_title;
+    grListenEventFunc  listen_event;
+    grDoneSurfaceFunc  done;
+  };
+
+
+
+ /********************************************************************
+  *
+  * <Function>
+  *   grAlloc
+  *
+  * <Description>
+  *   Simple memory allocation. The returned block is always zero-ed
+  *
+  * <Input>
+  *   size  :: size in bytes of the requested block
+  *
+  * <Return>
+  *   the memory block address. 0 in case of error
+  *
+  ********************************************************************/
+
+  extern  char*  grAlloc( long size );
+  
+
+ /********************************************************************
+  *
+  * <Function>
+  *   grRealloc
+  *
+  * <Description>
+  *   Simple memory re-allocation.
+  *
+  * <Input>
+  *   block :: original memory block address
+  *   size  :: new requested block size in bytes
+  *
+  * <Return>
+  *   the memory block address. 0 in case of error
+  *
+  ********************************************************************/
+
+  extern  char*  grRealloc( const char*  block, long size );
+
+
+ /********************************************************************
+  *
+  * <Function>
+  *   grFree
+  *
+  * <Description>
+  *   Simple memory release
+  *
+  * <Input>
+  *   block :: target block
+  *
+  ********************************************************************/
+
+  extern  void   grFree( const void*  block );
+
+
+  extern grDevice*  gr_devices[];
+  extern int        gr_num_devices;
+  extern int        gr_max_devices;
+
+#endif /* GROBJS_H */
diff --git a/demos/graph/gros2pm.c b/demos/graph/gros2pm.c
new file mode 100644
index 0000000..e7a63ce
--- /dev/null
+++ b/demos/graph/gros2pm.c
@@ -0,0 +1,895 @@
+#include "gros2pm.h"
+
+
+#define INCL_DOS
+#define INCL_WIN
+#define INCL_GPI
+#define INCL_SUB
+
+#include <os2.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+  static void Panic( const char* message )
+  {
+    fprintf( stderr, "%s", message );
+    exit(1);
+  }
+
+  typedef struct Translator
+  {
+    ULONG   os2key;
+    grKey   grkey;
+    
+  } Translator;
+  
+
+  static
+  Translator  key_translators[] =
+  {
+    { VK_BACKSPACE, grKeyBackSpace },
+    { VK_TAB,       grKeyTab       },
+    { VK_ENTER,     grKeyReturn    },
+    { VK_ESC,       grKeyEsc       },
+    { VK_HOME,      grKeyHome      },
+    { VK_LEFT,      grKeyLeft      },
+    { VK_UP,        grKeyUp        },
+    { VK_RIGHT,     grKeyRight     },
+    { VK_DOWN,      grKeyDown      },
+    { VK_PAGEUP,    grKeyPageUp    },
+    { VK_PAGEDOWN,  grKeyPageDown  },
+    { VK_END,       grKeyEnd       },
+    { VK_F1,        grKeyF1        },
+    { VK_F2,        grKeyF2        },
+    { VK_F3,        grKeyF3        },
+    { VK_F4,        grKeyF4        },
+    { VK_F5,        grKeyF5        },
+    { VK_F6,        grKeyF6        },
+    { VK_F7,        grKeyF7        },
+    { VK_F8,        grKeyF8        },
+    { VK_F9,        grKeyF9        },
+    { VK_F10,       grKeyF10       },
+    { VK_F11,       grKeyF11       },
+    { VK_F12,       grKeyF12       }
+  };
+
+
+#define MAX_PIXEL_MODES  32
+
+  static int           num_pixel_modes = 0;
+  static grPixelMode   pixel_modes[ MAX_PIXEL_MODES ];  
+  static int           pixel_depth[ MAX_PIXEL_MODES ];
+
+  static  HAB   gr_anchor;   /* device anchor block */
+
+  typedef POINTL  PMBlitPoints[4];
+
+
+  typedef struct grPMSurface_
+  {
+    grSurface  root;
+    grBitmap   image;
+
+    HAB        anchor;         /* handle to anchor block for surface's window */
+    HWND       frame_window;   /* handle to window's frame                    */
+    HWND       client_window;  /* handle to window's client                   */
+    HWND       title_window;   /* handle to window's title bar                */
+
+    HPS        image_ps;       /* memory presentation space used to hold */
+                               /* the surface's content under PM         */
+    HDC        image_dc;       /* memory device context for the image    */
+
+    HEV        event_lock;     /* semaphore used in listen_surface   */
+    HMTX       image_lock;     /* a mutex used to synchronise access */
+                               /* to the memory presentation space   */
+                               /* used to hold the surface           */
+
+    TID        message_thread; /* thread used to process this surface's */
+                               /* messages..                            */
+
+    PBITMAPINFO2 bitmap_header;/* os/2 bitmap descriptor                   */
+    HBITMAP      os2_bitmap;   /* Handle to OS/2 bitmap contained in image */
+    BOOL         ready;        /* ??? */
+
+    long         shades[256];  /* indices of gray levels in pixel_mode_gray */
+
+    POINTL       surface_blit[4];  /* surface blitting table   */
+    POINTL       magnify_blit[4];  /* magnifier blitting table */
+    int          magnification;    /* level of magnification   */
+    POINTL       magnify_center;
+    SIZEL        magnify_size;
+
+    grEvent      event;
+
+    PMBlitPoints blit_points;
+
+  } grPMSurface;
+
+
+
+  static
+  void  enable_os2_iostreams( void )
+  {
+    PTIB  thread_block;
+    PPIB  process_block;
+
+    /* XXX : This is a very nasty hack, it fools OS/2 and let the program */
+    /*       call PM functions, even though stdin/stdout/stderr are still */
+    /*       directed to the standard i/o streams..                       */
+    /*       The program must be compiled with WINDOWCOMPAT               */
+    /*                                                                    */
+    /*   Credits go to Michal for finding this !!                         */
+    /*                                                                    */
+    DosGetInfoBlocks( &thread_block, &process_block );
+    process_block->pib_ultype = 3;
+  }
+
+
+
+  static
+  int  init_device( void )
+  {
+    enable_os2_iostreams();
+
+    /* create an anchor block. This will allow this thread (i.e. the */
+    /* main one) to call Gpi functions..                             */
+    gr_anchor = WinInitialize(0);
+    if (!gr_anchor)
+    {
+      /* could not initialise Presentation Manager */
+      return -1;
+    }
+
+    return 0;
+  }
+
+
+
+  static
+  void  done_device( void )
+  {
+    /* Indicates that we do not use the Presentation Manager, this */
+    /* will also release all associated resources..                */
+    WinTerminate( gr_anchor );
+  }
+
+
+
+  /* close a given window */
+  static
+  void  done_surface( grPMSurface*  surface )
+  {
+    if ( surface->frame_window )
+      WinDestroyWindow( surface->frame_window );
+
+    WinReleasePS( surface->image_ps );
+
+    grDoneBitmap( &surface->image );
+    grDoneBitmap( &surface->root.bitmap );
+  }
+
+
+
+
+
+  static
+  void add_pixel_mode( grPixelMode  pixel_mode,
+                       int          depth )
+  {
+    if ( num_pixel_modes >= MAX_PIXEL_MODES )
+      Panic( "X11.Too many pixel modes\n" );
+      
+    pixel_modes[ num_pixel_modes ] = pixel_mode;
+    pixel_depth[ num_pixel_modes ] = depth;
+    
+    num_pixel_modes++;
+  }
+
+
+#define LOCK(x)    DosRequestMutexSem( x, SEM_INDEFINITE_WAIT );
+#define UNLOCK(x)  DosReleaseMutexSem( x )
+
+
+  static
+  const int  pixel_mode_bit_count[] =
+  {
+    0,
+    1,
+    4,
+    8,   /* pal8 */
+    8,   /* gray */
+    15,
+    16,
+    24,
+    32
+  };
+
+
+ /************************************************************************
+  *
+  * Technical note : how the OS/2 Presntation Manager driver works
+  *
+  * PM is, in my opinion, a bloated and over-engineered graphics
+  * sub-system, even though it has lots of nice features. Here are
+  * a few tidbits about it :
+  *
+  *
+  * - under PM, a "bitmap" is a device-specific object whose bits are
+  *   not directly accessible to the client application. This means
+  *   that we must use a scheme like the following to display our
+  *   surfaces :
+  *
+  *     - hold, for each surface, its own bitmap buffer where the
+  *       rest of MiGS writes directly.
+  *
+  *     - create a PM bitmap object with the same dimensions (and
+  *       possibly format).
+  *
+  *     - copy the content of each updated rectangle into the
+  *       PM bitmap with the function 'GpiSetBitmapBits'.
+  *
+  *     - finally, "blit" the PM bitmap to the screen calling
+  *       'GpiBlitBlt'
+  *
+  * - but there is more : you cannot directly blit a PM bitmap to the
+  *   screen with PM. The 'GpiBlitBlt' only works with presentation
+  *   spaces. This means that we also need to create, for each surface :
+  *
+  *     - a memory presentation space, used to hold the PM bitmap
+  *     - a "memory device context" for the presentation space
+  *
+  *   The blit is then performed from the memory presentation space
+  *   to the screen's presentation space..
+  *
+  *
+  * - because each surface creates its own event-handling thread,
+  *   we must protect the surface's presentation space from concurrent
+  *   accesses (i.e. calls to 'GpiSetBitmapBits' when drawing to the
+  *   surface, and calls to 'GpiBlitBlt' when drawing it on the screen
+  *   are performed in two different threads).
+  *
+  *   we use a simple mutex to do this.
+  *
+  *
+  * - we also use a semaphore to perform a rendez-vous between the
+  *   main and event-handling threads (needed in "listen_event").
+  *
+  ************************************************************************/
+
+  static
+  void  RunPMWindow( grPMSurface*  surface );
+
+
+
+
+
+
+
+
+
+
+
+
+  static
+  void  convert_gray_to_pal8( grPMSurface* surface,
+                              int          x,
+                              int          y,
+                              int          w,
+                              int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    long*      palette = surface->shades;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + w;
+      
+      for ( ; _write < limit; _write++, _read++ )
+        *_write = (byte) palette[ *_read ];
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_16( grPMSurface* surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 2*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    long*           palette = surface->shades;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 2*w;
+      
+      for ( ; _write < limit; _write += 2, _read++ )
+        *(short*)_write = (short)palette[ *_read ];
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_24( grPMSurface* surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 3*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 3*w;
+      
+      for ( ; _write < limit; _write += 3, _read++ )
+      {
+        byte  color = *_read;
+        
+        _write[0] =
+        _write[1] =
+        _write[2] = color;
+      }
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_32( grPMSurface* surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 4*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 4*w;
+      
+      for ( ; _write < limit; _write += 4, _read++ )
+      {
+        byte  color = *_read;
+        
+        _write[0] =
+        _write[1] =
+        _write[2] =
+        _write[3] = color;
+      }
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_rectangle( grPMSurface* surface,
+                           int          x,
+                           int          y,
+                           int          w,
+                           int          h )
+  {
+    int  z;
+    
+    /* first of all, clip to the surface's area */
+    if ( x   >= surface->image.width ||
+         x+w <= 0                    ||
+         y   >= surface->image.rows  ||
+         y+h <= 0 )
+      return;
+ 
+    if ( x < 0 )
+    {
+      w += x;
+      x  = 0;
+    }
+ 
+    z = (x + w) - surface->image.width;
+    if (z > 0)
+      w -= z;
+      
+    z = (y + h) - surface->image.rows;
+    if (z > 0)
+      h -= z;
+      
+    /* convert the rectangle to the target depth for gray surfaces */
+    if (surface->root.bitmap.mode == gr_pixel_mode_gray)
+    {
+      switch (surface->image.mode)
+      {
+        case gr_pixel_mode_pal8  :
+          convert_gray_to_pal8( surface, x, y, w, h );
+          break;
+
+        case gr_pixel_mode_rgb555:
+        case gr_pixel_mode_rgb565:
+          convert_gray_to_16  ( surface, x, y, w, h );
+          break;
+
+        case gr_pixel_mode_rgb24:
+          convert_gray_to_24  ( surface, x, y, w, h );
+          break;
+
+        case gr_pixel_mode_rgb32:
+          convert_gray_to_32  ( surface, x, y, w, h );
+          break;
+
+        default:
+          ;
+      }
+    }
+  } 
+
+
+  static
+  void  refresh_rectangle( grPMSurface* surface,
+                           int          x,
+                           int          y,
+                           int          w,
+                           int          h )
+  {
+    convert_rectangle( surface, x, y, w, h );
+
+    WinInvalidateRect( surface->client_window, NULL, FALSE );
+    WinUpdateWindow( surface->frame_window );
+  }
+
+  
+  static
+  void  set_title( grPMSurface* surface,
+                   const char*  title )
+  {
+    WinSetWindowText( surface->title_window, (PSZ)title );
+  }
+
+
+
+  static  
+  void  listen_event( grPMSurface* surface,
+                      int          event_mask,
+                      grEvent*     grevent )
+  {
+    ULONG  ulRequestCount;
+
+    (void) event_mask;   /* ignored for now */
+
+    /* the listen_event function blocks until there is an event to process */
+    DosWaitEventSem( surface->event_lock, SEM_INDEFINITE_WAIT );
+    DosQueryEventSem( surface->event_lock, &ulRequestCount );
+    *grevent = surface->event;
+    DosResetEventSem( surface->event_lock, &ulRequestCount );
+
+    return;
+  }
+
+
+  static
+  int  init_surface( grPMSurface*  surface,
+                     grBitmap*     bitmap )
+  {
+    PBITMAPINFO2  bit;
+    SIZEL         sizl = { 0, 0 };
+    LONG          palette[256];
+
+    /* create the bitmap - under OS/2, we support all modes as PM */
+    /* handles all conversions automatically..                    */
+    if ( grNewBitmap( surface->root.bitmap.mode,
+                      surface->root.bitmap.grays,
+                      surface->root.bitmap.width,
+                      surface->root.bitmap.rows,
+                      bitmap ) )
+      return grError;
+
+    surface->root.bitmap = *bitmap;
+
+    /* create the image and event lock */
+    DosCreateEventSem( NULL, &surface->event_lock, 0, TRUE  );
+    DosCreateMutexSem( NULL, &surface->image_lock, 0, FALSE );
+
+    /* create the image's presentation space */
+    surface->image_dc = DevOpenDC( gr_anchor,
+                                   OD_MEMORY, (PSZ)"*", 0L, 0L, 0L );
+
+    surface->image_ps = GpiCreatePS( gr_anchor,
+                                     surface->image_dc,
+                                     &sizl,
+                                     PU_PELS    | GPIT_MICRO |
+                                     GPIA_ASSOC | GPIF_DEFAULT );
+
+    GpiSetBackMix( surface->image_ps, BM_OVERPAINT );
+
+    /* create the image's PM bitmap */
+    bit = (PBITMAPINFO2)grAlloc( sizeof(BITMAPINFO2) + 256*sizeof(RGB2) );
+    surface->bitmap_header = bit;
+
+    bit->cbFix   = sizeof( BITMAPINFOHEADER2 );
+    bit->cx      = surface->root.bitmap.width;
+    bit->cy      = surface->root.bitmap.rows;
+    bit->cPlanes = 1;
+
+    bit->argbColor[0].bBlue  = 0;
+    bit->argbColor[0].bGreen = 0;
+    bit->argbColor[0].bRed   = 0;
+
+    bit->argbColor[1].bBlue  = 255;
+    bit->argbColor[1].bGreen = 255;
+    bit->argbColor[1].bRed   = 255;
+
+    bit->cBitCount = pixel_mode_bit_count[ surface->root.bitmap.mode ];
+
+    surface->os2_bitmap = GpiCreateBitmap( surface->image_ps,
+                                           (PBITMAPINFOHEADER2)bit,
+                                           0L, NULL, NULL );
+
+    GpiSetBitmap( surface->image_ps, surface->os2_bitmap );
+
+    bit->cbFix = sizeof( BITMAPINFOHEADER2 );
+    GpiQueryBitmapInfoHeader( surface->os2_bitmap,
+                              (PBITMAPINFOHEADER2)bit );
+
+    /* for gr_pixel_mode_gray, create a gray-levels logical palette */
+    if ( bitmap->mode == gr_pixel_mode_gray )
+    {
+      int     x, count;
+
+      count = bitmap->grays;
+      for ( x = 0; x < count; x++ )
+        palette[x] = (((count-x)*255)/count) * 0x010101;
+
+      /* create logical color table */
+      GpiCreateLogColorTable( surface->image_ps,
+                              (ULONG) LCOL_PURECOLOR,
+                              (LONG)  LCOLF_CONSECRGB,
+                              (LONG)  0L,
+                              (LONG)  count,
+                              (PLONG) palette );
+
+      /* now, copy the color indexes to surface->shades */
+      for ( x = 0; x < count; x++ )
+        surface->shades[x] = GpiQueryColorIndex( surface->image_ps,
+                                                 0, palette[x] );
+    }
+
+    /* set up the blit points array */
+    surface->blit_points[1].x = surface->root.bitmap.width;
+    surface->blit_points[1].y = surface->root.bitmap.rows;
+    surface->blit_points[3]   = surface->blit_points[1];
+
+    /* Finally, create the event handling thread for the surface's window */
+    DosCreateThread( &surface->message_thread,
+                     (PFNTHREAD) RunPMWindow,
+                     (ULONG)     surface,
+                     0UL,
+                     32920 );
+
+    surface->root.done         = (grDoneSurfaceFunc) done_surface;
+    surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
+    surface->root.set_title    = (grSetTitleFunc)    set_title;
+    surface->root.listen_event = (grListenEventFunc) listen_event;
+    
+    convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
+    return 0;
+  }
+
+
+
+  MRESULT EXPENTRY  Message_Process( HWND    handle,
+                                     ULONG   mess,
+                                     MPARAM  parm1,
+                                     MPARAM  parm2 );
+
+
+  static
+  void  RunPMWindow( grPMSurface*  surface )
+  {
+    unsigned char   class_name[] = "DisplayClass";
+             ULONG  class_flags;
+
+    static   HMQ    queue;
+             QMSG   message;
+
+    /* create an anchor to allow this thread to use PM */
+    surface->anchor = WinInitialize(0);
+    if (!surface->anchor)
+    {
+      printf( "Error doing WinInitialize()\n" );
+      return;
+    }
+
+    /* create a message queue */
+    queue = WinCreateMsgQueue( surface->anchor, 0 );
+    if (!queue)
+    {
+      printf( "Error doing >inCreateMsgQueue()\n" );
+      return;
+    }
+
+    /* register the window class */
+    if ( !WinRegisterClass( surface->anchor,
+                            (PSZ)   class_name,
+                            (PFNWP) Message_Process,
+                            CS_SIZEREDRAW,
+                            0 ) )
+    {
+      printf( "Error doing WinRegisterClass()\n" );
+      return;
+    }
+
+    /* create the PM window */
+    class_flags = FCF_TITLEBAR | FCF_MINBUTTON | FCF_DLGBORDER | 
+                  FCF_TASKLIST | FCF_SYSMENU; 
+
+    surface->frame_window = WinCreateStdWindow(
+                                HWND_DESKTOP,
+                                WS_VISIBLE,
+                                &class_flags,
+                                (PSZ) class_name,
+                                (PSZ) "FreeType PM Graphics",
+                                WS_VISIBLE,
+                                0, 0,
+                                &surface->client_window );
+    if (!surface->frame_window)
+    {
+      printf( "Error doing WinCreateStdWindow()\n" );
+      return;
+    }
+
+    /* find the title window handle */
+    surface->title_window = WinWindowFromID( surface->frame_window,
+                                             FID_TITLEBAR );
+
+    /* set Window size and position */
+    WinSetWindowPos( surface->frame_window,
+                     0L,
+                     (SHORT) 60,
+                     (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) -
+                             surface->root.bitmap.rows + 100,
+
+                     (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
+                             surface->root.bitmap.width,
+
+                     (SHORT) WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) +
+                             WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME )*2 +
+                             surface->root.bitmap.rows,
+
+                     SWP_SIZE | SWP_MOVE );
+
+    /* save the handle to the current surface within the window words */
+    WinSetWindowPtr( surface->frame_window,QWL_USER, surface );
+
+    /* run the message queue till the end */
+    while ( WinGetMsg( surface->anchor, &message, (HWND)NULL, 0, 0 ) )
+      WinDispatchMsg( surface->anchor, &message );
+
+    /* clean-up */
+    WinDestroyWindow( surface->frame_window );
+    surface->frame_window = 0;
+
+    WinDestroyMsgQueue( queue );
+    WinTerminate( surface->anchor );
+
+    /* await death... */
+    while ( 1 )
+      DosSleep( 100 );
+  }
+
+
+
+
+  /* Message processing for our PM Window class */
+  MRESULT EXPENTRY  Message_Process( HWND    handle,
+                                     ULONG   mess,
+                                     MPARAM  parm1,
+                                     MPARAM  parm2 )
+  {
+     static HDC     screen_dc;
+     static HPS     screen_ps;
+     static BOOL    minimized;
+
+     SIZEL   sizl;
+     SWP     swp;
+
+     grPMSurface*  surface;
+
+    /* get the handle to the window's surface */
+    surface = (grPMSurface*)WinQueryWindowPtr( handle, QWL_USER );
+
+    switch( mess )
+    {
+    case WM_DESTROY:
+      /* warn the main thread to quit if it didn't know */
+      surface->event.type = gr_event_key;
+      surface->event.key  = grKeyEsc;
+      DosPostEventSem( surface->event_lock );
+      break;
+
+    case WM_CREATE:
+      /* set original magnification */
+      minimized = FALSE;
+
+      /* create Device Context and Presentation Space for screen. */
+      screen_dc = WinOpenWindowDC( handle );
+      screen_ps = GpiCreatePS( surface->anchor,
+                               screen_dc,
+                               &sizl,
+                               PU_PELS | GPIT_MICRO |
+                               GPIA_ASSOC | GPIF_DEFAULT );
+
+      /* take the input focus */
+      WinFocusChange( HWND_DESKTOP, handle, 0L );
+      break;
+
+    case WM_MINMAXFRAME:
+      /* to update minimized if changed */
+      swp = *((PSWP) parm1);
+      if ( swp.fl & SWP_MINIMIZE ) 
+        minimized = TRUE;
+      if ( swp.fl & SWP_RESTORE )
+        minimized = FALSE;
+      return WinDefWindowProc( handle, mess, parm1, parm2 );
+      break;
+
+    case WM_ERASEBACKGROUND:
+    case WM_PAINT:  
+      /* copy the memory image of the screen out to the real screen */
+      DosRequestMutexSem( surface->image_lock, SEM_INDEFINITE_WAIT );
+      WinBeginPaint( handle, screen_ps, NULL );
+      
+      /* main image and magnified picture */
+      GpiBitBlt( screen_ps,
+                 surface->image_ps,
+                 4L,
+                 surface->blit_points,
+                 ROP_SRCCOPY, BBO_AND );
+
+      WinEndPaint( screen_ps );
+      DosReleaseMutexSem( surface->image_lock );   
+      break;
+
+    case WM_CHAR:
+      if ( CHARMSG( &mess )->fs & KC_KEYUP )
+        break;
+
+      /* look for a specific vkey */
+      {
+        int          count = sizeof( key_translators )/sizeof( key_translators[0] );
+        Translator*  trans = key_translators;
+        Translator*  limit = trans + count;
+
+        for ( ; trans < limit; trans++ )
+          if ( CHARMSG(&mess)->vkey == trans->os2key )
+          {
+            surface->event.key = trans->grkey;
+            goto Do_Key_Event;
+          }
+      }
+
+      /* otherwise, simply record the character code */
+      if ( (CHARMSG( &mess )->fs & KC_CHAR) == 0 )
+        break;
+
+      surface->event.key = CHARMSG(&mess)->chr;
+
+    Do_Key_Event:
+      surface->event.type = gr_event_key;
+      DosPostEventSem( surface->event_lock );
+      break;
+
+    default:
+      return WinDefWindowProc( handle, mess, parm1, parm2 );
+    }
+
+    return (MRESULT) FALSE;
+  }
+
+
+
+
+
+
+
+#if 0
+  static
+  grKey  KeySymTogrKey(   key )
+  {
+    grKey        k;
+    int          count = sizeof(key_translators)/sizeof(key_translators[0]);
+    Translator*  trans = key_translators;
+    Translator*  limit = trans + count;
+
+    k = grKeyNone;
+
+    while ( trans < limit )
+    {
+      if ( trans->xkey == key )
+      {
+        k = trans->grkey;
+        break;
+      }
+      trans++;
+    }
+
+    return k;
+  }
+
+
+
+  static  
+  void  listen_event( grPMSurface* surface,
+                      int          event_mask,
+                      grEvent*     grevent )
+  {
+    grKey           grkey;
+
+    /* XXXX : For now, ignore the event mask, and only exit when */
+    /*        a key is pressed..                                 */
+    (void)event_mask;
+
+
+    /* Now, translate the keypress to a grKey */
+    /* If this wasn't part of the simple translated keys, simply get the charcode */
+    /* from the character buffer                                                  */
+    grkey = grKEY(key_buffer[key_cursor++]);
+      
+  Set_Key:
+    grevent->type = gr_key_down;
+    grevent->key  = grkey;
+  }
+
+#endif
+
+
+
+  grDevice  gr_os2pm_device =
+  {
+    sizeof( grPMSurface ),
+    "os2pm",
+    
+    init_device,
+    done_device,
+    
+    (grDeviceInitSurfaceFunc) init_surface,
+    
+    0,
+    0
+    
+  };
+
+
diff --git a/demos/graph/gros2pm.h b/demos/graph/gros2pm.h
new file mode 100644
index 0000000..2293580
--- /dev/null
+++ b/demos/graph/gros2pm.h
@@ -0,0 +1,23 @@
+#ifndef GROS2PM_H
+#define GROS2PM_H
+
+#include "grobjs.h"
+
+  extern
+  grDevice  gr_os2pm_device;
+
+#ifdef GR_INIT_BUILD
+  static
+  grDeviceChain  gr_os2pm_device_chain =
+  {
+    "os2pm",
+    &gr_os2pm_device,
+    GR_INIT_DEVICE_CHAIN
+  };
+
+#undef GR_INIT_DEVICE_CHAIN
+#define GR_INIT_DEVICE_CHAIN  &gr_os2pm_device_chain
+
+#endif  /* GR_INIT_BUILD */
+
+#endif /* GROS2PM_H */
diff --git a/demos/graph/grtypes.h b/demos/graph/grtypes.h
new file mode 100644
index 0000000..aca1856
--- /dev/null
+++ b/demos/graph/grtypes.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ *
+ *  grtypes.h
+ *
+ *    basic type defintions
+ *
+ *  Copyright 1999 - The FreeType Development Team - www.freetype.org
+ *
+ *
+ *
+ *
+ ***************************************************************************/
+
+#ifndef GRTYPES_H
+#define GRTYPES_H
+
+  typedef unsigned char  byte;
+
+#if 0
+  typedef signed char    uchar;
+
+  typedef unsigned long  ulong;
+  typedef unsigned short ushort;
+  typedef unsigned int   uint;
+#endif
+  
+  typedef struct grDimension_
+  {
+    int  x;
+    int  y;
+
+  } grDimension;
+
+#define gr_err_ok                    0
+#define gr_err_memory               -1
+#define gr_err_bad_argument         -2
+#define gr_err_bad_target_depth     -3
+#define gr_err_bad_source_depth     -4
+#define gr_err_saturation_overflow  -5
+#define gr_err_conversion_overflow  -6
+#define gr_err_invalid_device       -7
+
+
+#ifdef GR_MAKE_OPTION_SINGLE_OBJECT
+#define  GR_LOCAL_DECL    static
+#define  GR_LOCAL_FUNC    static
+#else
+#define  GR_LOCAL_DECL    extern
+#define  GR_LOCAL_FUNC    /* void */
+#endif
+
+#endif /* GRTYPES_H */
diff --git a/demos/graph/grx11.c b/demos/graph/grx11.c
new file mode 100644
index 0000000..99d8538
--- /dev/null
+++ b/demos/graph/grx11.c
@@ -0,0 +1,936 @@
+#include "grx11.h"
+
+
+#ifdef TEST
+#include "grfont.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <X11/keysym.h>
+
+  static void Panic( const char* message )
+  {
+    fprintf( stderr, "%s", message );
+    exit(1);
+  }
+
+  typedef struct Translator
+  {
+    KeySym  xkey;
+    grKey   grkey;
+    
+  } Translator;
+  
+  static
+  Translator  key_translators[] =
+  {
+    { XK_BackSpace, grKeyBackSpace },
+    { XK_Tab,       grKeyTab       },
+    { XK_Return,    grKeyReturn    },
+    { XK_Escape,    grKeyEsc       },
+    { XK_Home,      grKeyHome      },
+    { XK_Left,      grKeyLeft      },
+    { XK_Up,        grKeyUp        },
+    { XK_Right,     grKeyRight     },
+    { XK_Down,      grKeyDown      },
+    { XK_Page_Up,   grKeyPageUp    },
+    { XK_Page_Down, grKeyPageDown  },
+    { XK_End,       grKeyEnd       },
+    { XK_Begin,     grKeyHome      },
+    { XK_F1,        grKeyF1        },
+    { XK_F2,        grKeyF2        },
+    { XK_F3,        grKeyF3        },
+    { XK_F4,        grKeyF4        },
+    { XK_F5,        grKeyF5        },
+    { XK_F6,        grKeyF6        },
+    { XK_F7,        grKeyF7        },
+    { XK_F8,        grKeyF8        },
+    { XK_F9,        grKeyF9        },
+    { XK_F10,       grKeyF10       },
+    { XK_F11,       grKeyF11       },
+    { XK_F12,       grKeyF12       }
+  };
+
+
+#ifdef TEST
+  
+#define grAlloc  malloc
+  
+#endif
+
+
+  static Display*  display;
+  static char*     displayname = "";
+
+  static Cursor  idle;
+  static Cursor  busy;
+
+#define MAX_PIXEL_MODES  32
+
+  typedef XPixmapFormatValues  XDepth;
+
+  static int           num_pixel_modes = 0;
+  static grPixelMode   pixel_modes[ MAX_PIXEL_MODES ];  
+  static XDepth        pixel_depth[ MAX_PIXEL_MODES ];
+
+  typedef struct grXSurface_
+  {
+    grSurface      root;
+    grBitmap       image;
+
+    Window         win;
+    Visual*        visual;
+    Colormap       colormap;
+    int            depth;
+    Bool           gray;
+    
+    GC             gc;
+    
+    XColor         color[256];   /* gray levels palette for 8-bit modes */
+    XImage*        ximage;
+
+    int            win_org_x;
+    int            win_org_y;
+    int            win_width;
+    int            win_height;
+    
+    int            image_width;
+    int            image_height;
+    
+  } grXSurface;
+
+
+
+
+  /* close a given window */
+  static
+  void  done_surface( grXSurface*  surface )
+  {
+    XUnmapWindow( display, surface->win );
+  }
+
+
+
+  /* close the device, i.e. the display connection */
+  static
+  void  done_device( void )
+  {
+    XCloseDisplay( display );
+  }
+
+
+
+  static
+  void add_pixel_mode( grPixelMode  pixel_mode,
+                       XDepth*      depth )
+  {
+    if ( num_pixel_modes >= MAX_PIXEL_MODES )
+      Panic( "X11.Too many pixel modes\n" );
+      
+    pixel_modes[ num_pixel_modes ] = pixel_mode;
+    pixel_depth[ num_pixel_modes ] = *depth;
+    
+    num_pixel_modes++;
+  }
+
+
+
+  static
+  int  init_device( void )
+  {
+    XDepth  dummy;
+  
+    XrmInitialize();
+    
+    display = XOpenDisplay( displayname );
+    if (!display)
+    {
+      return -1;
+     /* Panic( "Gr:error: cannot open X11 display\n" ); */
+    }
+      
+    idle = XCreateFontCursor( display, XC_left_ptr );
+    busy = XCreateFontCursor( display, XC_watch );
+    
+    num_pixel_modes = 0;
+    
+    /* always enable the 8-bit gray levels pixel mode                */
+    /* even if its display is emulated through a constrained palette */
+    /* or another color mode                                         */
+    dummy.depth          = 8;
+    dummy.bits_per_pixel = 8;
+    dummy.scanline_pad   = 8;
+    add_pixel_mode( gr_pixel_mode_gray, &dummy );
+
+    {
+      int          count;
+      XDepth*      format;
+      XDepth*      formats;
+      XVisualInfo  template;
+
+      formats = XListPixmapFormats( display, &count );
+      format  = formats;
+       
+#ifdef TEST
+      printf( "available pixmap formats\n" );
+      printf( "depth  pixbits  scanpad\n" );
+#endif
+       
+      while ( count-- > 0 )
+      {
+#ifdef TEST 
+        printf( " %3d     %3d      %3d\n",
+                format->depth,
+                format->bits_per_pixel,
+                format->scanline_pad );
+#endif
+      
+        if ( format->depth == 1 )
+          /* usually, this should be the first format */
+          add_pixel_mode( gr_pixel_mode_mono, format );
+          
+        else if ( format->depth == 8 )
+          add_pixel_mode( gr_pixel_mode_pal8, format );
+
+        /* note, the 32-bit modes return a depth of 24, and 32 bits per pixel */          
+        else if ( format->depth == 24 )
+        {
+          if ( format->bits_per_pixel == 24 )
+            add_pixel_mode( gr_pixel_mode_rgb24, format );
+            
+          else if ( format->bits_per_pixel == 32 )
+            add_pixel_mode( gr_pixel_mode_rgb32, format );
+        }
+          
+        else if ( format->depth == 16 )
+        {
+          int           count2;
+          XVisualInfo*  visuals;
+          XVisualInfo*  visual;
+
+          template.depth = format->depth;
+          visuals        = XGetVisualInfo( display,
+                                           VisualDepthMask,
+                                           &template,
+                                           &count2 );
+          visual = visuals;
+          
+          while ( count2-- > 0 )
+          {
+#ifdef TEST 
+            const char*  string = "unknown";
+            
+            switch (visual->class)
+            {
+              case TrueColor:   string = "TrueColor";    break;
+              case DirectColor: string = "DirectColor";  break;
+              case PseudoColor: string = "PseudoColor";  break;
+              case StaticGray : string = "StaticGray";   break;
+              case StaticColor: string = "StaticColor";  break;
+              case GrayScale:   string = "GrayScale";    break;
+            }
+
+            printf( ">   RGB %02x:%02x:%02x, colors %3d, bits %2d  %s\n",
+                    visual->red_mask,
+                    visual->green_mask,
+                    visual->blue_mask,
+                    visual->colormap_size,
+                    visual->bits_per_rgb,
+                    string );
+#endif
+            if ( visual->red_mask   == 0xf800 &&
+                 visual->green_mask == 0x07e0 &&
+                 visual->blue_mask  == 0x001f )
+              add_pixel_mode( gr_pixel_mode_rgb565, format );
+              
+            else if ( visual->red_mask   == 0x7c00 &&
+                      visual->green_mask == 0x03e0 &&
+                      visual->blue_mask  == 0x001f )
+              add_pixel_mode( gr_pixel_mode_rgb555, format );
+              
+            /* other 16-bit modes are ignored */  
+            visual++;
+          }
+          
+          XFree( visuals );
+        }
+        
+        format++;
+      }
+      
+      XFree( formats );
+    }
+    
+    gr_x11_device.num_pixel_modes = num_pixel_modes;
+    gr_x11_device.pixel_modes     = pixel_modes;
+    
+    return 0;
+  }
+
+
+
+
+
+
+
+
+
+
+
+
+  static
+  void  convert_gray_to_pal8( grXSurface*  surface,
+                              int          x,
+                              int          y,
+                              int          w,
+                              int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    XColor*    palette = surface->color;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + w;
+      
+      for ( ; _write < limit; _write++, _read++ )
+        *_write = (byte) palette[ *_read ].pixel;
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_16( grXSurface*  surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 2*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    XColor*    palette = surface->color;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 2*w;
+      
+      for ( ; _write < limit; _write += 2, _read++ )
+        *(short*)_write = (short)palette[ *_read ].pixel;
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_24( grXSurface*  surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 3*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 3*w;
+      
+      for ( ; _write < limit; _write += 3, _read++ )
+      {
+        byte  color = *_read;
+        
+        _write[0] =
+        _write[1] =
+        _write[2] = color;
+      }
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_gray_to_32( grXSurface*  surface,
+                            int          x,
+                            int          y,
+                            int          w,
+                            int          h )
+  {
+    grBitmap*  target  = &surface->image;
+    grBitmap*  source  = &surface->root.bitmap;
+    byte*      write   = (byte*)target->buffer + y*target->pitch + 4*x;
+    byte*      read    = (byte*)source->buffer + y*source->pitch + x;
+    
+    while (h > 0)
+    {
+      byte*  _write = write;
+      byte*  _read  = read;
+      byte*  limit  = _write + 4*w;
+      
+      for ( ; _write < limit; _write += 4, _read++ )
+      {
+        byte  color = *_read;
+        
+        _write[0] =
+        _write[1] =
+        _write[2] =
+        _write[3] = color;
+      }
+
+      write += target->pitch;
+      read  += source->pitch;
+      h--;
+    }
+  }
+
+
+  static
+  void  convert_rectangle( grXSurface*  surface,
+                           int          x,
+                           int          y,
+                           int          w,
+                           int          h )
+  {
+    int  z;
+    
+    /* first of all, clip to the surface's area */
+    if ( x   >= surface->image.width ||
+         x+w <= 0                    ||
+         y   >= surface->image.rows  ||
+         y+h <= 0 )
+      return;
+ 
+    if ( x < 0 )
+    {
+      w += x;
+      x  = 0;
+    }
+ 
+    z = (x + w) - surface->image.width;
+    if (z > 0)
+      w -= z;
+      
+    z = (y + h) - surface->image.rows;
+    if (z > 0)
+      h -= z;
+      
+    /* convert the rectangle to the target depth for gray surfaces */
+    if (surface->gray)
+    {
+      switch (surface->depth)
+      {
+        case 8 : convert_gray_to_pal8( surface, x, y, w, h ); break;
+        case 16: convert_gray_to_16  ( surface, x, y, w, h ); break;
+        case 24: convert_gray_to_24  ( surface, x, y, w, h ); break;
+        case 32: convert_gray_to_32  ( surface, x, y, w, h ); break;
+      }
+    }
+  } 
+
+
+  static
+  void  refresh_rectangle( grXSurface*  surface,
+                           int          x,
+                           int          y,
+                           int          w,
+                           int          h )
+  {
+    if (surface->gray)
+      convert_rectangle( surface, x, y, w, h );
+    
+    XPutImage( display,
+               surface->win,
+               surface->gc,
+               surface->ximage,
+               x, y, x, y, w, h );
+  }
+
+  
+  static
+  void  set_title( grXSurface*  surface,
+                   const char*  title )
+  {
+    XStoreName( display, surface->win, title );
+  }
+
+
+
+  static
+  grKey  KeySymTogrKey( KeySym  key )
+  {
+    grKey        k;
+    int          count = sizeof(key_translators)/sizeof(key_translators[0]);
+    Translator*  trans = key_translators;
+    Translator*  limit = trans + count;
+
+    k = grKeyNone;
+
+    while ( trans < limit )
+    {
+      if ( trans->xkey == key )
+      {
+        k = trans->grkey;
+        break;
+      }
+      trans++;
+    }
+
+    return k;
+  }
+
+
+
+  static  
+  void  listen_event( grXSurface*  surface,
+                      int          event_mask,
+                      grEvent*     grevent )
+  {
+    static char     key_buffer[10];
+    static int      key_cursor = 0;
+    static int      key_number = 0;
+    static XEvent   x_event;
+           KeySym   key;
+
+    int             bool_exit;
+    grKey           grkey;
+
+    XComposeStatus  compose;
+
+    /* XXXX : For now, ignore the event mask, and only exit when */
+    /*        a key is pressed..                                 */
+    (void)event_mask;
+
+    bool_exit = key_cursor < key_number;
+
+    XDefineCursor( display, surface->win, idle );
+
+    while ( !bool_exit )
+    {
+      XNextEvent( display, &x_event );
+
+      switch ( x_event.type )
+      {
+      case KeyPress: 
+        key_number = XLookupString( &x_event.xkey,
+                                    key_buffer,
+                                    sizeof ( key_buffer ),
+                                    &key,
+                                    &compose );
+        key_cursor = 0;
+
+        if ( key_number == 0 ||
+             key > 512       )
+        {
+          /* this may be a special key like F1, F2, etc.. */
+          grkey = KeySymTogrKey(key);
+          if (grkey != grKeyNone)
+            goto Set_Key;  
+        }
+        else
+          bool_exit = 1;
+        break;
+
+      case MappingNotify:
+        XRefreshKeyboardMapping( &x_event.xmapping );
+        break;
+      
+      case Expose:
+        refresh_rectangle( surface,
+                           x_event.xexpose.x,
+                           x_event.xexpose.y,
+                           x_event.xexpose.width,
+                           x_event.xexpose.height );
+        break;
+
+      /* You should add more cases to handle mouse events, etc. */
+      }
+    }
+
+    XDefineCursor( display, surface->win, busy );
+    XFlush       ( display );
+
+    /* Now, translate the keypress to a grKey */
+    /* If this wasn't part of the simple translated keys, simply get the charcode */
+    /* from the character buffer                                                  */
+    grkey = grKEY(key_buffer[key_cursor++]);
+      
+  Set_Key:
+    grevent->type = gr_key_down;
+    grevent->key  = grkey;
+  }
+
+
+
+
+  grXSurface*  init_surface( grXSurface*  surface,
+                             grBitmap*    bitmap )
+  {
+    int        screen;
+    grBitmap*  image;
+    char       grays;
+    XDepth*    format;
+    int        image_depth;
+    
+    screen = DefaultScreen( display );
+    
+    surface->colormap = DefaultColormap( display, screen );
+    surface->depth    = DefaultDepth( display, screen );
+    surface->visual   = DefaultVisual( display, screen ); 
+
+    image  = &surface->image;
+
+    /* force the surface image depth to 1 if necessary */
+    /* as this should be supported by all windows      */
+    image_depth = surface->depth;
+    if (bitmap->mode == gr_pixel_mode_mono)
+      image_depth = 1;
+
+    grays = ( bitmap->mode == gr_pixel_mode_gray &&
+              bitmap->grays >= 2 );
+
+    surface->gray = grays;
+ 
+    /* copy dimensions */
+    image->width  = bitmap->width;
+    image->rows   = bitmap->rows;
+    image->mode   = bitmap->mode;
+    image->pitch  = 0;
+    image->grays  = 0;
+    image->buffer = 0;
+
+    /* find the supported format corresponding to the request */
+    format = 0;
+
+    if (grays)    
+    {
+      /* choose the default depth in case of grays rendering */
+      int  i;
+      for ( i = 0; i < num_pixel_modes; i++ )
+        if ( image_depth == pixel_depth[i].depth )
+        {
+          format = pixel_depth + i;
+          break;
+        }
+    }
+    else
+    {
+      /* otherwise, select the format depending on the pixel mode */
+      int  i;
+      
+      format = 0;
+      for ( i = 0; i < num_pixel_modes; i++ )
+        if ( pixel_modes[i] == bitmap->mode )
+        {
+          format = pixel_depth + i;
+          break;
+        }
+    }
+    
+    if (!format)
+    {
+      grError = gr_err_bad_argument;
+      return 0;
+    }
+
+
+    /* correct surface.depth. This is required because in the case    */
+    /* of 32-bits pixels, the value of "format.depth" is 24 under X11 */
+    if ( format->depth          == 24 &&
+         format->bits_per_pixel == 32 )
+      image_depth = 32;
+     
+    /* allocate surface image */
+    {
+      int  bits, over;
+
+      bits = image->width * format->bits_per_pixel;
+      over = bits % format->scanline_pad;
+          
+      if (over)
+        bits += format->scanline_pad - over;
+      
+      if (!grays)
+      {
+        image->width  = bits;
+        bitmap->width = bits;
+      }
+      image->pitch  = bits >> 3;
+    }
+
+    image->buffer = grAlloc( image->pitch * image->rows );
+    if (!image->buffer) return 0;
+
+    /* now, allocate a gray pal8 pixmap, only when we asked */
+    /* for an 8-bit pixmap                                  */
+    if ( grays )
+    {
+      /* pad pitch to 32 bits */
+      bitmap->pitch  = (bitmap->width + 3) & -4;
+      bitmap->buffer = grAlloc( bitmap->pitch * bitmap->rows );
+      if (!bitmap->buffer)
+        Panic( "grX11: could not allocate surface bitmap!\n" );
+    }
+    else  /* otherwise */
+    {
+      *bitmap = *image;
+    }
+
+    surface->root.bitmap = *bitmap;
+ 
+    /* Now create the surface X11 image */
+    surface->ximage = XCreateImage( display, 
+                                    surface->visual,
+                                    format->depth,
+                                    format->depth == 1 ? XYBitmap : ZPixmap,
+                                    0,
+                                    (char*)image->buffer,
+                                    image->width,
+                                    image->rows,
+                                    8,
+                                    0 );
+    if ( !surface->ximage )
+      Panic( "grX11: cannot create surface X11 image\n" );
+ 
+
+    /* allocate gray levels in the case of gray surface */
+    if ( grays )
+    {
+      XColor*  color = surface->color;
+      int      i;
+      
+      for ( i = 0; i < bitmap->grays; i++, color++ )
+      {
+        color->red   =
+        color->green =
+        color->blue  = 65535 - ( i * 65535 ) / bitmap->grays;
+  
+        if ( !XAllocColor( display, surface->colormap, color ) )
+          Panic( "ERROR: cannot allocate Color\n" );
+      }
+    }
+    else if ( image_depth == 1 )
+    {
+      surface->ximage->byte_order       = MSBFirst;
+      surface->ximage->bitmap_bit_order = MSBFirst;
+    }
+
+    {
+        XTextProperty         xtp;
+        XSizeHints            xsh;
+        XSetWindowAttributes  xswa;
+    
+        xswa.border_pixel     = BlackPixel( display, screen );
+        xswa.background_pixel = WhitePixel( display, screen );
+        xswa.cursor           = busy;
+    
+        xswa.event_mask = KeyPressMask | ExposureMask;
+    
+        surface->win = XCreateWindow( display,
+                                      RootWindow( display, screen ),
+                                      0,
+                                      0,
+                                      image->width,
+                                      image->rows,
+                                      10,
+                                      surface->depth,
+                                      InputOutput, 
+                                      surface->visual,
+                                      CWBackPixel | CWBorderPixel |
+                                        CWEventMask | CWCursor,
+                                      &xswa );
+    
+        XMapWindow( display, surface->win );
+ 
+        surface->gc = XCreateGC( display, RootWindow( display, screen ), 0L, NULL );
+        XSetForeground( display, surface->gc, xswa.border_pixel     );
+        XSetBackground( display, surface->gc, xswa.background_pixel );
+    
+    
+        /* make window manager happy :-) */
+        xtp.value    = (unsigned char*)"FreeType";
+        xtp.encoding = 31;
+        xtp.format   = 8;
+        xtp.nitems   = strlen( (char*)xtp.value );
+    
+        xsh.x = 0;
+        xsh.y = 0;
+    
+        xsh.width  = image->width;
+        xsh.height = image->rows;
+        xsh.flags  = (PPosition | PSize);
+        xsh.flags  = 0;
+    
+        XSetWMProperties( display, surface->win, &xtp, &xtp, NULL, 0, &xsh, NULL, NULL );
+    }
+    
+    surface->root.done         = (grDoneSurfaceFunc) done_surface;
+    surface->root.refresh_rect = (grRefreshRectFunc) refresh_rectangle;
+    surface->root.set_title    = (grSetTitleFunc)    set_title;
+    surface->root.listen_event = (grListenEventFunc) listen_event;
+    
+    convert_rectangle( surface, 0, 0, bitmap->width, bitmap->rows );
+    return surface;
+  }
+  
+
+
+
+  grDevice  gr_x11_device =
+  {
+    sizeof( grXSurface ),
+    "x11",
+    
+    init_device,
+    done_device,
+    
+    (grDeviceInitSurfaceFunc) init_surface,
+    
+    0,
+    0
+    
+  };
+
+#ifdef TEST
+
+typedef struct grKeyName
+{
+  grKey       key;
+  const char* name;
+
+} grKeyName;
+
+
+static
+const grKeyName  key_names[] =
+{
+  { grKeyF1,   "F1"  },
+  { grKeyF2,   "F2"  },
+  { grKeyF3,   "F3"  },
+  { grKeyF4,   "F4"  },
+  { grKeyF5,   "F5"  },
+  { grKeyF6,   "F6"  },
+  { grKeyF7,   "F7"  },
+  { grKeyF8,   "F8"  },
+  { grKeyF9,   "F9"  },
+  { grKeyF10,  "F10" },
+  { grKeyF11,  "F11" },
+  { grKeyF12,  "F12" },
+  { grKeyEsc,  "Esc" },
+  { grKeyHome, "Home" },
+  { grKeyEnd,  "End"  },
+    
+  { grKeyPageUp,   "Page_Up" },
+  { grKeyPageDown, "Page_Down" },
+  { grKeyLeft,     "Left" },
+  { grKeyRight,    "Right" },
+  { grKeyUp,       "Up" },
+  { grKeyDown,     "Down" },
+  { grKeyBackSpace, "BackSpace" },
+  { grKeyReturn,   "Return" }
+};
+
+int  main( void )
+{
+  grSurface*  surface;
+  int         n;
+  
+  grInit();
+  surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
+  if (!surface)
+    Panic("Could not create window\n" );
+  else
+  {
+    grColor      color;
+    grEvent      event;
+    const char*  string;
+    int          x;
+    
+    grSetSurfaceRefresh( surface, 1 );
+    grSetTitle(surface,"X11 driver demonstration" );
+    
+    for ( x = -10; x < 10; x++ )
+    {
+      for ( n = 0; n < 128; n++ )
+      {
+        color.value = (n*3) & 127;
+        grWriteCellChar( surface,
+                         x + ((n % 60) << 3),
+                         80 + (x+10)*8*3 + ((n/60) << 3), n, color );
+      }
+
+    }
+    color.value = 64;
+    grWriteCellString( surface, 0, 0, "just an example", color );
+    
+    do
+    {
+      listen_event((grXSurface*)surface, 0, &event);
+    
+      /* return if ESC was pressed */
+      if ( event.key == grKeyEsc )
+        return 0;
+      
+      /* otherwise, display key string */
+      color.value = (color.value + 8) & 127;
+      {
+        int         count = sizeof(key_names)/sizeof(key_names[0]);
+        grKeyName*  name  = key_names;
+        grKeyName*  limit = name + count;
+        const char* kname  = 0;
+        char        kname_temp[16];
+      
+        while (name < limit)
+        {
+          if ( name->key == event.key )
+          {
+            kname = name->name;
+            break;
+          }
+          name++;
+        }
+      
+        if (!kname)
+        {
+          sprintf( kname_temp, "char '%c'", (char)event.key );
+          kname = kname_temp;
+        }
+        
+        grWriteCellString( surface, 30, 30, kname, color );
+        grRefreshSurface(surface);
+        paint_rectangle( surface, 0, 0, surface->bitmap.width, surface->bitmap.rows );
+      }
+    } while (1);
+  }
+    
+  return 0;
+  
+  
+}
+#endif /* TEST */
+
diff --git a/demos/graph/grx11.h b/demos/graph/grx11.h
new file mode 100644
index 0000000..cd77112
--- /dev/null
+++ b/demos/graph/grx11.h
@@ -0,0 +1,24 @@
+#ifndef GRX11_H
+#define GRX11_H
+
+#include "grobjs.h"
+#include "grdevice.h"
+
+  extern
+  grDevice  gr_x11_device;
+
+#ifdef GR_INIT_BUILD
+  static
+  grDeviceChain  gr_x11_device_chain =
+  {
+    "x11",
+    &gr_x11_device,
+    GR_INIT_DEVICE_CHAIN
+  };
+
+#undef GR_INIT_DEVICE_CHAIN
+#define GR_INIT_DEVICE_CHAIN  &gr_x11_device_chain
+
+#endif  /* GR_INIT_BUILD */
+
+#endif /* GRX11_H */
diff --git a/demos/graph/migs.html b/demos/graph/migs.html
new file mode 100644
index 0000000..365b9c9
--- /dev/null
+++ b/demos/graph/migs.html
@@ -0,0 +1,304 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.6 [en] (X11; I; Linux 2.2.9-19mdk i586) [Netscape]">
+</head>
+<body>
+
+<center><font size=+2>MiGS Overview</font>
+<br><font size=+2>A Minimalist Graphics Subsystem</font>
+<p>
+<hr WIDTH="100%"></center>
+
+<h1>
+<font size=+0>Introduction</font></h1>
+
+<blockquote>This document details the design and implementation of MiGS,
+the minimalist graphics subsystem used by the FreeType 2 demonstration
+programs. Its purpose is mainly to help writers of new demo programs, as
+well as developers who would like port the subsystem to other platforms.</blockquote>
+
+<hr WIDTH="100%">
+<h1>
+I - Design goals</h1>
+
+<blockquote>MiGS is a tiny graphics subsystem used to demo text rendering
+through the FreeType library. It was mainly written to provide the abilities
+to :</blockquote>
+
+<ul>
+<ul>
+<li>
+draw a monochrome glyph bitmap to many kinds of target surfaces (i.e. really
+bitmaps/pixmaps)</li>
+
+<li>
+draw an anti-aliased glyph bitmap, with any level of grays, to many kinds
+of target surfaces</li>
+
+<li>
+display a simple window on many systems like X11, OS/2 and Windows</li>
+
+<li>
+accept simple events (keypresses and mouse buttons) in this window.</li>
+
+<li>
+to be portable and present a unified API on all running systems</li>
+</ul>
+
+<p><br>MiGS uses system-specific "drivers" in order to perform display
+and event handling. The blitting functions are not device-specific. MiGS
+can be built and/or used with no system-specific features, like for example,
+to generate simple GIF, PNG, TIFF, etc.. images without ever needing to
+display them.</ul>
+
+<h1>
+
+<hr WIDTH="100%"></h1>
+
+<h1>
+II - Surfaces, bitmaps and windows</h1>
+
+<blockquote>A surface in MiGS models a drawable region where glyph images
+can be rendered, a surface always contains a bitmap descriptor as well
+as a few other things that will be described later in this section.
+<p>Some surfaces can be displayed, they are then either called <i>windowed
+surfaces</i> or <i>screen surfaces</i> depending on the nature of the <i>device</i>
+used to display them. Each <i>device</i> is implemented by a very simple
+<i>driver</i> in the MiGS code. Here are a few example devices that are
+or could be written to display surfaces :
+<p>- an X11 device
+<br>- a Win 32 GDI device
+<br>- an OS/2 Presentation Manager device
+<br>- a fullscreen SVGALib device on Linux
+<br>- a GGI visual device
+<br>- an OS/2 "Dive" device, or the equivalent Win32 "DirectX" device
+<p>etc..
+<p><b>NOTE: </b>For now, only the X11 device was written and tested.. More
+devices should come later
+<p>Before explaining how to create a surface, we need to explain how MiGS
+manages bitmaps and renders glyph images to them.
+<h3>
+1. Bitmaps :</h3>
+
+<blockquote>A bitmap in MiGS features the following things :
+<ul>
+<li>
+a <b><i>width</i></b> in pixels</li>
+
+<li>
+a <b><i>height</i></b> in pixels</li>
+
+<li>
+a <b><i>pixel mode</i></b>, which indicates how the pixels are stored in
+the surface's buffer</li>
+
+<li>
+a <b><i>pitch</i></b>, whose absolute values is the number of bytes taken
+by each surface row</li>
+
+<li>
+a <b><i>number</i></b> of valid <b><i>gray</i></b> levels (see below)</li>
+
+<li>
+a <b><i>buffer</i></b>, holding the surface's pixels</li>
+</ul>
+
+<p><br>MiGS uses the <i>"Y downwards"</i> convention, which means that
+<i>increasing
+Y</i> coordinates correspond to <i>lower rows</i> of the bitmap. Hence,
+the coordinate <i>(0,0)</i> always corresponds to the bitmap's
+<i>top-left
+pixel</i>.
+<p>The bitmap's rows can be stored either <i>"downwards"</i> or <i>"upwards"</i>
+in the pixel buffer.
+<p>In the first case (<i>downwards</i>), increasing memory addresses in
+the pixel buffer correspond to lower rows of the bitmap(e.g. PC video modes),
+and the <b><i>pitch</i></b> should be equal to <b><i>the number of bytes
+taken by each row</i></b>. The first pixel buffer byte corresponds to the
+upper row.
+<p>In the second case (<i>upwards</i>), increasing memory addresses in
+the pixel buffer correspond to upper rows of the bitmap and the <b><i>pitch</i></b>
+should be equal to the <b><i>opposite</i></b> of <i>the number of bytes
+taken by each row</i>. The first pixel buffer byte corresponds to the lower
+row.
+<p>In all cases, the <b><i>pitch</i></b> is the <i>increment to be used
+to go from one bitmap row to the one below it</i>.
+<p>The supported pixel modes are :
+<ul>
+<li>
+1-bit monochrome bitmaps. With "0" as the background, and "1" as the foreground.</li>
+
+<li>
+4-bit color bitmaps, using an arbitrary palette.</li>
+
+<li>
+8-bit color bitmaps, using an arbitrary palette.</li>
+
+<li>
+8-bit gray bitmaps, using a given N number of gray levels in the range
+0..N-1.</li>
+
+<li>
+15-bit color bitmaps, also known as RGB555</li>
+
+<li>
+16-bit color bitmaps, also known as RGB565</li>
+
+<li>
+24-bit color bitmaps, also known as RGB</li>
+
+<li>
+32-bit color bitmaps, also known as RGBA (though the A is ignored by MiGS)</li>
+</ul>
+The bitmap's <b><i>number of gray levels</i></b> is only relevant for <b><i>8-bit
+gray bitmaps</i></b>, and indicates the range of gray levels that can be
+found in the bitmap. If a bitmap as N gray levels, it is said to be <i>N-grayscales</i>,
+and the pixels within it must all have values between 0, considered as
+the <i>background</i> color, and N-1, considered as the <i>foreground</i>
+color.
+<p>N-grayscale bitmaps are crucial for the rendering of anti-aliased text.
+<br>&nbsp;</blockquote>
+
+<h3>
+2. Glyph images :</h3>
+
+<blockquote>The glyph images that can be drawn on bitmaps through MiGS
+are bitmaps themselves, though limited to the following pixel modes :
+<p><b>1-bit monochrome glyph bitmaps</b>
+<blockquote>These can be drawn on any kind of bitmap. Note that <i>only
+the "lit" pixels</i> (i.e. the bits set to 1) are effectively drawn to
+the target, as opaque blitting isn't supported (remember, it's a minimalist
+library !)</blockquote>
+
+<p><br><b>N-grayscales glyph images </b>(with any value of N >= 2)
+<blockquote>These can be drawn to <i>all RGB bitmaps</i> (15, 16, 24 &amp;
+32 bits/pixel), as well as any other M-grayscales bitmaps. In the latter
+case, the values of N and M <i>need not be equal</i>, as the library is
+able to perform automatic conversions <i>on the fly</i>.
+<p>For example, it is possible to render a 5-grayscales glyph image into
+a 128-grayscales bitmap. Moreover, it is also possible to render a 17-grayscales
+glyph image into a 5-grayscales bitmap, even if this will result in <i>a
+loss of quality</i>. This feature is crucial in order to experiment easily
+with other anti-aliasing algorithms for FreeType
+<br>&nbsp;</blockquote>
+Note that you can <i>only</i> draw <i>monochrome</i> bitmaps to the following
+pixel modes : monochrome, 4-bit color and 8-bit color.</blockquote>
+
+<h3>
+3. Windows and Screens:</h3>
+
+<blockquote>In order to debug FreeType, displaying a surface in a window
+or in full-screen mode, is required. MiGS thus makes a difference between
+<i>simple
+surfaces</i>, which only contain a bitmap, <i>windowed surfaces</i>, which
+are used to display their content in a window, and <i>screen surfaces</i>,
+which are used to display their content in a full-screen mode (SVGAlib,
+DirectX, GGI or wathever).
+<p>A few important things must be said about non-simple surfaces.
+<br>&nbsp;
+<ul>
+<li>
+First, they might contain some system-specific data which is used to manage
+the display in a window or on the screen. This must be <i>completely hidden</i>
+to MiGS clients. Indeed, rendering to any kind of surface is achieved through
+<i>exactly
+the same function calls</i>.</li>
+</ul>
+
+<ul>
+<li>
+Second, they may contain a bitmap whose pixel mode doesn't correspond to
+the screen's depth used to display it. For example, the surface might contain
+an 128-grayscale bitmap, while the screen is in RGB24 mode. Some conversion
+must be performed to display the surface. This can either happen in the
+system-specific graphics library (e.g. on OS/2, a single Presentation Manager
+call is used to blit a N-grayscale image to <i>any</i> kind of window)
+or in the system-specific part of MiGS (e.g. the X11 MiGS driver must convert
+the surface's bitmap into the appropriate <i>X11 image</i> each time a
+repaint is requested). Again this must be completely hidden to MiGS clients</li>
+</ul>
+Surfaces have also a few fields that are only used when displaying them
+in Windows :
+<p><b>a title string</b>
+<blockquote>This is simply a text string that is displayed on the title
+bar of the surface's window. It can also appear at the top or bottom of
+full-screen surfaces if the MiGS driver supports it. The title string can
+be changed with a call to <tt>grSetTitle</tt>, and is ignored for simple
+surfaces.</blockquote>
+
+<p><br><b>a refresh flag</b>
+<blockquote>This boolean flag is only used for window surfaces, and some
+fullscreen ones (depending on the driver implementation). When set, it
+indicates that each glyph image blit must be displayed immediately. By
+default, this flag is set to False, which means that demo programs must
+call the <tt>grRefreshSurface(surface)</tt> function to display the whole
+contents of a surface one it has been updated.
+<p>The refresh flag can be set with <tt>grSetSurfaceRefresh(surface,flag)</tt>.
+Note that a single surface rectangle can be forced to be displayed with
+a call to <tt>grRefreshRectangle(surface,x,y,w,h)</tt> at any time.</blockquote>
+</blockquote>
+
+<h3>
+4. Devices :</h3>
+
+<blockquote>As said before, each device is in charge of displaying a surface
+in a given window or screen. Each device is managed through a very simple
+driver, described to MiGS through a very simple "grDevice" structure.
+<p>A grDevice contains, among other things, pointers to the functions used
+to:
+<p>- refresh/display a given rectangle of the surface to the window/screen
+<br>- listen events (key presses and mouse) and send them back to client
+apps.
+<br>- for windowed devices, update the title bar.
+<p>As said before, this is a highly minimalist system..
+<br>&nbsp;</blockquote>
+</blockquote>
+
+<hr WIDTH="100%">
+<h1>
+III - Important implementation issues :</h1>
+
+<blockquote>
+<h3>
+1. Display surface negociation :</h3>
+
+<blockquote>A display surface is created with the function grNewScreenSurface
+which takes parameters indicating which device should be used, the pixel
+dimensions of the requested surface, as well as its pixel mode.
+<p>Because of some device-specific limitations, the resulting surface's
+properties might not match exactly those requested for the call. Hence,
+a developper should <b>always take care </b>of reading a new display surface's
+<b>bitmap</b> descriptor in order to get its <i>real</i> dimensions, pixel
+mode and eventually number of grays.
+<p>The function grNewSurface will create a memory surface with the corresponding
+bitmap.
+<br>The function grNewBitmapSurface will create a surface from a pre-existing
+bitmap.&nbsp;This is useful to draw text on loaded images, for example.
+<p>Any surface (display or not) is destroyed with grDoneSurface.</blockquote>
+
+<h3>
+</h3>
+
+<h3>
+2. Supporting 8-bit grayscale mode :</h3>
+
+<blockquote>It is important, for the debugging of FreeType anti-aliased
+renderer(s), that <b><i>_all_ devices should support the 8-bit gray mode</i></b>.
+The number of gray levels can be fixed or negociated as required by implementation-specific
+issues.
+<p>As most existing devices do not provide direct support for such a mode,
+each 8-bit surface must thus contain :
+<p>- an internal N-grayscale bitmap, used as the target of all glyph drawings
+<br>- its own device-specific "image", which matches the display depth.
+<p>Each time the device's "refresh_rect" function is called, it should
+then :
+<br>- convert the grayscales within the bitmap's rectangle into the image's
+buffer and format.
+<br>- display the corresponding image rectangle.
+<p>This scheme is used, for example, by the X11 device.</blockquote>
+</blockquote>
+
+</body>
+</html>
diff --git a/demos/graph/rules.mk b/demos/graph/rules.mk
new file mode 100644
index 0000000..d397e54
--- /dev/null
+++ b/demos/graph/rules.mk
@@ -0,0 +1,99 @@
+#**************************************************************************
+#*
+#*  FreeType demo utilities sub-Makefile
+#*
+#*  This Makefile is to be included by "freetype/demo/Makefile". Its
+#*  purpose is to compile MiGS (the Minimalist Graphics Subsystem)
+#*
+#*  It is written for GNU Make. Other make utilities are not
+#*  supported.. !!
+#*
+#*
+#*  The following variables must be defined :
+#*
+#*  CFLAGS     : C flags to use when compiling the utilities. This
+#*               must NOT include the '-c' flag used to specify a
+#*               simple compilation.
+#*
+#*  IFLAG      : include path flag. This is typically "-I" but some
+#*               compilers use a different convention..
+#*
+#*  LFLAG      : add link directory flag. Usually '-L' but could be
+#*               different..
+#*
+#*  OBJ_DIR    : target location of the object files
+#*
+#*  UTIL_DIR   : location of the utilities sources. I.e. this
+#*               directory (usually "freetype/demo/graph").
+#*
+#*
+#*  It also defines the following variables
+#*
+#*  SIMPLE_UTILS : list of object files for the non-graphical utilities
+#*
+#*  GRAPH_UTILS  : all object files, including the graphics sub-system
+#*
+#*  GRAPH_FLAGS  : additional compile flags for graphical apps
+#*  GRAPH_LINK   : additional link flags for graphical apps
+#*
+#**************************************************************************
+
+##########################################################################
+#
+#
+#
+#
+#
+
+GRAPH_INCLUDES := graph
+GRAPH_LIB      := $(OBJ_)graph.a
+GRAPH_LINK     := $(GRAPH_LIB)
+
+GRAPH_ := graph$(SEP)
+
+GRAPH_H := $(GRAPH_)graph.h    \
+           $(GRAPH_)grtypes.h  \
+           $(GRAPH_)grobjs.h   \
+           $(GRAPH_)grdevice.h \
+           $(GRAPH_)grblit.h
+
+
+GRAPH_OBJS := $(OBJ_)grblit.$O   \
+              $(OBJ_)grobjs.$O   \
+              $(OBJ_)grfont.$O   \
+              $(OBJ_)grdevice.$O \
+              $(OBJ_)grinit.$O
+
+
+# Add the rules used to detect and compile graphics driver depending
+# on the current platform..
+#
+include $(wildcard config/*/rules.mk)
+
+#########################################################################
+#
+# Build the "graph" library from its objects. This should be changed
+# in the future in order to support more systems. Probably something
+# like a `config/<system>' hierarchy with a system-specific rules file
+# to indicate how to make a library file, but for know, I'll stick to
+# unix and OS/2-gcc..
+#
+#
+$(GRAPH_LIB): $(GRAPH_OBJS)
+	ar -r $@ $(GRAPH_OBJS)
+
+
+# pattern rule for normal sources
+#
+$(OBJ_)%.$O: $(GRAPH_)%.c $(GRAPH_H)
+	$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $T$@ $<
+
+
+# a special rule is used for 'grinit.o' as it needs the definition
+# of some macros like "-DDEVICE_X11" or "-DDEVICE_OS2_PM"
+#
+$(OBJ_)grinit.$O: $(GRAPH_)grinit.c
+	$(CC) $(CFLAGS) $(GRAPH_INCLUDES:%=$I%) $I$(DEVICE_INCLUDES:%=$I%) $T$@ $< \
+                        $(DEVICES:%=$DDEVICE_%)
+
+
diff --git a/demos/graph/xtest.c b/demos/graph/xtest.c
new file mode 100644
index 0000000..4c6295e
--- /dev/null
+++ b/demos/graph/xtest.c
@@ -0,0 +1,125 @@
+#include "graph.h"
+#include "grfont.h"  /* dispara^itra bientot */
+#include <stdio.h>
+
+
+static
+void Panic( const char*  message )
+{
+  fprintf( stderr, "PANIC: %s\n", message );
+  exit(1);
+}
+
+
+typedef struct grKeyName
+{
+  grKey       key;
+  const char* name;
+
+} grKeyName;
+
+
+static
+const grKeyName  key_names[] =
+{
+  { grKeyF1,   "F1"  },
+  { grKeyF2,   "F2"  },
+  { grKeyF3,   "F3"  },
+  { grKeyF4,   "F4"  },
+  { grKeyF5,   "F5"  },
+  { grKeyF6,   "F6"  },
+  { grKeyF7,   "F7"  },
+  { grKeyF8,   "F8"  },
+  { grKeyF9,   "F9"  },
+  { grKeyF10,  "F10" },
+  { grKeyF11,  "F11" },
+  { grKeyF12,  "F12" },
+  { grKeyEsc,  "Esc" },
+  { grKeyHome, "Home" },
+  { grKeyEnd,  "End"  },
+    
+  { grKeyPageUp,   "Page_Up" },
+  { grKeyPageDown, "Page_Down" },
+  { grKeyLeft,     "Left" },
+  { grKeyRight,    "Right" },
+  { grKeyUp,       "Up" },
+  { grKeyDown,     "Down" },
+  { grKeyBackSpace, "BackSpace" },
+  { grKeyReturn,   "Return" }
+};
+
+int  main( void )
+{
+  grSurface*  surface;
+  int         n;
+  
+  grInit();
+  surface = grNewScreenSurface( 0, gr_pixel_mode_gray, 320, 400, 128 );
+  if (!surface)
+    Panic("Could not create window\n" );
+  else
+  {
+    grColor      color;
+    grEvent      event;
+    const char*  string;
+    int          x;
+    
+    grSetSurfaceRefresh( surface, 1 );
+    grSetTitle(surface,"X11 driver demonstration" );
+    
+    for ( x = -10; x < 10; x++ )
+    {
+      for ( n = 0; n < 128; n++ )
+      {
+        color.value = (n*3) & 127;
+        grWriteCellChar( surface,
+                         x + ((n % 60) << 3),
+                         80 + (x+10)*8*3 + ((n/60) << 3), n, color );
+      }
+
+    }
+    color.value = 64;
+    grWriteCellString( surface, 0, 0, "just an example", color );
+    
+    do
+    {
+      grListenSurface( surface, 0, &event);
+    
+      /* return if ESC was pressed */
+      if ( event.key == grKeyEsc )
+        return 0;
+      
+      /* otherwise, display key string */
+      color.value = (color.value + 8) & 127;
+      {
+        int         count = sizeof(key_names)/sizeof(key_names[0]);
+        grKeyName*  name  = (grKeyName*)key_names;
+        grKeyName*  limit = name + count;
+        const char* kname  = 0;
+        char        kname_temp[16];
+      
+        while (name < limit)
+        {
+          if ( name->key == event.key )
+          {
+            kname = (const char*)name->name;
+            break;
+          }
+          name++;
+        }
+      
+        if (!kname)
+        {
+          sprintf( kname_temp, "char '%c'", (char)event.key );
+          kname = kname_temp;
+        }
+        
+        grWriteCellString( surface, 30, 30, kname, color );
+        grRefreshSurface(surface);
+      }
+    } while (1);
+  }
+
+  return 0;
+}
+
diff --git a/demos/obj/README b/demos/obj/README
new file mode 100644
index 0000000..f11d2c1
--- /dev/null
+++ b/demos/obj/README
@@ -0,0 +1 @@
+This directory contains all the object files generated for the demonstration programs
diff --git a/demos/src/common.c b/demos/src/common.c
new file mode 100644
index 0000000..8a57405
--- /dev/null
+++ b/demos/src/common.c
@@ -0,0 +1,244 @@
+/*
+ *  This is a cheap replacement for getopt() because that routine is not
+ *  available on some platforms and behaves differently on other platforms.
+ *  This code was written from scratch without looking at any other
+ *  implementation.
+ *
+ *  This code is hereby expressly placed in the public domain.
+ *  mleisher@crl.nmsu.edu (Mark Leisher)
+ *  10 October 1997
+ */
+
+#ifndef lint
+#ifdef __GNUC__
+  static char rcsid[] __attribute__ ((unused)) = "$Id$";
+#else
+  static char rcsid[] = "$Id$";
+#endif
+#endif
+
+#include "common.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+  /*
+   *  Externals visible to programs.
+   */
+
+  int    opterr = 1;
+  int    optind = 1;
+  char*  optarg;
+
+  /*
+   *  Internal variables that are used to detect when the global values
+   *  need to be reset.
+   */
+
+  static int  cmdac;
+#ifdef __STDC__
+  static const char*   cmdname;
+  static char* const*  cmdav;
+#else
+  static char*   cmdname;
+  static char**  cmdav;
+#endif
+
+  int
+#ifdef __STDC__
+  getopt( int  ac, char* const*  av, const char*  pat )
+#else
+  getopt( ac, av, pat )
+    int     ac;
+    char**  av;
+    char*   pat;
+#endif
+  {
+    int  opt;
+#ifdef __STDC__
+    const char*  p;
+    const char*  pp;
+#else
+    char*  p;
+    char*  pp;
+#endif
+
+    /*
+     *  If there is no pattern, indicate the parsing is done.
+     */
+    if ( pat == 0 || *pat == 0 )
+      return -1;
+
+    /*
+     *  Always reset the option argument to NULL.
+     */
+    optarg = 0;
+
+    /*
+     *  If the number of arguments or argument list do not match the last
+     *  values seen, reset the internal pointers and the globals.
+     */
+    if ( ac != cmdac || av != cmdav )
+    {
+      optind = 1;
+      cmdac = ac;
+      cmdav = av;
+
+      /*
+       *  Determine the command name in case it is needed for warning
+       *  messages.
+       */
+      for ( cmdname = 0, p = av[0]; *p; p++ )
+      {
+        if ( *p == '/' || *p == '\\' )
+          cmdname = p;
+      }
+      /*
+       *  Skip the path separator if the name was assigned.
+       */
+      if ( cmdname )
+        cmdname++;
+      else
+        cmdname = av[0];
+    }
+
+    /*
+     *  If the next index is greater than or equal to the number of
+     *  arguments, then the command line is done.
+     */
+    if ( optind >= ac )
+      return -1;
+
+    /*
+     *  Test the next argument for one of three cases:
+     *    1. The next argument does not have an initial '-'.
+     *    2. The next argument is '-'.
+     *    3. The next argument is '--'.
+     *
+     *  In either of these cases, command line processing is done.
+     */
+    if ( av[optind][0] != '-'            ||
+         strcmp( av[optind], "-" ) == 0  ||
+         strcmp( av[optind], "--" ) == 0 )
+      return -1;
+
+    /*
+     *  Point at the next command line argument and increment the
+     *  command line index.
+     */
+    p = av[optind++];
+
+    /*
+     *  Look for the first character of the command line option.
+     */
+    for ( opt = *(p + 1), pp = pat; *pp && *pp != opt; pp++ )
+      ;
+
+    /*
+     *  If nothing in the pattern was recognized, then issue a warning
+     *  and return a '?'.
+     */
+    if ( *pp == 0 )
+    {
+      if ( opterr )
+        fprintf( stderr, "%s: illegal option -- %c\n", cmdname, opt );
+      return '?';
+    }
+
+    /*
+     *  If the option expects an argument, get it.
+     */
+    if ( *(pp + 1) == ':' && (optarg = av[optind]) == 0 )
+    {
+      /*
+       *  If the option argument is NULL, issue a warning and return a '?'.
+       */
+      if ( opterr )
+        fprintf( stderr, "%s: option requires an argument -- %c\n",
+                         cmdname, opt );
+      opt = '?';
+    }
+    else if ( optarg )
+    /*
+     *  Increment the option index past the argument.
+     */
+      optind++;
+
+    /*
+     *  Return the option character.
+     */
+    return opt;
+  }
+
+
+/****************************************************************************/
+/*                                                                          */
+/*  The FreeType project -- a free and portable quality TrueType renderer.  */
+/*                                                                          */
+/*  Copyright 1996-1998 by                                                  */
+/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
+/*                                                                          */
+/* ft_basename():                                                           */
+/*                                                                          */
+/* a stupid but useful function...                                          */
+/*                                                                          */
+/* rewritten by DavidT to get rid of GPLed programs in the FreeType demos.  */
+/*                                                                          */
+/****************************************************************************/
+
+  char*
+#ifdef __STDC__
+  ft_basename ( const char*  name )
+#else
+  ft_basename ( name )
+    char* name;
+#endif
+  {
+#ifdef __STDC__
+    const char*  base;
+    const char*  current;
+#else
+    char*        base;
+    char*        current;
+#endif
+    char         c;
+
+    base    = name;
+    current = name;
+
+    c = *current;
+  
+    while ( c )
+    {
+      if ( c == '/' || c == '\\' )
+        base = current + 1;
+
+      current++;
+      c = *current;
+    }
+
+    return (char*)base;
+  }
+
+
+#ifdef __STDC__
+  void Panic( const char*  fmt, ... )
+#else
+  void Panic( fmt )
+    const char* fmt;
+#endif
+  {
+    va_list  ap;
+
+
+    va_start( ap, fmt );
+    vprintf( fmt, ap );
+    va_end( ap );
+
+    exit( 1 );
+  }
+
+
+/* End */
diff --git a/demos/src/common.h b/demos/src/common.h
new file mode 100644
index 0000000..e137708
--- /dev/null
+++ b/demos/src/common.h
@@ -0,0 +1,53 @@
+/*
+ *  This is a cheap replacement for getopt() because that routine is not
+ *  available on some platforms and behaves differently on other platforms.
+ *
+ *  This code is hereby expressly placed in the public domain.
+ *  mleisher@crl.nmsu.edu (Mark Leisher)
+ *  10 October 1997
+ */
+
+#ifndef _H_COMMON
+#define _H_COMMON
+
+/* Note that by default, both functions are implemented in common.c */
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+  extern int    opterr;
+  extern int    optind;
+  extern char*  optarg;
+
+  extern int  getopt(
+#ifdef __STDC__
+    int           argc,
+    char* const*  argv,
+    const char*   pattern
+#endif
+  );
+
+
+  extern char*  ft_basename(
+#ifdef __STDC__
+    const char*  name
+#endif
+  );
+
+  /* print a message and exit */
+  extern  void  Panic  (
+#ifdef __STDC__
+    const char*  fmt, ...
+#endif
+  );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* _H_COMMON */
+
+
+/* End */
diff --git a/demos/src/ftlint.c b/demos/src/ftlint.c
new file mode 100644
index 0000000..0dc3926
--- /dev/null
+++ b/demos/src/ftlint.c
@@ -0,0 +1,169 @@
+/****************************************************************************/
+/*                                                                          */
+/*  The FreeType project -- a free and portable quality TrueType renderer.  */
+/*                                                                          */
+/*  Copyright 1996-1998 by                                                  */
+/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
+/*                                                                          */
+/*  ftlint: a simple font tester. This program tries to load all the        */
+/*          glyphs of a given font.                                         */
+/*                                                                          */
+/*  NOTE:  This is just a test program that is used to show off and         */
+/*         debug the current engine.                                        */
+/*                                                                          */
+/****************************************************************************/
+
+#include "freetype.h"
+#include "ftobjs.h"
+#include "ftdriver.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define gettext( x )  ( x )
+
+  FT_Error      error;
+
+  FT_Library    library;
+  FT_Face       face;
+  FT_Size       size;
+  FT_GlyphSlot  slot;
+
+  unsigned int  num_glyphs;
+  int           ptsize;
+
+  int  Fail;
+  int  Num;
+
+
+
+  static void  Usage( char*  name )
+  {
+    printf( "ftlint: simple font tester -- part of the FreeType project\n" );
+    printf( "----------------------------------------------------------\n" );
+    printf( "\n" );
+    printf( "Usage: %s ppem fontname[.ttf|.ttc] [fontname2..]\n", name );
+    printf( "\n" );
+
+    exit( 1 );
+  }
+
+
+  static void  Panic( const char*  message )
+  {
+    fprintf( stderr, "%s\n  error code = 0x%04x\n", message, error );
+    exit(1);
+  }
+
+
+  int  main( int  argc, char**  argv ) 
+  {
+    int           i, file_index;
+    unsigned int  id;
+    char          filename[128 + 4];
+    char          alt_filename[128 + 4];
+    char*         execname;
+    char*         fname;
+
+
+    execname = argv[0];
+
+    if ( argc < 3 )
+      Usage( execname );
+
+    if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
+      Usage( execname );
+
+    error = FT_Init_FreeType( &library );
+    if (error) Panic( "Could not create library object" );
+
+    /* Now check all files */
+    for ( file_index = 2; file_index < argc; file_index++ )
+    {
+      fname = argv[file_index];
+      i     = strlen( fname );
+      while ( i > 0 && fname[i] != '\\' && fname[i] != '/' )
+      {
+        if ( fname[i] == '.' )
+          i = 0;
+        i--;
+      }
+
+      filename[128] = '\0';
+      alt_filename[128] = '\0';
+
+      strncpy( filename, fname, 128 );
+      strncpy( alt_filename, fname, 128 );
+
+      if ( i >= 0 )
+      {
+        strncpy( filename + strlen( filename ), ".ttf", 4 );
+        strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
+      }
+
+      i     = strlen( filename );
+      fname = filename;
+
+      while ( i >= 0 )
+        if ( filename[i] == '/' || filename[i] == '\\' )
+        {
+          fname = filename + i + 1;
+          i = -1;
+        }
+        else 
+          i--;
+
+      printf( "%s: ", fname );
+
+      /* Load face */
+      error = FT_New_Face( library, filename, 0, &face );
+      if (error)
+      {
+        if (error == FT_Err_Invalid_File_Format)
+          printf( "unknow format\n" );
+        else
+          printf( "could not find/open file\n" );
+        continue;
+      }
+      if (error) Panic( "Could not open file" );
+
+      num_glyphs = face->num_glyphs;
+
+      error = FT_Set_Char_Size( face, ptsize << 6, ptsize << 6, 72, 72 );
+      if (error) Panic( "Could not set character size" );
+
+      Fail = 0;
+      {
+        for ( id = 0; id < num_glyphs; id++ )
+        {
+          error = FT_Load_Glyph( face, id, FT_LOAD_DEFAULT );
+          if (error)
+          {
+            if ( Fail < 10 )
+              printf( "glyph %4u: 0x%04x\n" , id, error );
+            Fail++;
+          }
+        }
+      }
+
+      if ( Fail == 0 )
+        printf( "OK.\n" );
+      else
+        if ( Fail == 1 )
+          printf( "1 fail.\n" );
+        else
+          printf( "%d fails.\n", Fail );
+
+      FT_Done_Face( face );
+    }
+
+    FT_Done_FreeType(library);
+    exit( 0 );      /* for safety reasons */
+
+    return 0;       /* never reached */
+  }
+
+
+/* End */
diff --git a/demos/src/ftsbit.c b/demos/src/ftsbit.c
new file mode 100644
index 0000000..14f3553
--- /dev/null
+++ b/demos/src/ftsbit.c
@@ -0,0 +1,313 @@
+/****************************************************************************/
+/*                                                                          */
+/*  The FreeType project -- a free and portable quality TrueType renderer.  */
+/*                                                                          */
+/*  Copyright 1996-1998 by                                                  */
+/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
+/*                                                                          */
+/*  ftsbit: a _very_ simple embedded bitmap dumper for FreeType 1.x.        */
+/*                                                                          */
+/*  NOTE:  This is just a test program that is used to show off and         */
+/*         debug the current engine.                                        */
+/*                                                                          */
+/****************************************************************************/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "freetype.h"
+
+
+#ifdef HAVE_LIBINTL_H
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include <libintl.h>
+#include "ftxerr18.h"
+
+#else /* !HAVE_LIBINTL */
+
+#define gettext( x )  ( x )
+
+  /* We ignore error message strings with this function */
+
+  static char*  TT_ErrToString18( FT_Error  error )
+  {
+    static char  temp[32];
+
+    sprintf( temp, "0x%04lx", error );
+    return temp;
+  }
+
+#endif /* !HAVE_LIBINTL */
+
+
+  FT_Error      error;
+  FT_Library    engine;
+  FT_Resource   resource;
+
+  FT_Face       face;
+  FT_Size       instance;
+  FT_GlyphSlot  glyph;
+
+  unsigned int  num_glyphs;
+  int           ptsize;
+
+  int  Fail;
+  int  Num;
+
+
+
+  static void  Usage( char*  name )
+  {
+    printf( gettext( "ftsbit: simple TrueType 'sbit' dumper -- part of the FreeType project\n" ) );
+    printf(          "---------------------------------------------------------------------\n" );
+    printf(          "\n" );
+    printf( gettext( "Usage: %s ppem fontname (index)* (index1-index2)*\n\n" ), name );
+    printf( gettext( "   or  %s -a ppem fontname   (dumps all glyphs)\n" ), name );
+    printf(          "\n" );
+
+    exit( EXIT_FAILURE );
+  }
+
+
+
+  static
+  void  dump_bitmap( FT_GlyphSlot  glyph, int glyph_index )
+  {
+    /* Dump the resulting bitmap */
+    {
+      int             y;
+      unsigned char*  line = (unsigned char*)glyph->bitmap.buffer;
+
+      printf( "glyph index %d = %dx%d pixels, ",
+              glyph_index, glyph->bitmap.rows, glyph->bitmap.width );
+
+      printf( "advance = %d, minBearing = [%d,%d]\n",
+              glyph->metrics.horiAdvance >> 6,
+              glyph->metrics.horiBearingX >> 6,
+              glyph->metrics.horiBearingY >> 6 );
+
+      for ( y = 0; y < glyph->bitmap.rows; y++, line += glyph->bitmap.cols )
+      {
+        unsigned char*  ptr = line;
+        int             x;
+        unsigned char   mask = 0x80;
+
+        for ( x = 0; x < glyph->bitmap.width; x++ )
+        {
+          printf( "%c", (ptr[0] & mask) ? '*' : '.' );
+          mask >>= 1;
+          if (mask == 0)
+          {
+            mask = 0x80;
+            ptr++;
+          }
+        }
+
+        printf( "\n" );
+      }
+    }
+  }
+
+
+  
+  static
+  void  dump_range( FT_GlyphSlot  glyph,
+                    int           first_glyph,
+                    int           last_glyph )
+  {
+    int  i;
+    
+    for ( i = first_glyph; i <= last_glyph; i++ )
+    {
+      error = FT_Load_Glyph( glyph,
+                             instance,
+                             (unsigned short)i,
+                             FT_LOAD_NO_OUTLINE,
+                             0 );
+      if (error)
+      {
+        printf( "  no bitmap for glyph %d\n", i );
+        printf( gettext( "FreeType error message: %s\n" ),
+                TT_ErrToString18( error ) );
+        continue;
+      }
+      
+      dump_bitmap(glyph,i);
+    }
+  }
+
+
+
+
+  int  main( int  argc, char**  argv )
+  {
+    int    i;
+    char   filename[128 + 4];
+    char   alt_filename[128 + 4];
+    char*  execname;
+    char*  fname;
+    int    dump_all = 0;
+
+
+#ifdef HAVE_LIBINTL_H
+    setlocale( LC_ALL, "" );
+    bindtextdomain( "freetype", LOCALEDIR );
+    textdomain( "freetype" );
+#endif
+
+    execname = argv[0];
+
+    if ( argc < 3 )
+      Usage( execname );
+
+    if ( argv[1][0] == '-' &&
+         argv[1][1] == 'a' )
+    {
+      argv++;
+      argc--;
+      dump_all = 1;
+    }
+
+    if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
+      Usage( execname );
+
+    /* Initialize engine */
+    if ( (error = FT_Init_FreeType( &engine )) )
+    {
+      fprintf( stderr, gettext( "Error while initializing engine\n" ) );
+      goto Failure;
+    }
+
+    /* Now check all files */
+    fname = argv[2];
+    i     = strlen( fname );
+    while ( i > 0 && fname[i] != '\\' && fname[i] != '/' )
+    {
+      if ( fname[i] == '.' )
+        i = 0;
+      i--;
+    }
+
+    filename[128] = '\0';
+    alt_filename[128] = '\0';
+
+    strncpy( filename, fname, 128 );
+    strncpy( alt_filename, fname, 128 );
+
+    if ( i >= 0 )
+    {
+      strncpy( filename + strlen( filename ), ".ttf", 4 );
+      strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
+    }
+
+    /* Load face */
+    error = FT_New_Resource( engine, filename, &resource );
+    if (error)
+    {
+      strcpy( filename, alt_filename );
+      error = FT_New_Resource( engine, alt_filename, &resource );
+    }
+
+    i     = strlen( filename );
+    fname = filename;
+
+    while ( i >= 0 )
+      if ( filename[i] == '/' || filename[i] == '\\' )
+      {
+        fname = filename + i + 1;
+        i = -1;
+      }
+      else
+        i--;
+
+    if ( error )
+    {
+      printf( gettext( "Could not find or open file.\n" ) );
+      goto Failure;
+    }
+
+    error = FT_New_Face( resource, 0, &face );
+    if (error)
+    {
+      printf( gettext( "Could not create face object.\n  " ) );
+      goto Failure;
+    }
+
+    /* get face properties */
+    num_glyphs = face->num_glyphs;
+
+    /* create instance */
+    error = FT_New_Size( face, &instance );
+    if ( error )
+    {
+      printf( gettext( "Could not create instance.\n" ) );
+      goto Failure;
+    }
+
+    error = FT_Set_Pixel_Sizes( instance, ptsize, ptsize );
+    if (error)
+    {
+      printf( gettext( "Could not set character size.\n" ) );
+      goto Failure;
+    }
+
+    glyph = face->slot;
+
+    if (dump_all)
+      dump_range( glyph, 0, num_glyphs-1 );
+    else
+    {
+      for ( i = 3; i < argc; i++ )
+      {
+        /* check for range in argument string */
+        int    range_check = 0;
+        char*  base = argv[i];
+        char*  cur  = base;
+        int    first, last;
+        
+        while (*cur)
+        {
+          if (*cur == '-')
+          {
+            range_check = 1;
+            break;
+          }
+          cur++;
+        }
+
+        if (range_check)
+        {
+          if ( sscanf( argv[i], "%d-%d", &first, &last ) != 2 )
+            Usage( execname );
+            
+          dump_range( glyph, first, last );
+        }
+        else
+        {
+          if ( sscanf( argv[i], "%d", &first ) != 1 )
+            Usage( execname );
+            
+          dump_range( glyph, first, first );
+        }
+      }
+    }
+
+    FT_Done_FreeType( engine );
+    exit( EXIT_SUCCESS );      /* for safety reasons */
+
+    return 0;       /* never reached */
+
+  Failure:
+    printf( gettext( "FreeType error message: %s\n" ),
+            TT_ErrToString18( error ) );
+    exit( EXIT_FAILURE );
+  }
+
+
+/* End */
diff --git a/demos/src/fttimer.c b/demos/src/fttimer.c
new file mode 100644
index 0000000..84fa222
--- /dev/null
+++ b/demos/src/fttimer.c
@@ -0,0 +1,460 @@
+/****************************************************************************/
+/*                                                                          */
+/*  The FreeType project - a Free and Portable Quality TrueType Renderer.   */
+/*                                                                          */
+/*  Copyright 1996-1998 by                                                  */
+/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
+/*                                                                          */
+/*  fttimer: A simple performance benchmark.  Now with graylevel rendering  */
+/*           with the '-g' option.                                          */
+/*                                                                          */
+/*           Be aware that the timer program benchmarks different things    */
+/*           in each release of the FreeType library.  Thus, performance    */
+/*           should only be compared between similar release numbers.       */
+/*                                                                          */
+/*                                                                          */
+/*  NOTE: This is just a test program that is used to show off and          */
+/*        debug the current engine.  In no way does it shows the final      */
+/*        high-level interface that client applications will use.           */
+/*                                                                          */
+/****************************************************************************/
+
+#include "freetype.h"
+#include "ftoutln.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>    /* for clock() */
+
+#include "graph.h"
+
+/* SunOS 4.1.* does not define CLOCKS_PER_SEC, so include <sys/param.h> */
+/* to get the HZ macro which is the equivalent.                         */
+#if defined(__sun__) && !defined(SVR4) && !defined(__SVR4)
+#include <sys/param.h>
+#define CLOCKS_PER_SEC HZ
+#endif
+
+#define CHARSIZE    400   /* character point size */
+#define MAX_GLYPHS  512   /* Maximum number of glyphs rendered at one time */
+
+  char  Header[128];
+
+  FT_Error      error;
+  FT_Library    library;
+
+  FT_Face       face;
+  FT_Size       size;
+  FT_GlyphSlot  glyph;
+
+  FT_Outline    outline;
+
+  FT_Pos*   cur_x;
+  FT_Pos*   cur_y;
+
+  unsigned short*  cur_endContour;
+  unsigned char*   cur_touch;
+
+  FT_Outline  outlines[MAX_GLYPHS];
+
+  int             num_glyphs;
+  int             tab_glyphs;
+  int             cur_glyph;
+  int             cur_point;
+  unsigned short  cur_contour;
+  
+  int             pixel_size   = CHARSIZE*96/72;
+  int             repeat_count = 1;
+
+  FT_Bitmap      Bit;
+  grBitmap       bit;
+
+  int  Fail;
+  int  Num;
+
+  int  vio_Height, vio_Width;
+
+  short  visual;      /* display glyphs while rendering */
+  short  gray_render; /* smooth fonts with gray levels  */
+
+
+
+  static void Clear_Buffer();
+
+  static void Panic( const char* message )
+  {
+    fprintf( stderr, "%s\n  error code = 0x%04x\n", message, error );
+  }
+
+/*******************************************************************/
+/*                                                                 */
+/*  Get_Time:                                                      */
+/*                                                                 */
+/*    Returns the current time in milliseconds.                    */
+/*                                                                 */
+/*******************************************************************/
+
+  long  Get_Time( void )
+  {
+    return clock() * 10000 / CLOCKS_PER_SEC;
+  }
+
+
+/*******************************************************************/
+/*                                                                 */
+/*  Init_Engine:                                                   */
+/*                                                                 */
+/*    Allocates bitmap, render pool and other structs...           */
+/*                                                                 */
+/*******************************************************************/
+
+  void  Init_Engine( void )
+  {
+    Bit.rows       = bit.rows;
+    Bit.width      = bit.width;
+    Bit.pitch      = bit.pitch;
+    Bit.buffer     = bit.buffer;
+    Bit.pixel_mode = gray_render ? ft_pixel_mode_grays : ft_pixel_mode_mono;
+    Bit.num_grays  = bit.grays;
+    Clear_Buffer();
+  }
+
+
+/*******************************************************************/
+/*                                                                 */
+/*  Clear_Buffer:                                                  */
+/*                                                                 */
+/*    Clears current bitmap.                                       */
+/*                                                                 */
+/*******************************************************************/
+
+  static void  Clear_Buffer( void )
+  {
+    long size = Bit.rows * Bit.pitch;
+
+    memset( Bit.buffer, 0, size );
+  }
+
+
+/*******************************************************************/
+/*                                                                 */
+/*  LoadTrueTypeChar:                                              */
+/*                                                                 */
+/*    Loads a glyph into memory.                                   */
+/*                                                                 */
+/*******************************************************************/
+
+  FT_Error  LoadChar( int  idx )
+  {
+    error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT );
+    if ( error )
+      return error;
+
+    glyph->outline.second_pass    = 0;
+    glyph->outline.high_precision = 0;
+    glyph->outline.dropout_mode   = 0;
+
+    /* debugging */
+#if 0
+    if ( idx == 0 && !visual )
+    {
+      printf( "points = %d\n", outline.points );
+      for ( j = 0; j < outline.points; j++ )
+        printf( "%02x  (%01hx,%01hx)\n",
+                 j, outline.xCoord[j], outline.yCoord[j] );
+      printf( "\n" );
+    }
+#endif
+
+    /* create a new outline */
+    FT_New_Outline( library,
+                    glyph->outline.n_points, 
+                    glyph->outline.n_contours, 
+                    &outlines[cur_glyph] );
+
+    /* copy the glyph outline into it */
+    glyph->outline.high_precision = 0;
+    glyph->outline.second_pass    = 0;
+    FT_Copy_Outline( &glyph->outline, &outlines[cur_glyph] );
+
+    /* center outline around 0 */
+    {
+      FT_BBox  bbox;
+      
+      FT_Get_Outline_CBox( &glyph->outline, &bbox );
+      FT_Translate_Outline( &outlines[cur_glyph],
+                            - ( bbox.xMax - bbox.xMin )/2,
+                            - ( bbox.yMax - bbox.yMin )/2 );
+    }
+    /* translate it */
+    FT_Translate_Outline( &outlines[cur_glyph],
+                          Bit.width * 32 ,
+                          Bit.rows  * 32 );
+    cur_glyph++;
+
+    return FT_Err_Ok;
+  }
+
+
+/*******************************************************************/
+/*                                                                 */
+/*  ConvertRaster:                                                 */
+/*                                                                 */
+/*    Performs scan conversion.                                    */
+/*                                                                 */
+/*******************************************************************/
+
+  FT_Error  ConvertRaster( int  index )
+  {
+    outlines[index].second_pass    = 0;
+    outlines[index].high_precision = 0;
+
+    return FT_Get_Outline_Bitmap( library, &outlines[index], &Bit );
+  }
+
+
+  static void Usage()
+  {
+      fprintf( stderr, "fttimer: simple performance timer -- part of the FreeType project\n" );
+      fprintf( stderr, "-----------------------------------------------------------------\n\n" );
+      fprintf( stderr, "Usage: fttimer [options] fontname[.ttf|.ttc]\n\n" );
+      fprintf( stderr, "options:\n");
+      fprintf( stderr, "   -r : repeat count to be used (default is 1)\n" );
+      fprintf( stderr, "   -s : character pixel size (default is 600)\n" );
+      fprintf( stderr, "   -v : display results..\n" );
+      fprintf( stderr, "   -g : render anti-aliased glyphs\n" );
+      exit(1);
+  }
+
+
+  int  main( int  argc, char**  argv )
+  {
+    int    i, total, base, rendered_glyphs;
+    char   filename[128 + 4];
+    char   alt_filename[128 + 4];
+    char*  execname;
+    grSurface*  surface = 0;
+
+    long   t, t0, tz0;
+
+
+    execname    = argv[0];
+
+    gray_render = 0;
+    visual      = 0;
+
+    while ( argc > 1 && argv[1][0] == '-' )
+    {
+      switch ( argv[1][1] )
+      {
+      case 'g':
+        gray_render = 1;
+        break;
+
+      case 'v':
+        visual = 1;
+        break;
+
+      case 's':
+        argc--;
+        argv++;
+        if ( argc < 2 ||
+            sscanf( argv[1], "%d", &pixel_size ) != 1 )
+          Usage();
+        break;
+
+      case 'r':
+        argc--;
+        argv++;
+        if ( argc < 2 ||
+             sscanf( argv[1], "%d", &repeat_count ) != 1 )
+          Usage();
+        if (repeat_count < 1)
+          repeat_count = 1;
+        break;
+
+      default:
+        fprintf( stderr, "Unknown argument '%s'!\n", argv[1] );
+		Usage();
+      }
+      argc--;
+      argv++;
+    }
+
+    if ( argc != 2 )
+	  Usage();
+
+    i = strlen( argv[1] );
+    while ( i > 0 && argv[1][i] != '\\' )
+    {
+      if ( argv[1][i] == '.' )
+        i = 0;
+      i--;
+    }
+
+    filename[128] = '\0';
+    alt_filename[128] = '\0';
+
+    strncpy( filename, argv[1], 128 );
+    strncpy( alt_filename, argv[1], 128 );
+
+    if ( i >= 0 )
+    {
+      strncpy( filename + strlen( filename ), ".ttf", 4 );
+      strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
+    }
+
+    /* Initialize engine */
+
+    if ( (error = FT_Init_FreeType( &library )) )
+      Panic( "Error while initializing engine" );
+
+    /* Load face */
+
+    error = FT_New_Face( library, filename, 0, &face );
+    if ( error == FT_Err_Cannot_Open_Stream )
+      Panic( "Could not find/open font resource" );
+    else if ( error )
+      Panic( "Error while opening font resource" );
+
+    /* get face properties and allocate preload arrays */
+
+    num_glyphs = face->num_glyphs;
+    glyph      = face->glyph;
+        
+    tab_glyphs = MAX_GLYPHS;
+    if ( tab_glyphs > num_glyphs )
+      tab_glyphs = num_glyphs;
+
+    /* create size */
+
+    error = FT_Set_Pixel_Sizes( face, pixel_size, pixel_size );
+    if ( error ) Panic( "Could not reset instance" );
+
+    bit.mode  = gray_render ? gr_pixel_mode_gray : gr_pixel_mode_mono;
+    bit.width = 640;
+    bit.rows  = 480;
+    bit.grays = 128;
+ 
+    if ( visual )
+    {
+      if ( !grInitDevices() )
+        Panic( "Could not initialize graphics.\n" );
+        
+      surface = grNewSurface( 0, &bit );
+      if (!surface)
+        Panic( "Could not open graphics window/screen.\n" );
+    }
+    else
+    {
+      if ( grNewBitmap( bit.mode,
+                        bit.grays,
+                        bit.width,
+                        bit.rows,
+                       &bit ) )
+        Panic( "Could not create rendering buffer.\n" );
+    }
+
+    Init_Engine();
+
+    Num  = 0;
+    Fail = 0;
+
+    total = num_glyphs;
+    base  = 0;
+
+    rendered_glyphs = 0;
+
+    t0 = 0;  /* Initial time */
+
+    tz0 = Get_Time();
+
+    while ( total > 0 )
+    {
+      int  repeat;
+      
+      /* First, preload 'tab_glyphs' in memory */
+      cur_glyph   = 0;
+      cur_point   = 0;
+      cur_contour = 0;
+  
+      printf( "loading %d glyphs", tab_glyphs );
+
+      for ( Num = 0; Num < tab_glyphs; Num++ )
+      {
+        error = LoadChar( base + Num );
+        if ( error )
+          Fail++;
+
+        total--;
+      }
+
+      base += tab_glyphs;
+
+      if ( tab_glyphs > total ) 
+        tab_glyphs = total;
+
+      printf( ", rendering... " );
+
+      /* Now, render the loaded glyphs */
+
+      t = Get_Time();
+
+      for ( repeat = 0; repeat < repeat_count; repeat++ )
+      {
+        for ( Num = 0; Num < cur_glyph; Num++ )
+        {
+          if ( (error = ConvertRaster( Num )) )
+            Fail++;
+            
+          else
+  	  {
+            rendered_glyphs ++;
+
+            if ( Num == 0 && visual )
+            {
+              sprintf( Header, "Glyph: %5d", Num );
+              grSetTitle( surface, Header );
+              grRefreshSurface( surface );
+              Clear_Buffer();
+            }
+	  }
+        }
+      }
+
+      t = Get_Time() - t;
+      if ( t < 0 )
+        t += 1000 * 60 * 60;
+
+      printf( " = %f s\n", (double)t / 10000 );
+      t0 += t;
+
+      /* Now free all loaded outlines */
+      for ( Num = 0; Num < cur_glyph; Num++ )
+        FT_Done_Outline( library, &outlines[Num] );
+    }
+
+    tz0 = Get_Time() - tz0;
+
+    FT_Done_Face( face );
+
+    printf( "\n" );
+    printf( "rendered glyphs  = %d\n", rendered_glyphs );
+    printf( "render time      = %f s\n", (double)t0 / 10000 );
+    printf( "fails            = %d\n", Fail );
+    printf( "average glyphs/s = %f\n", 
+             (double)rendered_glyphs / t0 * 10000 );
+
+    printf( "total timing     = %f s\n", (double)tz0 / 10000 );
+    printf( "Fails = %d\n", Fail );
+
+    FT_Done_FreeType( library );
+
+    exit( 0 );      /* for safety reasons */
+
+    return 0;       /* never reached */
+  }
+
+
+/* End */
diff --git a/demos/src/fttry.c b/demos/src/fttry.c
new file mode 100644
index 0000000..1dd878e
--- /dev/null
+++ b/demos/src/fttry.c
@@ -0,0 +1,155 @@
+/****************************************************************************/
+/*                                                                          */
+/*  The FreeType project -- a free and portable quality TrueType renderer.  */
+/*                                                                          */
+/*  Copyright 1996-1998 by                                                  */
+/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
+/*                                                                          */
+/*  ftlint: a simple TrueType instruction tester.                           */
+/*                                                                          */
+/*  NOTE:  This is just a test program that is used to show off and         */
+/*         debug the current engine.                                        */
+/*                                                                          */
+/****************************************************************************/
+
+#include "freetype.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define gettext( x )  ( x )
+
+  FT_Error      error;
+
+  FT_Library    library;
+  FT_Face       face;
+
+  unsigned int  num_glyphs;
+  int           ptsize;
+
+  int  Fail;
+  int  Num;
+
+
+
+  static void  Usage( char*  name )
+  {
+    printf( "fttry: simple TrueType instruction tester -- part of the FreeType project\n" );
+    printf( "--------------------------------------------------------------------------\n" );
+    printf( "\n" );
+    printf( "Usage: %s ppem glyph fontname [fontname2..]\n\n", name );
+    printf( "    or %s -u glyph fontname [fontname2..]\n", name );
+    printf( "          to load an unscaled glyph\n\n" );
+
+    exit( 1 );
+  }
+
+
+  static void  Panic( const char*  message )
+  {
+    fprintf( stderr, "%s\n  error code = 0x%04x\n", message, error );
+    exit(1);
+  }
+
+  int  main( int  argc, char**  argv ) 
+  {
+    int           i, file_index, glyph_index;
+    char          filename[128 + 4];
+    char          alt_filename[128 + 4];
+    char*         execname;
+    char*         fname;
+    int           load_unscaled = 0;
+
+    execname = argv[0];
+
+    if ( argc < 3 )
+      Usage( execname );
+
+    if ( argv[1][0] == '-' &&
+         argv[1][1] == 'u' )
+    {
+      load_unscaled = 1;
+    }
+    else
+    {
+      if ( sscanf( argv[1], "%d", &ptsize ) != 1 )
+        Usage( execname );
+    }
+    argc--;
+    argv++;
+
+    if ( sscanf( argv[1], "%d", &glyph_index ) != 1 )
+      Usage( execname );
+
+    error = FT_Init_FreeType( &library );
+    if (error) Panic( "Could not create library object" );
+
+    /* Now check all files */
+    for ( file_index = 2; file_index < argc; file_index++ )
+    {
+      fname = argv[file_index];
+      i     = strlen( fname );
+      while ( i > 0 && fname[i] != '\\' && fname[i] != '/' )
+      {
+        if ( fname[i] == '.' )
+          i = 0;
+        i--;
+      }
+
+      filename[128] = '\0';
+      alt_filename[128] = '\0';
+
+      strncpy( filename, fname, 128 );
+      strncpy( alt_filename, fname, 128 );
+
+      if ( i >= 0 )
+      {
+        strncpy( filename + strlen( filename ), ".ttf", 4 );
+        strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
+      }
+
+      i     = strlen( filename );
+      fname = filename;
+
+      while ( i >= 0 )
+        if ( filename[i] == '/' || filename[i] == '\\' )
+        {
+          fname = filename + i + 1;
+          i = -1;
+        }
+        else 
+          i--;
+
+      printf( "%s: ", fname );
+
+      /* Load face */
+      error = FT_New_Face( library, filename, 0, &face );
+      if (error) Panic( "Could not create face object" );
+
+      num_glyphs = face->num_glyphs;
+
+      error = FT_Set_Char_Size( face, ptsize << 6, 0, 0, 0 );
+      if (error) Panic( "Could not set character size" );
+      
+      error = FT_Load_Glyph( face,
+                             glyph_index,
+                             load_unscaled ? FT_LOAD_NO_SCALE
+                                           : FT_LOAD_DEFAULT );
+      if ( error == 0 )
+        printf( "OK.\n" );
+      else
+        printf( "Fail with error 0x%04x\n", error );
+
+      FT_Done_Face( face );
+    }
+
+    FT_Done_FreeType(library);
+    exit( 0 );      /* for safety reasons */
+
+    return 0;       /* never reached */
+  }
+
+
+/* End */
diff --git a/demos/src/ftview.c b/demos/src/ftview.c
new file mode 100644
index 0000000..74ebde0
--- /dev/null
+++ b/demos/src/ftview.c
@@ -0,0 +1,615 @@
+/****************************************************************************/
+/*                                                                          */
+/*  The FreeType project -- a free and portable quality TrueType renderer.  */
+/*                                                                          */
+/*  Copyright 1996-1999 by                                                  */
+/*  D. Turner, R.Wilhelm, and W. Lemberg                                    */
+/*                                                                          */
+/*                                                                          */
+/*  FTView - a simple font viewer.                                          */
+/*                                                                          */
+/*  This is a new version using the MiGS graphics subsystem for             */
+/*  blitting and display.                                                   */
+/*                                                                          */
+/*  Press F1 when running this program to have a list of key-bindings       */
+/*                                                                          */
+/****************************************************************************/
+
+#include "freetype.h"
+#include "ftoutln.h"
+#include "common.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "graph.h"
+#include "grfont.h"
+
+#define  DIM_X   500
+#define  DIM_Y   400
+
+#define  CENTER_X   (bit.width/2)
+#define  CENTER_Y   (bit.rows/2)
+
+#define  MAXPTSIZE  500                 /* dtp */
+
+
+  char  Header[128];
+  char* new_header = 0;
+
+  FT_Library    library;      /* the FreeType library            */
+  FT_Face       face;         /* the font face                   */
+  FT_Size       size;         /* the font size                   */
+  FT_GlyphSlot  glyph;        /* the glyph slot                  */
+  
+  FT_Error      error;        /* error returned by FreeType ?    */
+
+  grSurface*     surface;     /* current display surface         */
+  grBitmap       bit;         /* current display bitmap          */
+
+  int  num_glyphs;            /* number of glyphs */
+  int  ptsize;                /* current point size */
+  
+  int  hinted      = 1;       /* is glyph hinting active ?    */
+  int  gray_render = 1;       /* is anti-aliasing active ?    */
+  int  use_sbits   = 1;       /* do we use embedded bitmaps ? */
+  int  low_prec    = 1;       /* force low precision          */
+  int  Num;                   /* current first glyph index    */
+
+  int    res = 96;
+
+  int            Fail;
+  unsigned char  autorun;
+
+  int  graph_init = 0;
+
+
+  /* PanicZ */
+  static void PanicZ( const char* message )
+  {
+    fprintf( stderr, "%s\n  error = 0x%04x\n", message, error );
+    exit(1);
+  }
+
+
+  /* Clears the Bit bitmap/pixmap */
+  static void  Clear_Display( void )
+  {
+    long  size = (long)bit.pitch * bit.rows;
+    memset( bit.buffer, 0, size );
+  }
+
+
+  /* Initialize the display bitmap named Bit */
+  static int  Init_Display()
+  {
+    grInitDevices();
+
+    bit.mode   = gr_pixel_mode_gray;
+    bit.width  = DIM_X;
+    bit.rows   = DIM_Y;
+    bit.grays  = 128;
+
+    surface = grNewSurface( 0, &bit );
+    if (!surface)
+      PanicZ( "could not allocate display surface\n" );
+
+    graph_init = 1;
+    return 0;
+  }
+
+
+#define MAX_BUFFER  65000
+
+#define FLOOR(x)  ((x) & -64)
+#define CEIL(x)   (((x)+63) & -64)
+#define TRUNC(x)  ((x) >> 6)
+
+  static
+  char   bit_buffer[ MAX_BUFFER ];
+  
+  /* Render a single glyph */
+  static FT_Error  Render_Glyph( int  x_offset,
+                                 int  y_offset )
+  {
+    /* first, render the glyph into an intermediate buffer */
+    FT_Bitmap  bit2;
+    grBitmap   bit3;
+    int        width, height, pitch, size;
+    int        left, right, top, bottom;
+
+    left  = FLOOR( glyph->metrics.horiBearingX );
+    right = CEIL( glyph->metrics.horiBearingX + glyph->metrics.width );
+    width = TRUNC(right - left);
+    
+    top    = CEIL( glyph->metrics.horiBearingY );
+    bottom = FLOOR( glyph->metrics.horiBearingY - glyph->metrics.height );
+    height = TRUNC( top - bottom );
+
+    if ( glyph->format == ft_glyph_format_outline )
+    {    
+      pitch  = ( gray_render ? (width+3) & -4 : (width+7) >> 3 );
+      size   = pitch*height; 
+
+      if (size > MAX_BUFFER)
+        return FT_Err_Out_Of_Memory;
+    
+      bit2.width      = width;
+      bit2.rows       = height;
+      bit2.pitch      = pitch;
+      bit2.pixel_mode = gray_render ? ft_pixel_mode_grays : ft_pixel_mode_mono;
+      bit2.buffer     = bit_buffer;
+
+      bit3.rows   = bit2.rows;
+      bit3.width  = bit2.width;
+      bit3.pitch  = bit2.pitch;
+      bit3.mode   = gray_render ? bit.mode : gr_pixel_mode_mono;
+      bit3.buffer = bit_buffer;
+      bit3.grays  = 128;
+
+      FT_Translate_Outline( &glyph->outline, -left, -bottom );
+      memset( bit_buffer, 0, size );
+
+      if (low_prec)
+        glyph->outline.high_precision = 0;
+        
+      FT_Get_Outline_Bitmap( library, &glyph->outline, &bit2 );
+    }
+    else
+    {
+      bit3.rows   = glyph->bitmap.rows;
+      bit3.width  = glyph->bitmap.width;
+      bit3.pitch  = glyph->bitmap.pitch;
+      bit3.mode   = gr_pixel_mode_mono;
+      bit3.buffer = glyph->bitmap.buffer;
+      bit3.grays  = 0;
+    }
+      
+    /* Then, blit the image to the target surface */
+    grBlitGlyphToBitmap( &bit,
+                         &bit3,
+                         x_offset + TRUNC(left),
+                         y_offset - TRUNC(top),
+                         (grColor)127L ); 
+    return 0;
+  }
+
+
+  static FT_Error  Reset_Scale( int  pointSize )
+  {
+    FT_Error  error;
+
+    error = FT_Set_Char_Size( face, pointSize << 6,
+                                    pointSize << 6,
+                                    res,
+                                    res );
+    if ( error )
+    {
+    }
+    return FT_Err_Ok;
+  }
+  
+
+  static FT_Error  LoadChar( int  idx, int  hint )
+  {
+    int  flags;
+
+    flags = FT_LOAD_DEFAULT;
+    
+    if ( !hint )
+      flags |= FT_LOAD_NO_HINTING;
+
+    if ( !use_sbits )
+      flags |= FT_LOAD_NO_BITMAP;
+
+    return FT_Load_Glyph( face, idx, flags );
+  }
+
+
+
+  static FT_Error  Render_All( int  first_glyph, int  ptsize )
+  {
+    FT_F26Dot6  start_x, start_y, step_x, step_y, x, y;
+    int         i;
+
+    FT_Error    error;
+
+
+    start_x = 4;
+    start_y = 16 + ptsize ;
+
+    step_x = size->metrics.x_ppem + 4;
+    step_y = size->metrics.y_ppem + 10;
+
+    x = start_x;
+    y = start_y;
+
+    i = first_glyph;
+
+    while ( i < num_glyphs )
+    {
+      if ( !(error = LoadChar( i, hinted )) )
+      {
+        Render_Glyph( x, y );
+
+        x += ( glyph->metrics.horiAdvance >> 6 ) + 1;
+
+        if ( x + size->metrics.x_ppem > bit.width )
+        {
+          x  = start_x;
+          y += step_y;
+
+          if ( y >= bit.rows )
+            return FT_Err_Ok;
+        }
+      }
+      else
+        Fail++;
+
+      i++;
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+  static void Help( )
+  {
+    grEvent  dummy_event;
+
+    Clear_Display();
+    grGotoxy( 0, 0 );
+    grSetMargin( 2, 1 );
+    grGotobitmap( &bit );
+    
+    grWriteln("FreeType Glyph Viewer - part of the FreeType test suite" );
+    grLn();
+    grWriteln("This program is used to display all glyphs from one or" );
+    grWriteln("several font files, with the FreeType library.");
+    grLn();
+    grWriteln("Use the following keys :");
+    grLn();
+    grWriteln("  F1 or ?   : display this help screen" );
+    grWriteln("  a         : toggle anti-aliasing" );
+    grWriteln("  h         : toggle outline hinting" );
+    grWriteln("  b         : toggle embedded bitmaps" );
+    grWriteln("  l         : toggle low precision rendering" );
+    grLn();
+    grWriteln("  Up        : increase pointsize by 1 unit" );
+    grWriteln("  Down      : decrease pointsize by 1 unit" );
+    grWriteln("  Page Up   : increase pointsize by 10 units" );
+    grWriteln("  Page Down : decrease pointsize by 10 units" );
+    grLn();
+    grWriteln("  Right     : increment first glyph index" );
+    grWriteln("  Left      : decrement first glyph index" );
+    grLn();
+    grWriteln("  F5        : decrement first glyph index by 10" );
+    grWriteln("  F6        : increment first glyph index by 10" );
+    grWriteln("  F7        : decrement first glyph index by 100");
+    grWriteln("  F8        : increment first glyph index by 100");
+    grWriteln("  F9        : decrement first glyph index by 1000");
+    grWriteln("  F10       : increment first glyph index by 1000");
+    grLn();
+    grWriteln("press any key to exit this help screen");
+        
+    grRefreshSurface( surface );
+    grListenSurface( surface, gr_event_key, &dummy_event );
+  }
+
+
+
+  static int  Process_Event( grEvent*  event )
+  {
+    int  i;
+    
+    switch ( event->key )
+    {
+    case grKeyEsc:            /* ESC or q */
+    case grKEY('q'):
+      return 0;
+
+    case grKEY('a'):
+      gray_render = !gray_render;
+      new_header = ( gray_render
+                   ? "anti-aliasing is now on"
+                   : "anti-aliasing is now off" );
+      return 1;
+
+    case grKEY('b'):
+      use_sbits  = !use_sbits;
+      new_header = ( use_sbits
+                   ? "embedded bitmaps are now used when available"
+                   : "embedded bitmaps are now ignored" );
+      return 1;
+      
+    case grKEY('n'):
+    case grKEY('p'):
+      return (int)event->key;
+
+    case grKEY('l'):
+      low_prec = !low_prec;
+      new_header = ( low_prec
+                   ? "rendering precision is now forced to low"
+                   : "rendering precision is now normal" );
+      break;
+      
+    case grKEY('h'):
+      hinted = !hinted;
+      new_header = ( hinted
+                   ? "glyph hinting is now active"
+                   : "glyph hinting is now ignored" );
+      break;
+
+    case grKeyF1:
+    case grKEY('?'):
+      Help();
+      return 1;
+
+#if 0
+    case grKeyF3:  i =  16; goto Do_Rotate;
+    case grKeyF4:  i = -16; goto Do_Rotate;
+    case grKeyF5:  i =   1; goto Do_Rotate;
+    case grKeyF6:  i =  -1; goto Do_Rotate;
+#endif
+
+    case grKeyPageUp:   i =  10; goto Do_Scale;
+    case grKeyPageDown: i = -10; goto Do_Scale;
+    case grKeyUp:       i =   1; goto Do_Scale;
+    case grKeyDown:     i =  -1; goto Do_Scale;
+
+    case grKeyLeft:  i =  -1; goto Do_Glyph;
+    case grKeyRight: i =   1; goto Do_Glyph;
+    case grKeyF7:    i = -10; goto Do_Glyph;
+    case grKeyF8:    i =  10; goto Do_Glyph;
+    case grKeyF9:    i = -100; goto Do_Glyph;
+    case grKeyF10:   i =  100; goto Do_Glyph;
+    case grKeyF11:   i = -1000; goto Do_Glyph;
+    case grKeyF12:   i =  1000; goto Do_Glyph;
+    default:
+      ;
+    }
+    return 1;
+
+#if 0    
+  Do_Rotate:
+    Rotation = (Rotation + i) & 1023;
+    return 1;
+#endif
+
+  Do_Scale:
+    ptsize += i;
+    if (ptsize < 1)         ptsize = 1;
+    if (ptsize > MAXPTSIZE) ptsize = MAXPTSIZE;
+    return 1;
+    
+  Do_Glyph:
+    Num += i;
+    if (Num < 0)           Num = 0;
+    if (Num >= num_glyphs) Num = num_glyphs-1;
+    return 1;
+  }
+
+
+
+  static void  usage( char*  execname )
+  {
+    fprintf( stderr,  "\n" );
+    fprintf( stderr,  "ftview: simple glyph viewer -- part of the FreeType project\n" );
+    fprintf( stderr,  "-----------------------------------------------------------\n" );
+    fprintf( stderr,  "\n" );
+    fprintf( stderr,  "Usage: %s [options below] ppem fontname[.ttf|.ttc] ...\n",
+             execname );
+    fprintf( stderr,  "\n" );
+    fprintf( stderr,  "  -r R      use resolution R dpi (default: 72 dpi)\n" );
+    fprintf( stderr,  "  -f index  specify first glyph index to display\n" );
+    fprintf( stderr,  "\n" );
+
+    exit( 1 );
+  }
+
+
+  int  main( int  argc, char**  argv ) 
+  {
+    int    i, old_ptsize, orig_ptsize, file;
+    int    first_glyph = 0;
+    int    XisSetup = 0;
+    char   filename[128 + 4];
+    char   alt_filename[128 + 4];
+    char*  execname;
+    int    option;
+    int    file_loaded;
+
+    FT_Error  error;
+    grEvent   event;
+ 
+    execname = ft_basename( argv[0] );
+
+    while ( 1 )
+    {
+      option = getopt( argc, argv, "f:r:" );
+
+      if ( option == -1 )
+        break;
+
+      switch ( option )
+      {
+      case 'f':
+        first_glyph = atoi( optarg );
+        break;
+        
+      case 'r':
+        res = atoi( optarg );
+        if ( res < 1 )
+          usage( execname );
+        break;
+
+      default:
+        usage( execname );
+        break;
+      }
+    }
+
+    argc -= optind;
+    argv += optind;
+
+    if ( argc <= 1 )
+      usage( execname );
+
+    if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 )
+      orig_ptsize = 64;
+
+    file = 1;
+
+    /* Initialize engine */
+    error = FT_Init_FreeType( &library );
+    if (error) PanicZ( "Could not initialise FreeType library" );
+
+/*    FT_Set_Raster_Palette( library, 17, palette_17 ); */
+
+  NewFile:
+    ptsize      = orig_ptsize;
+    hinted      = 1;
+    file_loaded = 0;
+
+    i = strlen( argv[file] );
+    while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' )
+    {
+      if ( argv[file][i] == '.' )
+        i = 0;
+        i--; 
+    }
+
+    filename[128] = '\0';
+    alt_filename[128] = '\0';
+
+    strncpy( filename, argv[file], 128 );
+    strncpy( alt_filename, argv[file], 128 );
+
+    if ( i >= 0 )
+    {
+      strncpy( filename + strlen( filename ), ".ttf", 4 );
+      strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
+    }
+
+    /* Load face */
+
+    error = FT_New_Face( library, filename, 0, &face );
+    if (error) goto Display_Font;
+
+    file_loaded++;
+    
+    error = Reset_Scale( ptsize );
+    if (error) goto Display_Font;
+        
+    num_glyphs = face->num_glyphs;
+    glyph      = face->glyph;
+    size       = face->size;
+
+  Display_Font:
+    /* initialise graphics if needed */
+    if ( !XisSetup )
+    {
+      XisSetup = 1;
+      Init_Display();
+    }
+  
+    grSetTitle( surface, "FreeType Glyph Viewer - press F1 for help" );
+    old_ptsize = ptsize;
+
+    if ( file_loaded >= 1 )
+    {
+      Fail = 0;
+      Num  = first_glyph;
+    
+      if ( Num >= num_glyphs )
+        Num = num_glyphs-1;
+      
+      if ( Num < 0 )
+        Num = 0;
+    }
+
+    for ( ;; )
+    {
+      int  key;
+
+      Clear_Display();
+
+      if ( file_loaded >= 1 )
+      {
+        Render_All( Num, ptsize );
+
+        sprintf( Header, "%s %s (file %s)",
+                         face->family_name,
+                         face->style_name,
+                         ft_basename( filename ) );
+
+        if (!new_header)
+          new_header = Header;
+              
+        grWriteCellString( &bit, 0, 0, new_header, (grColor)127L );
+        new_header = 0;
+
+        sprintf( Header, "at %d points, first glyph = %d",
+                         ptsize,
+                         Num );
+      }
+      else
+      {
+        sprintf( Header, "%s : is not a font file or could not be opened",
+                         ft_basename(filename) );
+      }
+
+      grWriteCellString( &bit, 0, 8, Header, (grColor)127L );
+      grRefreshSurface( surface );
+      
+      grListenSurface( surface, 0, &event );
+      if ( !( key = Process_Event( &event ) ) )
+        goto Fin;
+
+      if ( key == 'n' )
+      {
+        if (file_loaded >= 1)
+          FT_Done_Face( face );
+          
+        if ( file < argc - 1 )
+          file++;
+
+        goto NewFile;
+      }
+
+      if ( key == 'p' )
+      {
+        if (file_loaded >= 1)
+          FT_Done_Face( face );
+          
+        if ( file > 1 )
+          file--;
+
+        goto NewFile;
+      }
+
+      if ( ptsize != old_ptsize )
+      {
+        if ( Reset_Scale( ptsize ) )
+          PanicZ( "Could not resize font." );
+
+        old_ptsize = ptsize;
+      }
+    }
+
+  Fin:
+#if 0
+    grDoneSurface(surface);
+    grDone();
+#endif
+    printf( "Execution completed successfully.\n" );
+    printf( "Fails = %d\n", Fail );
+
+    exit( 0 );      /* for safety reasons */
+    return 0;       /* never reached */
+}
+
+
+/* End */
+
diff --git a/demos/src/t1dump.c b/demos/src/t1dump.c
new file mode 100644
index 0000000..b349ebf
--- /dev/null
+++ b/demos/src/t1dump.c
@@ -0,0 +1,1031 @@
+/****************************************************************************/
+/*                                                                          */
+/* t1dump.c                                                            1.0  */
+/*                                                                          */
+/* Copyright 1999 - The FreeType Project http://www.freetype.org            */
+/*                                                                          */
+/* T1Dump is a very simply Type 1 font dumper. It can be used to            */
+/* write the following information to the standard ouput, or any            */
+/* given file:                                                              */
+/*                                                                          */
+/*  - a description of the font file (including name, properties, etc..)    */
+/*  - the decrypted private dictionary, 'as is', i.e. in binary form        */
+/*  - the stream of tokens from the font file (useful to debug the          */
+/*    Type1 driver or to look at the font's internal structure..)           */
+/*  - the charstring commands of a given subroutine                         */
+/*  - the charstring commands of a given glyph                              */
+/*  - the encoding                                                          */
+/*  - the glyph names                                                       */
+/*                                                                          */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "freetype.h"
+#include <t1tokens.h>
+#include <t1gload.h>
+#include <t1load.h>
+#include <t1parse.h>
+
+FT_Library      library;    /* root library object */
+FT_Face         face;       /* truetype face */
+T1_Face         t1_face;
+FT_Error        error;
+FILE*           target;
+
+  void Panic( const char* message )
+  {
+    fprintf( stderr, "%s\n  error code = 0x%04x\n", message, error );
+    exit(1);
+  }
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**********                                                       *********/
+/**********                                                       *********/
+/**********              DUMP FONT INFORMATION                    *********/
+/**********                                                       *********/
+/**********                                                       *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+  static
+  T1_Error  Dump_Font_Info( void )
+  {
+    T1_FontInfo*  info = &t1_face->font_info;
+    T1_Private*   priv = &t1_face->private_dict;
+    T1_Int        n;
+
+    fprintf( target, "Font Name    : %s\n", t1_face->font_name );
+
+    fprintf( target, "Version      : %s\n", info->version );
+    fprintf( target, "Full Name    : %s\n", info->full_name );
+    fprintf( target, "Family       : %s\n", info->family_name );
+    fprintf( target, "Weight       : %s\n", info->weight );
+    fprintf( target, "Italic angle : %ld\n", info->italic_angle );
+
+    fprintf( target, "Fixed pitch  : %s\n",
+                     info->is_fixed_pitch ? "yes" : "no" );
+
+    fprintf( target, "Underline    : pos %d, thickness %d\n",
+                     info->underline_position,
+                     info->underline_thickness );
+
+    fprintf( target, "Unique ID    : %d\n", priv->unique_id );
+    fprintf( target, "lenIV        : %d\n", priv->lenIV );
+
+    fprintf( target, "blues        : [" );
+    for ( n = 0; n < priv->num_blues; n++ )
+    fprintf( target, " %d", priv->blue_values[n] );
+    fprintf( target, " ]\n" );
+
+    fprintf( target, "other blues  : [" );
+    for ( n = 0; n < priv->num_other_blues; n++ )
+    fprintf( target, " %d", priv->other_blues[n] );
+    fprintf( target, " ]\n" );
+
+    fprintf( target, "family blues : [" );
+    for ( n = 0; n < priv->num_family_blues; n++ )
+    fprintf( target, " %d", priv->family_blues[n] );
+    fprintf( target, " ]\n" );
+
+    fprintf( target, "family other : [" );
+    for ( n = 0; n < priv->num_family_other_blues; n++ )
+    fprintf( target, " %d", priv->family_other_blues[n] );
+    fprintf( target, " ]\n" );
+
+    fprintf( target, "Blue scale   : %f\n", priv->blue_scale*1.0/65536.0 );
+    fprintf( target, "Blue shift   : %d\n", priv->blue_shift );
+    fprintf( target, "Blue fuzz    : %d\n", priv->blue_fuzz );
+
+    fprintf( target, "Std width    : %d\n", priv->standard_width );
+    fprintf( target, "Std height   : %d\n", priv->standard_height );
+    fprintf( target, "Force bold   : %s\n", priv->force_bold ? "yes" : "no" );
+    fprintf( target, "Round stem   : %s\n", priv->round_stem_up ? "yes" : "no" );
+
+    fprintf( target, "Stem snap W  : [" );
+    for ( n = 0; n < priv->num_snap_widths; n++ )
+    fprintf( target, " %d", priv->stem_snap_widths[n] );
+    fprintf( target, " ]\n" );
+
+    fprintf( target, "Stem snap H  : [" );
+    for ( n = 0; n < priv->num_snap_heights; n++ )
+    fprintf( target, " %d", priv->stem_snap_heights[n] );
+    fprintf( target, " ]\n" );
+
+    fprintf( target, "Language     : %ld\n", priv->language_group );
+    fprintf( target, "Password     : %ld\n", priv->password );
+    fprintf( target, "Min feature  : [ %d %d ]\n",
+             priv->min_feature[0],
+             priv->min_feature[1] );
+
+    fprintf( target, "Font BBOX    : [ %ld %ld %ld %ld ]\n",
+                     t1_face->font_bbox.xMin,
+                     t1_face->font_bbox.yMin,
+                     t1_face->font_bbox.xMax,
+                     t1_face->font_bbox.yMax );
+
+    fprintf( target, "Font matrix  : [ %f %f %f %f ]\n",
+                     1.0*t1_face->font_matrix.xx/65536000.0,
+                     1.0*t1_face->font_matrix.xy/65536000.0,
+                     1.0*t1_face->font_matrix.yx/65536000.0,
+                     1.0*t1_face->font_matrix.yy/65536000.0 );
+#if 0
+    fprintf( target,
+    fprintf( target,
+    fprintf( target,
+    fprintf( target,
+    fprintf( target,
+    fprintf( target,
+#endif
+    fprintf( target, "Num glyphs   : %d\n", t1_face->num_glyphs );
+    fprintf( target, "Num subrs    : %d\n", t1_face->num_subrs );
+    
+    return 0;
+  }
+
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**********                                                       *********/
+/**********                                                       *********/
+/**********              DUMP PRIVATE DICT IN RAW FORM            *********/
+/**********                                                       *********/
+/**********                                                       *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+  static
+  T1_Error  parse_int( T1_Tokenizer  tokzer,
+                       T1_Long*      result )
+  {
+    T1_Bool    sign = 0;
+    T1_Long    sum  = 0;
+    T1_Token*  token = &tokzer->token;
+    T1_Byte*   base  = tokzer->base + token->start;
+    T1_Byte*   limit = base + token->len;
+
+    if (base >= limit)
+      goto Fail;
+
+    /* check sign */
+    if ( *base == '+' )
+      base++;
+
+    else if ( *base == '-' )
+    {
+      sign++;
+      base++;
+    }
+
+    /* parse digits */
+    if ( base >= limit )
+      goto Fail;
+
+    do
+    {
+      sum = ( 10*sum + (*base++ - '0') );
+
+    } while (base < limit);
+
+    if (sign)
+      sum = -sum;
+
+    *result = sum;
+    return T1_Err_Ok;
+
+  Fail:
+    *result = 0;
+    return T1_Err_Syntax_Error;
+  }
+
+
+
+
+
+  static
+  T1_Error  Dump_Private_Dict( const char*  filename )
+  {
+    struct FT_StreamRec_  stream_rec;
+    FT_Stream             stream = &stream_rec;
+    T1_Error              error;
+    T1_Tokenizer          tokenizer;
+
+    error = FT_New_Stream( filename, stream );
+    if (error) return error;
+
+    stream->memory = library->memory;
+    
+    error = New_Tokenizer( stream, &tokenizer );
+    if (error) goto Exit;
+
+    /* go directly to the Private dictionary */
+    error = Open_PrivateDict( tokenizer );
+    if (error)
+      Panic( "Could not open private dictionary !!" );
+
+    /* Write it to the target file */
+    fwrite( tokenizer->base, tokenizer->limit, 1, target );
+
+  Exit:
+    if (stream->close)
+      stream->close(stream);
+
+    return error;
+  }
+
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**********                                                       *********/
+/**********                                                       *********/
+/**********              DUMP TYPE 1 TOKEN STREAM                 *********/
+/**********                                                       *********/
+/**********                                                       *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+  static
+  T1_Error  Dump_Type1_Tokens( const char* filename )
+  {
+    struct FT_StreamRec_  stream_rec;
+    FT_Stream             stream = &stream_rec;
+
+    T1_Error      error;
+    T1_Tokenizer  tokenizer;
+
+    error = FT_New_Stream( filename, stream );
+    if (error) return error;
+
+    stream->memory = library->memory;
+    
+    error = New_Tokenizer( stream, &tokenizer );
+    if (error) goto Exit;
+
+    /* Dump the first segment of the Type1 font */
+    do
+    {
+      T1_Token*  token;
+      T1_String  temp_string[128];
+      T1_Int     len;
+
+      error = Read_Token( tokenizer );
+      if (error) { error = 0; break; }
+
+      /* dump the token */
+      token = &tokenizer->token;
+      len   = token->len;
+      if (len > 127) len = 127;
+
+      strncpy( temp_string,
+               (T1_String*)(tokenizer->base + token->start),
+               len );
+      temp_string[len] = '\0';
+
+      fprintf( target, "%s\n", temp_string );
+
+	  /* Exit the loop when we encounter a "currentfile" token */
+	  if ( token->kind  == tok_keyword &&
+	       token->kind2 == key_currentfile )
+		break;
+
+    } while (1);
+
+    error = Open_PrivateDict( tokenizer );
+    if (error)
+      Panic( "** could not open private dictionary **\n" );
+    else
+    {
+      T1_Int   num = 0;
+      T1_Bool  last_num = 0;
+
+      do
+      {
+        T1_Token*  token;
+        T1_String  temp_string[128];
+        T1_Int     len;
+
+        error = Read_Token( tokenizer );
+        if (error) { error = 0; break; }
+
+        /* dump the token */
+        token = &tokenizer->token;
+        len   = token->len;
+        if (len > 127) len = 127;
+
+        strncpy( temp_string,
+                 (T1_String*)(tokenizer->base + token->start),
+                 len );
+        temp_string[len] = '\0';
+
+        /* detect "RD" uses */
+        if ( token->kind  == tok_keyword          &&
+             ( token->kind2 == key_RD ||
+               token->kind2 == key_RD_alternate ) &&
+             last_num                             )
+        {
+          fprintf( target, "%s [%d binary bytes] ", temp_string, num );
+          tokenizer->cursor += num;
+        }
+        else
+        {
+          fprintf( target, "%s\n", temp_string );
+
+          /* exit dump when we encounter a 'closefile' */
+          if ( token->kind  == tok_keyword   &&
+               token->kind2 == key_closefile )
+            break;
+
+          /* record numerical value if any */
+          if ( token->kind == tok_number )
+          {
+            T1_Long  sum;
+
+            if ( !parse_int( tokenizer, &sum ) )
+            {
+              num      = sum;
+              last_num = 1;
+            }
+            else
+              last_num = 0;
+          }
+          else
+            last_num = 0;
+        }
+
+      } while (1);
+    }
+
+  Exit:
+    if (stream->close)
+      stream->close(stream);
+    return error;
+  }
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**********                                                       *********/
+/**********                                                       *********/
+/**********                DUMP CHARACTER ENCODING                *********/
+/**********                                                       *********/
+/**********                                                       *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+  static
+  void  Dump_Encoding( void )
+  {
+	T1_Encoding*  encode = &t1_face->encoding;
+	int           n;
+
+	fprintf( target, "characters count = %d\n", encode->num_chars );
+
+	fprintf( target, "first code = %d, last code = %d\n",
+			 encode->code_first, encode->code_last );
+
+    for ( n = 0; n < encode->num_chars; n++ )
+    {
+	  int  code = (int)encode->char_index[n];
+
+	  if (code || n == 0)
+	    fprintf( target, "%3d %s\n", n, t1_face->glyph_names[code] );
+    }
+  }
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**********                                                       *********/
+/**********                                                       *********/
+/**********        DUMP SUBROUTINES AND GLYPH CHARSTRINGS         *********/
+/**********                                                       *********/
+/**********                                                       *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+  static
+  void  Dump_CharStrings( T1_Byte*  base,
+                          T1_Int    len )
+  {
+    T1_Byte*   cur   = base;
+    T1_Byte*   limit = base + len;
+    T1_String  temp_name[128];
+    T1_String* string;
+
+    T1_Int     x = 0;
+
+    while ( cur < limit )
+    {
+      switch (*cur++)
+      {
+        case 1:  string = "hstem";     break;
+
+        case 3:  string = "vstem";     break;
+        case 4:  string = "vmoveto";   break;
+        case 5:  string = "rlineto";   break;
+        case 6:  string = "hlineto";   break;
+        case 7:  string = "vlineto";   break;
+        case 8:  string = "rrcurveto"; break;
+        case 9:  string = "closepath"; break;
+        case 10: string = "callsubr";  break;
+        case 11: string = "return";    break;
+
+        case 13: string = "hsbw";      break;
+        case 14: string = "endchar";   break;
+
+        case 21: string = "rmoveto";   break;
+        case 22: string = "hmoveto";   break;
+
+        case 30: string = "vhcurveto"; break;
+        case 31: string = "hvcurveto";  break;
+
+        case 12:
+          {
+            if (cur > limit)
+              Panic( "invalid charstrings stream\n" );
+
+            switch (*cur++)
+            {
+              case 0:  string = "dotsection";      break;
+              case 1:  string = "vstem3";          break;
+              case 2:  string = "hstem3";          break;
+              case 6:  string = "seac";            break;
+              case 7:  string = "sbw";             break;
+              case 12: string = "div";             break;
+              case 16: string = "callothersubr";   break;
+              case 17: string = "pop";             break;
+              case 33: string = "setcurrentpoint"; break;
+
+              default:
+                sprintf( temp_name, "escape(12)+unknown(%d)", cur[1] );
+                string = temp_name;
+            }
+          }
+          break;
+
+        case 255:    /* four bytes integer */
+          {
+            T1_Long  sum;
+
+            if (cur+4 > limit)
+              Panic( "invalid charstrings stream\n" );
+
+            sum = ((long)cur[0] << 24) |
+                  ((long)cur[1] << 16) |
+                  ((long)cur[2] << 8)  |
+                         cur[3];
+            sprintf( temp_name, "%ld ", sum );
+            string = temp_name;
+            cur += 4;
+          }
+          break;
+
+        default:
+          if (cur[-1] >= 32)
+          {
+            if (cur[-1] < 247)
+            {
+              sprintf( temp_name, "%ld", (long)cur[-1] - 139 );
+            }
+            else if (cur[-1] < 251)
+            {
+              cur++;
+              sprintf( temp_name, "%ld",
+                       ((long)(cur[-2]-247) << 8) + cur[-1] + 108 );
+            }
+            else
+            {
+              cur++;
+              sprintf( temp_name, "%ld",
+                       -((long)(cur[-2]-251) << 8) - cur[-1] - 108 );
+            }
+            string = temp_name;
+          }
+          else
+          {
+            sprintf( temp_name, "unknown(%d)", cur[-1] );
+            string = temp_name;
+          }
+      }
+
+      /* now print the charstring command */
+      {
+        int  len = strlen(string)+1;
+
+        if ( x+len > 60 )
+        {
+          x = 0;
+          fprintf( target, "\n" );
+        }
+        else
+          fprintf( target, " " );
+
+        fprintf( target, "%s", string );
+        x += len;
+      }
+    }
+  }
+
+
+
+  static
+  void  Dump_Glyph( int  glyph_index )
+  {
+    fprintf( target, "glyph name: %s\n", t1_face->glyph_names[glyph_index] );
+    Dump_CharStrings( t1_face->charstrings     [glyph_index],
+                      t1_face->charstrings_len [glyph_index] );
+  }
+
+  static
+  void  Dump_Subrs( int  subrs_index )
+  {
+    Dump_CharStrings( t1_face->subrs    [ subrs_index ],
+                      t1_face->subrs_len[ subrs_index ] );
+  }
+
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**********                                                       *********/
+/**********                                                       *********/
+/**********                EXECUTE GLYPH CHARSTRINGS              *********/
+/**********                                                       *********/
+/**********                                                       *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+         static
+         T1_Error  operator_endchar( T1_Builder*  builder )
+         {
+           (void)builder;
+           fprintf( target, "endchar\n" );
+           return 0;
+         }
+       
+       
+         static
+         T1_Error  operator_sbw( T1_Builder*  builder,
+                                 T1_Pos       sbx,
+                                 T1_Pos       sby,
+                                 T1_Pos       wx,
+                                 T1_Pos       wy )
+         {
+           (void)builder;
+           fprintf( target, "set bearing [%ld,%ld] width [%ld,%ld]\n",
+                            sbx, sby, wx, wy );
+           return 0;
+         }
+       
+#if 0
+         static
+         T1_Error  operator_seac( T1_Builder*  builder,
+                                  T1_Pos       asb,
+                                  T1_Pos       adx,
+                                  T1_Pos       ady,
+                                  T1_Int       bchar,
+                                  T1_Int       achar )
+         {
+           (void)builder;
+           fprintf( target, "accented char: %ld [%ld,%ld] b=%d, a=%d\n",
+                            asb, adx, ady, bchar, achar );
+           return 0;
+         }
+#endif
+       
+         static
+         T1_Error  operator_closepath( T1_Builder*  builder )
+         {
+           (void)builder;
+           fprintf( target, "closepath\n" );
+           return 0;
+         }
+       
+       
+         static
+         T1_Error  operator_rlineto( T1_Builder*  builder,
+                                     T1_Pos       dx,
+                                     T1_Pos       dy )
+         {
+           (void)builder;
+           fprintf( target, "%ld %ld rlineto\n", dx, dy );
+           return 0;
+         }
+       
+       
+         static
+         T1_Error  operator_rmoveto( T1_Builder*  builder,
+                                     T1_Pos       dx,
+                                     T1_Pos       dy )
+         {
+           (void)builder;
+           fprintf( target, "%ld %ld rmoveto\n", dx, dy );
+           return 0;
+         }
+       
+       
+         static
+         T1_Error  operator_rrcurveto( T1_Builder*  builder,
+                                       T1_Pos       dx1,
+                                       T1_Pos       dy1,
+                                       T1_Pos       dx2,
+                                       T1_Pos       dy2,
+                                       T1_Pos       dx3,
+                                       T1_Pos       dy3 )
+         {
+           (void)builder;
+           fprintf( target, "%ld %ld %ld %ld %ld %ld rrcurveto\n",
+                    dx1, dy1, dx2, dy2, dx3, dy3 );
+           return 0;
+         }
+       
+       
+         static
+         T1_Error  operator_dotsection( T1_Builder*  builder )
+         {
+           (void)builder;
+           fprintf( target, "dotsection\n" );
+           return 0;
+         }
+       
+       
+         static
+         T1_Error  operator_stem( T1_Builder*  builder,
+                                  T1_Pos       pos,
+                                  T1_Pos       width,
+                                  T1_Bool      vertical )
+         {
+           (void)builder;
+           fprintf( target, "%ld %ld %s\n", pos, width,
+                    vertical ? "vstem" : "hstem" );
+           return 0;
+         }
+       
+       
+         static
+         T1_Error  operator_stem3( T1_Builder*  builder,
+                                   T1_Pos       pos0,
+                                   T1_Pos       width0,
+                                   T1_Pos       pos1,
+                                   T1_Pos       width1,
+                                   T1_Pos       pos2,
+                                   T1_Pos       width2,
+                                   T1_Bool      vertical )
+         {
+           (void)builder;
+           fprintf( target, "%ld %ld %ld %ld %ld %ld %s\n",
+                    pos0, width0, pos1, width1, pos2, width2,
+                    vertical ? "vstem3" : "hstem3" );
+           return 0;
+         }
+       
+       
+#if 0
+         static
+         T1_Error  operator_flex( T1_Builder*  builder,
+                                  T1_Pos       threshold,
+                                  T1_Pos       end_x,
+                                  T1_Pos       end_y )
+         {
+           (void)builder;
+           fprintf( target, "%ld %ld %ld flex\n", threshold, end_x, end_y );
+           return 0;
+         }
+#endif  
+       
+         static
+         T1_Error  operator_changehints( T1_Builder*  builder )
+         {
+           (void)builder;
+           fprintf( target, "-- change hints --\n" );
+           return 0;
+         }
+       
+       
+  static
+  T1_Error  Execute_CharString( int  glyph_index )
+  {
+    static const T1_Builder_Funcs   builds =
+    {
+      operator_endchar,
+      operator_sbw,
+      operator_closepath,
+      operator_rlineto,
+      operator_rmoveto,
+      operator_rrcurveto,
+    };
+
+    static const T1_Hinter_Funcs  hints =
+    {
+      operator_dotsection,
+      operator_changehints,
+      operator_stem,
+      operator_stem3,
+    };
+
+    T1_Decoder  decoder;
+    T1_Error    error;
+
+    T1_Init_Decoder( &decoder, &hints );
+    T1_Init_Builder( &decoder.builder, t1_face, 0, 0, &builds );
+
+    error = T1_Parse_CharStrings( &decoder,
+                                  t1_face->charstrings    [glyph_index],
+                                  t1_face->charstrings_len[glyph_index],
+                                  t1_face->num_subrs,
+                                  t1_face->subrs,
+                                  t1_face->subrs_len );
+   return error;                               
+  }
+
+
+
+
+
+
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**********                                                       *********/
+/**********                                                       *********/
+/**********                  DEBUG FONT LOADING                   *********/
+/**********                                                       *********/
+/**********                                                       *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+  static
+  T1_Error  Debug_Type1_Font( const char*  filename )
+  {
+    struct FT_StreamRec_  stream_rec;
+    T1_FaceRec    t1facerec;
+    T1_Tokenizer  tokenizer;
+    T1_Parser     parser;
+    T1_Error      error;
+    FT_Stream     stream = &stream_rec;
+
+    error = FT_New_Stream( filename, stream );
+    if (error) goto Exit;
+
+    stream->memory = library->memory;
+    
+    /* create an empty face record */
+    memset( &t1facerec, 0, sizeof(t1facerec) );
+    t1facerec.root.memory = library->memory;
+    t1facerec.root.stream = stream;
+
+    t1_face = &t1facerec;
+
+    /* open the tokenizer, this will also check the font format */
+	error = New_Tokenizer( stream, &tokenizer );
+    if (error) goto Fail;
+
+    /* Now, load the font program into the face object */
+    Init_T1_Parser( &parser, t1_face, tokenizer );
+
+    /* force token dump */
+    parser.dump_tokens = 1;
+
+    error = Parse_T1_FontProgram( &parser );
+
+    Done_Tokenizer( tokenizer );
+
+  Fail:
+    if (stream->close)
+      stream->close( stream );
+  Exit:
+    return error;
+  }
+
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**********                                                       *********/
+/**********                                                       *********/
+/**********                     MAIN PROGRAM                      *********/
+/**********                                                       *********/
+/**********                                                       *********/
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+
+
+  static
+  void Usage()
+  {
+    fprintf( stderr, "t1dump       -  a simple Type 1 font dumper\n" );
+    fprintf( stderr, "(c) The FreeType project - www.freetype.org\n" );
+    fprintf( stderr, "-------------------------------------------\n\n" );
+
+    fprintf( stderr, "usage :   t1dump  [options] fontfile(.pfb|.pfa)\n\n" );
+
+    fprintf( stderr, "    options\n" );
+    fprintf( stderr, "          -o filename : dumps to a specific file\n" );
+    fprintf( stderr, "          -g index    : dump glyph charstring\n" );
+    fprintf( stderr, "          -s index    : dump subrs charstring\n" );
+    fprintf( stderr, "          -x index    : execute glyph charstring\n" );
+	fprintf( stderr, "          -e          : dump encoding\n" );
+    fprintf( stderr, "          -t          : dumps the Type 1 token stream\n" );
+    fprintf( stderr, "          -d          : debug font loading\n" );
+    fprintf( stderr, "          -p          : dumps private dictionary 'as is'\n\n" );
+
+    exit(1);
+  }
+
+
+typedef enum Request_
+{
+  req_dump_info,
+  req_dump_private,
+  req_dump_tokens,
+  req_dump_encoding,
+  req_dump_glyph,
+  req_dump_subr,
+  req_load_font,
+  req_execute_glyph,
+  req_debug_font
+
+} Request;
+
+
+static char*    file_name;
+static int      glyph_index;
+static Request  request = req_dump_info;
+
+static FT_Driver t1_driver;
+
+  int  main( int argc, char**  argv )
+  {
+    char  valid;
+
+
+    /* Check number of arguments */
+    if ( argc < 2 ) Usage();
+
+    /* Check options */
+    target = stdout;
+
+    argv++;
+    while (argv[0][0] == '-')
+    {
+      valid = 0;
+      switch (argv[0][1])
+      {
+        case 'p':
+          request = req_dump_private;
+          valid   = 1;
+          break;
+
+        case 't':
+          request = req_dump_tokens;
+          valid   = 1;
+          break;
+
+        case 'e':
+          request = req_dump_encoding;
+          valid   = 1;
+          break;
+
+        case 'd':
+          request = req_debug_font;
+          valid   = 1;
+          break;
+
+        case 'o':
+          if (argc < 2) Usage();
+          target = fopen( argv[1], "w" );
+          if (!target)
+            Panic( "Could not open/create destination file" );
+          argv++;
+          argc--;
+          valid = 1;
+          break;
+
+        case 'g':
+        case 's':
+        case 'x':
+          if (argc < 2) Usage();
+          if ( sscanf( argv[1], "%d", &glyph_index ) != 1 )
+            Usage();
+
+          switch (argv[0][1])
+          {
+            case 'g': request = req_dump_glyph;    break;
+            case 's': request = req_dump_subr;     break;
+            case 'x': request = req_execute_glyph; break;
+          }
+          argv++;
+          argc--;
+          valid = 1;
+          break;
+
+        default:
+          ;
+      }
+
+      if (valid)
+      {
+        argv++;
+        argc--;
+        if (argc < 2) Usage();
+      }
+      else
+        break;
+    }
+
+    /* Get file name */
+    file_name = argv[0];
+
+    /* Instead of calling FT_Init_FreeType, we set up our own system  */
+    /* object and library. This is reserved for FreeType 2 wizards !! */
+
+    /* Init library, read face object, get driver, create size */
+    error = FT_Init_FreeType( &library );
+    if (error) Panic( "could not initialise FreeType library" );
+
+    t1_driver = FT_Get_Driver( library, "type1" );
+    if (!t1_driver) Panic( "no Type1 driver in current FreeType lib" );
+
+    error = FT_New_Face( library, file_name, 0, &face );
+    if (error) Panic( "could not find/open/create font file" );
+    
+    if (face->driver != t1_driver)
+      Panic( "font format is not Type 1 !" );
+
+    switch (request)
+    {
+      case req_dump_private:
+        error = Dump_Private_Dict(file_name);
+        break;
+
+      case req_dump_tokens:
+        error = Dump_Type1_Tokens(file_name);
+        break;
+
+      case req_debug_font:
+        error = Debug_Type1_Font(file_name);
+        break;
+
+      default:
+        error = FT_New_Face( library, file_name, 0, &face );
+        if (error) Panic( "could not load Type 1 font" );
+
+        t1_face = (T1_Face)face;
+
+        /* check glyph index, it is 0 by default */
+        if ( glyph_index < 0 || glyph_index >= t1_face->num_glyphs )
+          Panic( "invalid glyph index\n" );
+
+        switch (request)
+        {
+          case req_dump_glyph:
+            Dump_Glyph( glyph_index );
+            break;
+
+          case req_dump_subr:
+            Dump_Subrs( glyph_index );
+            break;
+
+          case req_execute_glyph:
+            Execute_CharString( glyph_index );
+            break;
+
+          case req_dump_encoding:
+            Dump_Encoding();
+            break;
+
+          default:
+            Dump_Font_Info();
+        }
+    }
+
+    if (error) Panic( "could not dump Type 1 font" );
+
+    FT_Done_FreeType( library );
+    return 0;
+  }
diff --git a/demos/src/ttdebug.c b/demos/src/ttdebug.c
new file mode 100644
index 0000000..b885dda
--- /dev/null
+++ b/demos/src/ttdebug.c
@@ -0,0 +1,1247 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef UNIX
+#ifndef HAVE_POSIX_TERMIOS
+#include <sys/ioctl.h>
+#include <termio.h>
+#else
+#ifndef HAVE_TCGETATTR
+#define HAVE_TCGETATTR
+#endif /* HAVE_TCGETATTR */
+#ifndef HAVE_TCSETATTR
+#define HAVE_TCSETATTR
+#endif /* HAVE_TCSETATTR */
+#include <termios.h>
+#endif /* HAVE_POSIX_TERMIOS */
+#endif
+
+/* Define the `getch()' function.  On Unix systems, it is an alias  */
+/* for `getchar()', and the debugger front end must ensure that the */
+/* `stdin' file descriptor is not in line-by-line input mode.       */
+#ifndef UNIX
+#include <conio.h>
+#else
+#define getch  getchar
+#endif
+
+
+#include "freetype.h"
+#include "ttobjs.h"
+#include "ttdriver.h"
+#include "ttinterp.h"
+
+
+FT_Library      library;    /* root library object */
+FT_Memory       memory;     /* system object */
+TT_Driver       driver;     /* truetype driver */
+TT_Face         face;       /* truetype face */
+TT_Size         size;       /* truetype size */
+TT_GlyphSlot    glyph;      /* truetype glyph slot */
+TT_ExecContext  exec;       /* truetype execution context */
+TT_Error        error;
+
+TT_CodeRange_Tag  debug_coderange = tt_coderange_glyph;
+
+  typedef FT_Byte ByteStr[2];
+  typedef FT_Byte WordStr[4];
+  typedef FT_Byte LongStr[8];
+  typedef FT_Byte DebugStr[128];
+
+  static  DebugStr tempStr;
+
+#undef  PACK
+#define PACK( x, y )  ((x << 4) | y)
+
+  static const TT_Byte  Pop_Push_Count[256] =
+  {
+    /* opcodes are gathered in groups of 16 */
+    /* please keep the spaces as they are   */
+
+    /*  SVTCA  y  */  PACK( 0, 0 ),
+    /*  SVTCA  x  */  PACK( 0, 0 ),
+    /*  SPvTCA y  */  PACK( 0, 0 ),
+    /*  SPvTCA x  */  PACK( 0, 0 ),
+    /*  SFvTCA y  */  PACK( 0, 0 ),
+    /*  SFvTCA x  */  PACK( 0, 0 ),
+    /*  SPvTL //  */  PACK( 2, 0 ),
+    /*  SPvTL +   */  PACK( 2, 0 ),
+    /*  SFvTL //  */  PACK( 2, 0 ),
+    /*  SFvTL +   */  PACK( 2, 0 ),
+    /*  SPvFS     */  PACK( 2, 0 ),
+    /*  SFvFS     */  PACK( 2, 0 ),
+    /*  GPV       */  PACK( 0, 2 ),
+    /*  GFV       */  PACK( 0, 2 ),
+    /*  SFvTPv    */  PACK( 0, 0 ),
+    /*  ISECT     */  PACK( 5, 0 ),
+
+    /*  SRP0      */  PACK( 1, 0 ),
+    /*  SRP1      */  PACK( 1, 0 ),
+    /*  SRP2      */  PACK( 1, 0 ),
+    /*  SZP0      */  PACK( 1, 0 ),
+    /*  SZP1      */  PACK( 1, 0 ),
+    /*  SZP2      */  PACK( 1, 0 ),
+    /*  SZPS      */  PACK( 1, 0 ),
+    /*  SLOOP     */  PACK( 1, 0 ),
+    /*  RTG       */  PACK( 0, 0 ),
+    /*  RTHG      */  PACK( 0, 0 ),
+    /*  SMD       */  PACK( 1, 0 ),
+    /*  ELSE      */  PACK( 0, 0 ),
+    /*  JMPR      */  PACK( 1, 0 ),
+    /*  SCvTCi    */  PACK( 1, 0 ),
+    /*  SSwCi     */  PACK( 1, 0 ),
+    /*  SSW       */  PACK( 1, 0 ),
+
+    /*  DUP       */  PACK( 1, 2 ),
+    /*  POP       */  PACK( 1, 0 ),
+    /*  CLEAR     */  PACK( 0, 0 ),
+    /*  SWAP      */  PACK( 2, 2 ),
+    /*  DEPTH     */  PACK( 0, 1 ),
+    /*  CINDEX    */  PACK( 1, 1 ),
+    /*  MINDEX    */  PACK( 1, 0 ),
+    /*  AlignPTS  */  PACK( 2, 0 ),
+    /*  INS_$28   */  PACK( 0, 0 ),
+    /*  UTP       */  PACK( 1, 0 ),
+    /*  LOOPCALL  */  PACK( 2, 0 ),
+    /*  CALL      */  PACK( 1, 0 ),
+    /*  FDEF      */  PACK( 1, 0 ),
+    /*  ENDF      */  PACK( 0, 0 ),
+    /*  MDAP[0]   */  PACK( 1, 0 ),
+    /*  MDAP[1]   */  PACK( 1, 0 ),
+
+    /*  IUP[0]    */  PACK( 0, 0 ),
+    /*  IUP[1]    */  PACK( 0, 0 ),
+    /*  SHP[0]    */  PACK( 0, 0 ),
+    /*  SHP[1]    */  PACK( 0, 0 ),
+    /*  SHC[0]    */  PACK( 1, 0 ),
+    /*  SHC[1]    */  PACK( 1, 0 ),
+    /*  SHZ[0]    */  PACK( 1, 0 ),
+    /*  SHZ[1]    */  PACK( 1, 0 ),
+    /*  SHPIX     */  PACK( 1, 0 ),
+    /*  IP        */  PACK( 0, 0 ),
+    /*  MSIRP[0]  */  PACK( 2, 0 ),
+    /*  MSIRP[1]  */  PACK( 2, 0 ),
+    /*  AlignRP   */  PACK( 0, 0 ),
+    /*  RTDG      */  PACK( 0, 0 ),
+    /*  MIAP[0]   */  PACK( 2, 0 ),
+    /*  MIAP[1]   */  PACK( 2, 0 ),
+
+    /*  NPushB    */  PACK( 0, 0 ),
+    /*  NPushW    */  PACK( 0, 0 ),
+    /*  WS        */  PACK( 2, 0 ),
+    /*  RS        */  PACK( 1, 1 ),
+    /*  WCvtP     */  PACK( 2, 0 ),
+    /*  RCvt      */  PACK( 1, 1 ),
+    /*  GC[0]     */  PACK( 1, 1 ),
+    /*  GC[1]     */  PACK( 1, 1 ),
+    /*  SCFS      */  PACK( 2, 0 ),
+    /*  MD[0]     */  PACK( 2, 1 ),
+    /*  MD[1]     */  PACK( 2, 1 ),
+    /*  MPPEM     */  PACK( 0, 1 ),
+    /*  MPS       */  PACK( 0, 1 ),
+    /*  FlipON    */  PACK( 0, 0 ),
+    /*  FlipOFF   */  PACK( 0, 0 ),
+    /*  DEBUG     */  PACK( 1, 0 ),
+
+    /*  LT        */  PACK( 2, 1 ),
+    /*  LTEQ      */  PACK( 2, 1 ),
+    /*  GT        */  PACK( 2, 1 ),
+    /*  GTEQ      */  PACK( 2, 1 ),
+    /*  EQ        */  PACK( 2, 1 ),
+    /*  NEQ       */  PACK( 2, 1 ),
+    /*  ODD       */  PACK( 1, 1 ),
+    /*  EVEN      */  PACK( 1, 1 ),
+    /*  IF        */  PACK( 1, 0 ),
+    /*  EIF       */  PACK( 0, 0 ),
+    /*  AND       */  PACK( 2, 1 ),
+    /*  OR        */  PACK( 2, 1 ),
+    /*  NOT       */  PACK( 1, 1 ),
+    /*  DeltaP1   */  PACK( 1, 0 ),
+    /*  SDB       */  PACK( 1, 0 ),
+    /*  SDS       */  PACK( 1, 0 ),
+
+    /*  ADD       */  PACK( 2, 1 ),
+    /*  SUB       */  PACK( 2, 1 ),
+    /*  DIV       */  PACK( 2, 1 ),
+    /*  MUL       */  PACK( 2, 1 ),
+    /*  ABS       */  PACK( 1, 1 ),
+    /*  NEG       */  PACK( 1, 1 ),
+    /*  FLOOR     */  PACK( 1, 1 ),
+    /*  CEILING   */  PACK( 1, 1 ),
+    /*  ROUND[0]  */  PACK( 1, 1 ),
+    /*  ROUND[1]  */  PACK( 1, 1 ),
+    /*  ROUND[2]  */  PACK( 1, 1 ),
+    /*  ROUND[3]  */  PACK( 1, 1 ),
+    /*  NROUND[0] */  PACK( 1, 1 ),
+    /*  NROUND[1] */  PACK( 1, 1 ),
+    /*  NROUND[2] */  PACK( 1, 1 ),
+    /*  NROUND[3] */  PACK( 1, 1 ),
+
+    /*  WCvtF     */  PACK( 2, 0 ),
+    /*  DeltaP2   */  PACK( 1, 0 ),
+    /*  DeltaP3   */  PACK( 1, 0 ),
+    /*  DeltaCn[0] */ PACK( 1, 0 ),
+    /*  DeltaCn[1] */ PACK( 1, 0 ),
+    /*  DeltaCn[2] */ PACK( 1, 0 ),
+    /*  SROUND    */  PACK( 1, 0 ),
+    /*  S45Round  */  PACK( 1, 0 ),
+    /*  JROT      */  PACK( 2, 0 ),
+    /*  JROF      */  PACK( 2, 0 ),
+    /*  ROFF      */  PACK( 0, 0 ),
+    /*  INS_$7B   */  PACK( 0, 0 ),
+    /*  RUTG      */  PACK( 0, 0 ),
+    /*  RDTG      */  PACK( 0, 0 ),
+    /*  SANGW     */  PACK( 1, 0 ),
+    /*  AA        */  PACK( 1, 0 ),
+
+    /*  FlipPT    */  PACK( 0, 0 ),
+    /*  FlipRgON  */  PACK( 2, 0 ),
+    /*  FlipRgOFF */  PACK( 2, 0 ),
+    /*  INS_$83   */  PACK( 0, 0 ),
+    /*  INS_$84   */  PACK( 0, 0 ),
+    /*  ScanCTRL  */  PACK( 1, 0 ),
+    /*  SDVPTL[0] */  PACK( 2, 0 ),
+    /*  SDVPTL[1] */  PACK( 2, 0 ),
+    /*  GetINFO   */  PACK( 1, 1 ),
+    /*  IDEF      */  PACK( 1, 0 ),
+    /*  ROLL      */  PACK( 3, 3 ),
+    /*  MAX       */  PACK( 2, 1 ),
+    /*  MIN       */  PACK( 2, 1 ),
+    /*  ScanTYPE  */  PACK( 1, 0 ),
+    /*  InstCTRL  */  PACK( 2, 0 ),
+    /*  INS_$8F   */  PACK( 0, 0 ),
+
+    /*  INS_$90  */   PACK( 0, 0 ),
+    /*  INS_$91  */   PACK( 0, 0 ),
+    /*  INS_$92  */   PACK( 0, 0 ),
+    /*  INS_$93  */   PACK( 0, 0 ),
+    /*  INS_$94  */   PACK( 0, 0 ),
+    /*  INS_$95  */   PACK( 0, 0 ),
+    /*  INS_$96  */   PACK( 0, 0 ),
+    /*  INS_$97  */   PACK( 0, 0 ),
+    /*  INS_$98  */   PACK( 0, 0 ),
+    /*  INS_$99  */   PACK( 0, 0 ),
+    /*  INS_$9A  */   PACK( 0, 0 ),
+    /*  INS_$9B  */   PACK( 0, 0 ),
+    /*  INS_$9C  */   PACK( 0, 0 ),
+    /*  INS_$9D  */   PACK( 0, 0 ),
+    /*  INS_$9E  */   PACK( 0, 0 ),
+    /*  INS_$9F  */   PACK( 0, 0 ),
+
+    /*  INS_$A0  */   PACK( 0, 0 ),
+    /*  INS_$A1  */   PACK( 0, 0 ),
+    /*  INS_$A2  */   PACK( 0, 0 ),
+    /*  INS_$A3  */   PACK( 0, 0 ),
+    /*  INS_$A4  */   PACK( 0, 0 ),
+    /*  INS_$A5  */   PACK( 0, 0 ),
+    /*  INS_$A6  */   PACK( 0, 0 ),
+    /*  INS_$A7  */   PACK( 0, 0 ),
+    /*  INS_$A8  */   PACK( 0, 0 ),
+    /*  INS_$A9  */   PACK( 0, 0 ),
+    /*  INS_$AA  */   PACK( 0, 0 ),
+    /*  INS_$AB  */   PACK( 0, 0 ),
+    /*  INS_$AC  */   PACK( 0, 0 ),
+    /*  INS_$AD  */   PACK( 0, 0 ),
+    /*  INS_$AE  */   PACK( 0, 0 ),
+    /*  INS_$AF  */   PACK( 0, 0 ),
+
+    /*  PushB[0]  */  PACK( 0, 1 ),
+    /*  PushB[1]  */  PACK( 0, 2 ),
+    /*  PushB[2]  */  PACK( 0, 3 ),
+    /*  PushB[3]  */  PACK( 0, 4 ),
+    /*  PushB[4]  */  PACK( 0, 5 ),
+    /*  PushB[5]  */  PACK( 0, 6 ),
+    /*  PushB[6]  */  PACK( 0, 7 ),
+    /*  PushB[7]  */  PACK( 0, 8 ),
+    /*  PushW[0]  */  PACK( 0, 1 ),
+    /*  PushW[1]  */  PACK( 0, 2 ),
+    /*  PushW[2]  */  PACK( 0, 3 ),
+    /*  PushW[3]  */  PACK( 0, 4 ),
+    /*  PushW[4]  */  PACK( 0, 5 ),
+    /*  PushW[5]  */  PACK( 0, 6 ),
+    /*  PushW[6]  */  PACK( 0, 7 ),
+    /*  PushW[7]  */  PACK( 0, 8 ),
+
+    /*  MDRP[00]  */  PACK( 1, 0 ),
+    /*  MDRP[01]  */  PACK( 1, 0 ),
+    /*  MDRP[02]  */  PACK( 1, 0 ),
+    /*  MDRP[03]  */  PACK( 1, 0 ),
+    /*  MDRP[04]  */  PACK( 1, 0 ),
+    /*  MDRP[05]  */  PACK( 1, 0 ),
+    /*  MDRP[06]  */  PACK( 1, 0 ),
+    /*  MDRP[07]  */  PACK( 1, 0 ),
+    /*  MDRP[08]  */  PACK( 1, 0 ),
+    /*  MDRP[09]  */  PACK( 1, 0 ),
+    /*  MDRP[10]  */  PACK( 1, 0 ),
+    /*  MDRP[11]  */  PACK( 1, 0 ),
+    /*  MDRP[12]  */  PACK( 1, 0 ),
+    /*  MDRP[13]  */  PACK( 1, 0 ),
+    /*  MDRP[14]  */  PACK( 1, 0 ),
+    /*  MDRP[15]  */  PACK( 1, 0 ),
+
+    /*  MDRP[16]  */  PACK( 1, 0 ),
+    /*  MDRP[17]  */  PACK( 1, 0 ),
+    /*  MDRP[18]  */  PACK( 1, 0 ),
+    /*  MDRP[19]  */  PACK( 1, 0 ),
+    /*  MDRP[20]  */  PACK( 1, 0 ),
+    /*  MDRP[21]  */  PACK( 1, 0 ),
+    /*  MDRP[22]  */  PACK( 1, 0 ),
+    /*  MDRP[23]  */  PACK( 1, 0 ),
+    /*  MDRP[24]  */  PACK( 1, 0 ),
+    /*  MDRP[25]  */  PACK( 1, 0 ),
+    /*  MDRP[26]  */  PACK( 1, 0 ),
+    /*  MDRP[27]  */  PACK( 1, 0 ),
+    /*  MDRP[28]  */  PACK( 1, 0 ),
+    /*  MDRP[29]  */  PACK( 1, 0 ),
+    /*  MDRP[30]  */  PACK( 1, 0 ),
+    /*  MDRP[31]  */  PACK( 1, 0 ),
+
+    /*  MIRP[00]  */  PACK( 2, 0 ),
+    /*  MIRP[01]  */  PACK( 2, 0 ),
+    /*  MIRP[02]  */  PACK( 2, 0 ),
+    /*  MIRP[03]  */  PACK( 2, 0 ),
+    /*  MIRP[04]  */  PACK( 2, 0 ),
+    /*  MIRP[05]  */  PACK( 2, 0 ),
+    /*  MIRP[06]  */  PACK( 2, 0 ),
+    /*  MIRP[07]  */  PACK( 2, 0 ),
+    /*  MIRP[08]  */  PACK( 2, 0 ),
+    /*  MIRP[09]  */  PACK( 2, 0 ),
+    /*  MIRP[10]  */  PACK( 2, 0 ),
+    /*  MIRP[11]  */  PACK( 2, 0 ),
+    /*  MIRP[12]  */  PACK( 2, 0 ),
+    /*  MIRP[13]  */  PACK( 2, 0 ),
+    /*  MIRP[14]  */  PACK( 2, 0 ),
+    /*  MIRP[15]  */  PACK( 2, 0 ),
+
+    /*  MIRP[16]  */  PACK( 2, 0 ),
+    /*  MIRP[17]  */  PACK( 2, 0 ),
+    /*  MIRP[18]  */  PACK( 2, 0 ),
+    /*  MIRP[19]  */  PACK( 2, 0 ),
+    /*  MIRP[20]  */  PACK( 2, 0 ),
+    /*  MIRP[21]  */  PACK( 2, 0 ),
+    /*  MIRP[22]  */  PACK( 2, 0 ),
+    /*  MIRP[23]  */  PACK( 2, 0 ),
+    /*  MIRP[24]  */  PACK( 2, 0 ),
+    /*  MIRP[25]  */  PACK( 2, 0 ),
+    /*  MIRP[26]  */  PACK( 2, 0 ),
+    /*  MIRP[27]  */  PACK( 2, 0 ),
+    /*  MIRP[28]  */  PACK( 2, 0 ),
+    /*  MIRP[29]  */  PACK( 2, 0 ),
+    /*  MIRP[30]  */  PACK( 2, 0 ),
+    /*  MIRP[31]  */  PACK( 2, 0 )
+  };
+
+
+  static const FT_String*  OpStr[256] = {
+            "SVTCA y",       /* Set vectors to coordinate axis y    */
+            "SVTCA x",       /* Set vectors to coordinate axis x    */
+            "SPvTCA y",      /* Set Proj. vec. to coord. axis y     */
+            "SPvTCA x",      /* Set Proj. vec. to coord. axis x     */
+            "SFvTCA y",      /* Set Free. vec. to coord. axis y     */
+            "SFvTCA x",      /* Set Free. vec. to coord. axis x     */
+            "SPvTL //",      /* Set Proj. vec. parallel to segment  */
+            "SPvTL +",       /* Set Proj. vec. normal to segment    */
+            "SFvTL //",      /* Set Free. vec. parallel to segment  */
+            "SFvTL +",       /* Set Free. vec. normal to segment    */
+            "SPvFS",         /* Set Proj. vec. from stack           */
+            "SFvFS",         /* Set Free. vec. from stack           */
+            "GPV",           /* Get projection vector               */
+            "GFV",           /* Get freedom vector                  */
+            "SFvTPv",        /* Set free. vec. to proj. vec.        */
+            "ISECT",         /* compute intersection                */
+
+            "SRP0",          /* Set reference point 0               */
+            "SRP1",          /* Set reference point 1               */
+            "SRP2",          /* Set reference point 2               */
+            "SZP0",          /* Set Zone Pointer 0                  */
+            "SZP1",          /* Set Zone Pointer 1                  */
+            "SZP2",          /* Set Zone Pointer 2                  */
+            "SZPS",          /* Set all zone pointers               */
+            "SLOOP",         /* Set loop counter                    */
+            "RTG",           /* Round to Grid                       */
+            "RTHG",          /* Round to Half-Grid                  */
+            "SMD",           /* Set Minimum Distance                */
+            "ELSE",          /* Else                                */
+            "JMPR",          /* Jump Relative                       */
+            "SCvTCi",        /* Set CVT                             */
+            "SSwCi",         /*                                     */
+            "SSW",           /*                                     */
+
+            "DUP",
+            "POP",
+            "CLEAR",
+            "SWAP",
+            "DEPTH",
+            "CINDEX",
+            "MINDEX",
+            "AlignPTS",
+            "INS_$28",
+            "UTP",
+            "LOOPCALL",
+            "CALL",
+            "FDEF",
+            "ENDF",
+            "MDAP[-]",
+            "MDAP[r]",
+
+            "IUP[y]",
+            "IUP[x]",
+            "SHP[0]",
+            "SHP[1]",
+            "SHC[0]",
+            "SHC[1]",
+            "SHZ[0]",
+            "SHZ[1]",
+            "SHPIX",
+            "IP",
+            "MSIRP[0]",
+            "MSIRP[1]",
+            "AlignRP",
+            "RTDG",
+            "MIAP[-]",
+            "MIAP[r]",
+
+            "NPushB",
+            "NPushW",
+            "WS",
+            "RS",
+            "WCvtP",
+            "RCvt",
+            "GC[0]",
+            "GC[1]",
+            "SCFS",
+            "MD[0]",
+            "MD[1]",
+            "MPPEM",
+            "MPS",
+            "FlipON",
+            "FlipOFF",
+            "DEBUG",
+
+            "LT",
+            "LTEQ",
+            "GT",
+            "GTEQ",
+            "EQ",
+            "NEQ",
+            "ODD",
+            "EVEN",
+            "IF",
+            "EIF",
+            "AND",
+            "OR",
+            "NOT",
+            "DeltaP1",
+            "SDB",
+            "SDS",
+
+            "ADD",
+            "SUB",
+            "DIV",
+            "MUL",
+            "ABS",
+            "NEG",
+            "FLOOR",
+            "CEILING",
+            "ROUND[G]",
+            "ROUND[B]",
+            "ROUND[W]",
+            "ROUND[?]",
+            "NROUND[G]",
+            "NROUND[B]",
+            "NROUND[W]",
+            "NROUND[?]",
+
+            "WCvtF",
+            "DeltaP2",
+            "DeltaP3",
+            "DeltaC1",
+            "DeltaC2",
+            "DeltaC3",
+            "SROUND",
+            "S45Round",
+            "JROT",
+            "JROF",
+            "ROFF",
+            "INS_$7B",
+            "RUTG",
+            "RDTG",
+            "SANGW",
+            "AA",
+
+            "FlipPT",
+            "FlipRgON",
+            "FlipRgOFF",
+            "INS_$83",
+            "INS_$84",
+            "ScanCTRL",
+            "SDPVTL[0]",
+            "SDPVTL[1]",
+            "GetINFO",
+            "IDEF",
+            "ROLL",
+            "MAX",
+            "MIN",
+            "ScanTYPE",
+            "IntCTRL",
+            "INS_$8F",
+
+            "INS_$90",
+            "INS_$91",
+            "INS_$92",
+            "INS_$93",
+            "INS_$94",
+            "INS_$95",
+            "INS_$96",
+            "INS_$97",
+            "INS_$98",
+            "INS_$99",
+            "INS_$9A",
+            "INS_$9B",
+            "INS_$9C",
+            "INS_$9D",
+            "INS_$9E",
+            "INS_$9F",
+
+            "INS_$A0",
+            "INS_$A1",
+            "INS_$A2",
+            "INS_$A3",
+            "INS_$A4",
+            "INS_$A5",
+            "INS_$A6",
+            "INS_$A7",
+            "INS_$A8",
+            "INS_$A9",
+            "INS_$AA",
+            "INS_$AB",
+            "INS_$AC",
+            "INS_$AD",
+            "INS_$AE",
+            "INS_$AF",
+
+            "PushB[0]",
+            "PushB[1]",
+            "PushB[2]",
+            "PushB[3]",
+            "PushB[4]",
+            "PushB[5]",
+            "PushB[6]",
+            "PushB[7]",
+            "PushW[0]",
+            "PushW[1]",
+            "PushW[2]",
+            "PushW[3]",
+            "PushW[4]",
+            "PushW[5]",
+            "PushW[6]",
+            "PushW[7]",
+
+            "MDRP[G]",
+            "MDRP[B]",
+            "MDRP[W]",
+            "MDRP[?]",
+            "MDRP[rG]",
+            "MDRP[rB]",
+            "MDRP[rW]",
+            "MDRP[r?]",
+            "MDRP[mG]",
+            "MDRP[mB]",
+            "MDRP[mW]",
+            "MDRP[m?]",
+            "MDRP[mrG]",
+            "MDRP[mrB]",
+            "MDRP[mrW]",
+            "MDRP[mr?]",
+            "MDRP[pG]",
+            "MDRP[pB]",
+
+            "MDRP[pW]",
+            "MDRP[p?]",
+            "MDRP[prG]",
+            "MDRP[prB]",
+            "MDRP[prW]",
+            "MDRP[pr?]",
+            "MDRP[pmG]",
+            "MDRP[pmB]",
+            "MDRP[pmW]",
+            "MDRP[pm?]",
+            "MDRP[pmrG]",
+            "MDRP[pmrB]",
+            "MDRP[pmrW]",
+            "MDRP[pmr?]",
+
+            "MIRP[G]",
+            "MIRP[B]",
+            "MIRP[W]",
+            "MIRP[?]",
+            "MIRP[rG]",
+            "MIRP[rB]",
+            "MIRP[rW]",
+            "MIRP[r?]",
+            "MIRP[mG]",
+            "MIRP[mB]",
+            "MIRP[mW]",
+            "MIRP[m?]",
+            "MIRP[mrG]",
+            "MIRP[mrB]",
+            "MIRP[mrW]",
+            "MIRP[mr?]",
+            "MIRP[pG]",
+            "MIRP[pB]",
+
+            "MIRP[pW]",
+            "MIRP[p?]",
+            "MIRP[prG]",
+            "MIRP[prB]",
+            "MIRP[prW]",
+            "MIRP[pr?]",
+            "MIRP[pmG]",
+            "MIRP[pmB]",
+            "MIRP[pmW]",
+            "MIRP[pm?]",
+            "MIRP[pmrG]",
+            "MIRP[pmrB]",
+            "MIRP[pmrW]",
+            "MIRP[pmr?]"
+          };
+
+
+/*********************************************************************
+ *
+ * Init_Keyboard : set the input file descriptor to char-by-char
+ *                 mode on Unix..
+ *
+ *********************************************************************/
+
+#ifdef UNIX
+
+ struct termios  old_termio;
+ 
+ static
+ void Init_Keyboard( void )
+ {
+   struct termios  termio;
+
+#ifndef HAVE_TCGETATTR
+   ioctl( 0, TCGETS, &old_termio ); 
+#else
+   tcgetattr( 0, &old_termio );
+#endif
+
+   termio = old_termio;
+   
+/*   termio.c_lflag &= ~(ICANON+ECHO+ECHOE+ECHOK+ECHONL+ECHOKE); */
+   termio.c_lflag &= ~(ICANON+ECHO+ECHOE+ECHOK+ECHONL);
+
+#ifndef HAVE_TCSETATTR
+   ioctl( 0, TCSETS, &termio );
+#else
+   tcsetattr( 0, TCSANOW, &termio );
+#endif
+ }
+
+ static
+ void Reset_Keyboard( void )
+ {
+#ifndef HAVE_TCSETATTR
+   ioctl( 0, TCSETS, &old_termio );
+#else
+   tcsetattr( 0, TCSANOW, &old_termio );
+#endif
+
+ }
+
+#else
+
+ static
+ void Init_Keyboard( void )
+ {
+ }
+
+ static
+ void Reset_Keyboard( void )
+ {
+ }
+
+#endif
+
+
+  void Panic( const char* message )
+  {
+    fprintf( stderr, "%s\n  error code = 0x%04x\n", message, error );
+    Reset_Keyboard();
+    exit(1);
+  }
+
+
+/******************************************************************
+ *
+ *  Function    :  Calc_Length
+ *
+ *  Description :  Computes the length in bytes of current opcode.
+ *
+ *****************************************************************/
+
+#define CUR  (*exc)
+
+
+  static void  Calc_Length( TT_ExecContext  exc )
+  {
+    CUR.opcode = CUR.code[CUR.IP];
+
+    switch ( CUR.opcode )
+    {
+    case 0x40:
+      if ( CUR.IP + 1 >= CUR.codeSize )
+        Panic( "code range overflow !!" );
+
+      CUR.length = CUR.code[CUR.IP + 1] + 2;
+      break;
+
+    case 0x41:
+      if ( CUR.IP + 1 >= CUR.codeSize )
+        Panic( "code range overflow !!" );
+
+      CUR.length = CUR.code[CUR.IP + 1] * 2 + 2;
+      break;
+
+    case 0xB0:
+    case 0xB1:
+    case 0xB2:
+    case 0xB3:
+    case 0xB4:
+    case 0xB5:
+    case 0xB6:
+    case 0xB7:
+      CUR.length = CUR.opcode - 0xB0 + 2;
+      break;
+
+    case 0xB8:
+    case 0xB9:
+    case 0xBA:
+    case 0xBB:
+    case 0xBC:
+    case 0xBD:
+    case 0xBE:
+    case 0xBF:
+      CUR.length = (CUR.opcode - 0xB8) * 2 + 3;
+      break;
+
+    default:
+      CUR.length = 1;
+      break;
+    }
+
+    /* make sure result is in range */
+
+    if ( CUR.IP + CUR.length > CUR.codeSize )
+      Panic( "code range overflow !!" );
+  }
+
+
+  /* Disassemble the current line */
+  /*                              */
+  const FT_String* Cur_U_Line( TT_ExecContext  exec )
+  {
+    FT_String  s[32];
+    FT_Int op, i, n;
+
+    op = exec->code[ exec->IP ];
+
+    sprintf( tempStr, "%04lx: %02hx  %s", exec->IP, op, OpStr[op] );
+
+    if ( op == 0x40 )
+    {
+      n = exec->code[ exec->IP+1 ];
+      sprintf( s, "(%d)", n );
+      strncat( tempStr, s, 8 );
+
+      if ( n > 20 ) n = 20; /* limit output */
+
+      for ( i = 0; i < n; i++ )
+      {
+        sprintf( s, " $%02hx", exec->code[ exec->IP+i+2 ] );
+        strncat( tempStr, s, 8 );
+      }
+    }
+    else if ( op == 0x41 )
+    {
+      n = exec->code[ exec->IP+1 ];
+      sprintf( s, "(%d)", n );
+      strncat( tempStr, s, 8 );
+
+      if (n > 20) n = 20; /* limit output */
+
+      for ( i = 0; i < n; i++ )
+      {
+        sprintf( s, " $%02hx%02hx", exec->code[ exec->IP+i*2+2 ],
+                                    exec->code[ exec->IP+i*2+3 ] );
+        strncat( tempStr, s, 8 );
+      }
+    }
+    else if ( (op & 0xF8) == 0xB0 )
+    {
+      n = op-0xB0;
+
+      for ( i=0; i <= n; i++ )
+      {
+        sprintf( s, " $%02hx", exec->code[ exec->IP+i+1 ] );
+        strncat( tempStr, s, 8 );
+      }
+    }
+    else if ( (op & 0xF8) == 0xB8 )
+    {
+      n = op-0xB8;
+
+      for ( i = 0; i <= n; i++ )
+      {
+        sprintf( s, " $%02hx%02hx", exec->code[ exec->IP+i*2+1 ],
+                                  exec->code[ exec->IP+i*2+2 ] );
+        strncat( tempStr, s, 8 );
+      }
+    }
+
+    return (FT_String*)tempStr;
+  }
+
+
+  static
+  TT_Error  RunIns( TT_ExecContext  exc )
+  {
+    FT_Int    A, diff, key;
+    FT_Long   next_IP;
+    FT_Char   ch, oldch, *temp;
+
+    TT_Error  error = 0;
+
+    TT_GlyphZone  save;
+    TT_GlyphZone  pts;
+
+    const FT_String*  round_str[8] =
+    {
+      "to half-grid",
+      "to grid",
+      "to double grid",
+      "down to grid",
+      "up to grid",
+      "off",
+      "super",
+      "super 45"
+    };
+
+    /* only debug the requested code range */
+    if (exc->curRange != (TT_Int)debug_coderange)
+      return TT_RunIns(exc);
+
+    exc->pts.n_points   = exc->zp0.n_points;
+    exc->pts.n_contours = exc->zp0.n_contours;
+
+    pts = exc->pts;
+    
+
+    save.n_points   = pts.n_points;
+    save.n_contours = pts.n_contours;
+
+    save.org   = (TT_Vector*)malloc( 2 * sizeof( TT_F26Dot6 ) *
+                                       save.n_points );
+    save.cur   = (TT_Vector*)malloc( 2 * sizeof( TT_F26Dot6 ) *
+                                       save.n_points );
+    save.touch = (TT_Byte*)malloc( save.n_points );
+
+    exc->instruction_trap = 1;
+
+    do
+    {
+      if ( CUR.IP < CUR.codeSize )
+      {
+        Calc_Length( exc );
+
+        CUR.args = CUR.top - (Pop_Push_Count[CUR.opcode] >> 4);
+
+        /* `args' is the top of the stack once arguments have been popped. */
+        /* One can also interpret it as the index of the last argument.    */
+
+        /* Print the current line.  We use a 80-columns console with the   */
+        /* following formatting:                                           */
+        /*                                                                 */
+        /* [loc]:[addr] [opcode]  [disassemby]          [a][b]|[c][d]      */
+        /*                                                                 */
+
+        {
+          char      temp[80];
+          int       n, col, pop;
+          int       args = CUR.args;
+
+          sprintf( temp, "%78c\n", ' ' );
+
+          /* first letter of location */
+          switch ( CUR.curRange )
+          {
+          case tt_coderange_glyph:
+            temp[0] = 'g';
+            break;
+          case tt_coderange_cvt:
+            temp[0] = 'c';
+            break;
+          default:
+            temp[0] = 'f';
+          }
+
+          /* current IP */
+          sprintf( temp+1, "%04lx: %02x  %-36.36s",
+                   CUR.IP,
+                   CUR.opcode,
+                   Cur_U_Line(&CUR) );
+
+          strncpy( temp+46, " (", 2 );
+
+          args = CUR.top - 1;
+          pop  = Pop_Push_Count[CUR.opcode] >> 4;
+          col  = 48;
+          for ( n = 6; n > 0; n-- )
+          {
+            if ( pop == 0 )
+              temp[col-1] = (temp[col-1] == '(' ? ' ' : ')' );
+
+            if ( args < CUR.top && args >= 0 )
+              sprintf( temp+col, "%04lx", CUR.stack[args] );
+            else
+              sprintf( temp+col, "    " );
+
+            temp[col+4] = ' ';
+            col += 5;
+            pop--;
+            args--;
+          }
+          temp[78] = '\n';
+          temp[79] = '\0';
+          printf( "%s", temp );
+        }
+
+        /* First, check for empty stack and overflow */
+        if ( CUR.args < 0 )
+        {
+          printf( "ERROR : Too Few Arguments\n" );
+          CUR.error = TT_Err_Too_Few_Arguments;
+          goto LErrorLabel_;
+        }
+
+        CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15);
+
+      /* new_top  is the new top of the stack, after the instruction's */
+      /* execution. top will be set to new_top after the 'case'        */
+
+        if ( CUR.new_top > CUR.stackSize )
+        {
+          printf( "ERROR : Stack overflow\n" );
+          CUR.error = TT_Err_Stack_Overflow;
+          goto LErrorLabel_;
+        }
+      }
+      else
+        printf( "End of program reached.\n" );
+
+      key = 0;
+      do
+      {
+       /* read keyboard */
+
+        ch = getch();
+
+        switch ( ch )
+        {
+        /* Help - show keybindings */
+        case '?':
+          printf( "TTDebug Help\n\n" );
+          printf( "?   Show this page\n" );
+          printf( "q   Quit debugger\n" );
+          printf( "n   Skip to next instruction\n" );
+          printf( "s   Step into\n" );
+          printf( "v   Show vector info\n" );
+          printf( "g   Show graphics state\n" );
+          printf( "p   Show points zone\n\n" );
+          break;
+
+        /* Show vectors */
+        case 'v':
+          printf( "freedom    (%04hx,%04hx)\n", exc->GS.freeVector.x,
+                                                exc->GS.freeVector.y );
+          printf( "projection (%04hx,%04hx)\n", exc->GS.projVector.x,
+                                                exc->GS.projVector.y );
+          printf( "dual       (%04hx,%04hx)\n\n", exc->GS.dualVector.x,
+                                                  exc->GS.dualVector.y );
+          break;
+
+        /* Show graphics state */
+        case 'g':
+          printf( "rounding   %s\n", round_str[exc->GS.round_state] );
+          printf( "min dist   %04lx\n", exc->GS.minimum_distance );
+          printf( "cvt_cutin  %04lx\n", exc->GS.control_value_cutin );
+          break;
+
+        /* Show points table */
+        case 'p':
+          for ( A = 0; A < exc->pts.n_points; A++ )
+          {
+            printf( "%02hx  ", A );
+            printf( "%08lx,%08lx - ", pts.org[A].x, pts.org[A].y );
+            printf( "%08lx,%08lx\n",  pts.cur[A].x, pts.cur[A].y );
+          }
+          printf(( "\n" ));
+          break;
+
+        default:
+          key = 1;
+        }
+      } while ( !key );
+
+      MEM_Copy( save.org,   pts.org, pts.n_points * sizeof ( TT_Vector ) );
+      MEM_Copy( save.cur,   pts.cur, pts.n_points * sizeof ( TT_Vector ) );
+      MEM_Copy( save.touch, pts.touch, pts.n_points );
+
+      /* a return indicate the last command */
+      if (ch == '\r')
+        ch = oldch;
+
+      switch ( ch )
+      {
+      /* Quit debugger */
+      case 'q':
+        goto LErrorLabel_;
+
+      /* Step over */
+      case 'n':
+        if ( exc->IP < exc->codeSize )
+        {
+          /* `step over' is equivalent to `step into' except if  */
+          /* the current opcode is a CALL or LOOPCALL            */
+          if ( CUR.opcode != 0x2a && CUR.opcode != 0x2b )
+            goto Step_into;
+
+          /* otherwise, loop execution until we reach the next opcode */
+          next_IP = CUR.IP + CUR.length;
+          while ( exc->IP != next_IP )
+          {
+            if ( ( error = TT_RunIns( exc ) ) )
+              goto LErrorLabel_;
+          }
+        }
+        oldch = ch;
+        break;
+
+      /* Step into */
+      case 's':
+        if ( exc->IP < exc->codeSize )
+
+      Step_into:
+          if ( ( error = TT_RunIns( exc ) ) )
+            goto LErrorLabel_;
+        oldch = ch;
+        break;
+
+      default:
+        printf( "unknown command. Press ? for help\n" );
+        oldch = '\0';
+      }
+
+      for ( A = 0; A < pts.n_points; A++ )
+      {
+        diff = 0;
+        if ( save.org[A].x != pts.org[A].x ) diff |= 1;
+        if ( save.org[A].y != pts.org[A].y ) diff |= 2;
+        if ( save.cur[A].x != pts.cur[A].x ) diff |= 4;
+        if ( save.cur[A].y != pts.cur[A].y ) diff |= 8;
+        if ( save.touch[A] != pts.touch[A] ) diff |= 16;
+
+        if ( diff )
+        {
+          printf( "%02hx  ", A );
+
+          if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx ";
+          printf( temp, save.touch[A] & 7 );
+
+          if ( diff & 1 ) temp = "(%08lx)"; else temp = " %08lx ";
+          printf( temp, save.org[A].x );
+
+          if ( diff & 2 ) temp = "(%08lx)"; else temp = " %08lx ";
+          printf( temp, save.org[A].y );
+
+          if ( diff & 4 ) temp = "(%08lx)"; else temp = " %08lx ";
+          printf( temp, save.cur[A].x );
+
+          if ( diff & 8 ) temp = "(%08lx)"; else temp = " %08lx ";
+          printf( temp, save.cur[A].y );
+
+          printf( "\n" );
+
+          printf( "%02hx  ", A );
+
+          if ( diff & 16 ) temp = "[%01hx]"; else temp = " %01hx ";
+          printf( temp, pts.touch[A] & 7 );
+
+          if ( diff & 1 ) temp = "[%08lx]"; else temp = " %08lx ";
+          printf( temp, pts.org[A].x );
+
+          if ( diff & 2 ) temp = "[%08lx]"; else temp = " %08lx ";
+          printf( temp, pts.org[A].y );
+
+          if ( diff & 4 ) temp = "[%08lx]"; else temp = " %08lx ";
+          printf( temp, pts.cur[A].x );
+
+          if ( diff & 8 ) temp = "[%08lx]"; else temp = " %08lx ";
+          printf( temp, pts.cur[A].y );
+
+          printf( "\n\n" );
+        }
+      }
+    } while ( TRUE );
+
+  LErrorLabel_:
+
+    if (error)
+      Panic( "error during execution" );
+    return error;
+  }
+
+
+
+
+
+  static
+  void Usage()
+  {
+    fprintf( stderr, "ttdebug  -  a simply TrueType font debugger\n" );
+    fprintf( stderr, "(c) The FreeType project - www.freetype.org\n" );
+    fprintf( stderr, "-------------------------------------------\n\n" );
+
+    fprintf( stderr, "usage :   ttdebug  [options]  glyph  size  fontfile[.ttf]\n\n" );
+
+    fprintf( stderr, "    glyph - glyph index within the font file. Can be negative to query \n" );
+    fprintf( stderr, "            the debugging of the font 'cvt' program\n\n" );
+
+    fprintf( stderr, "    size - size of glyph in pixels\n\n" );
+
+    fprintf( stderr, "    fontfile - a valid TrueType file.\n\n" );
+
+    fprintf( stderr, "  valid options are:\n\n" );
+    fprintf( stderr, "    -d    : Dump mode. Shows the glyph program and exit immediately\n" );
+    fprintf( stderr, "    -n    : Non-interactive mode. Dumps the execution trace and exit\n" );
+
+    exit(1);
+  }
+
+
+int    dump_mode;
+int    non_interactive_mode;
+char*  file_name;
+int    glyph_index;
+int    glyph_size;
+
+  int  main( int argc, char**  argv )
+  {
+    char  valid;
+
+    /* Check number of arguments */
+    if ( argc < 4 ) Usage();
+
+    /* Check options */
+    dump_mode            = 0;
+    non_interactive_mode = 0;
+
+    argv++;
+    while (argv[0][0] == '-')
+    {
+      valid = 0;
+      switch (argv[0][1])
+      {
+        case 'd':
+          dump_mode = 1;
+          valid     = 1;
+          break;
+
+        case 'n':
+          non_interactive_mode = 1;
+          valid                = 1;
+          break;
+
+        default:
+          ;
+      }
+
+      if (valid)
+      {
+        argv++;
+        argc--;
+        if (argc < 4) Usage();
+      }
+      else
+        break;
+    }
+
+    /* Get Glyph index */
+    if ( sscanf( argv[0], "%d", &glyph_index ) != 1 )
+    {
+      printf( "invalid glyph index = %s\n", argv[1] );
+      Usage();
+    }
+
+    /* Get Glyph size */
+    if ( sscanf( argv[1], "%d", &glyph_size ) != 1 )
+    {
+      printf( "invalid glyph size = %s\n", argv[1] );
+      Usage();
+    }
+
+    /* Get file name */
+    file_name = argv[2];
+
+    Init_Keyboard();
+
+    /* Init library, read face object, get driver, create size */
+    error = FT_Init_FreeType( &library );
+    if (error) Panic( "could not initialise FreeType library" );
+
+    memory = library->memory;
+    
+    FT_Set_Debug_Hook( library,
+                       FT_DEBUG_HOOK_TRUETYPE,
+                       (FT_DebugHook_Func)RunIns );
+
+    error = FT_New_Face( library, file_name, 0, (FT_Face*)&face );
+    if (error) Panic( "could not open font resource" );
+
+    /* find driver and check format */
+    driver = (TT_Driver)face->root.driver;
+    if (driver->root.interface.init_face != tt_driver_interface.init_face)
+    {
+      error = FT_Err_Invalid_File_Format;
+      Panic( "This is not a TrueType font" );
+    }
+  
+    size = (TT_Size)face->root.size;
+
+    if (glyph_index < 0)
+    {
+      exec = TT_New_Context( face );
+      size->debug   = 1;
+      size->context = exec;
+
+      error = FT_Set_Char_Size( (FT_Face)face, glyph_size << 6, glyph_size << 6, 72, 72 );
+      if (error) Panic( "could not set character sizes" );
+    }
+    else
+    {
+      error = FT_Set_Char_Size( (FT_Face)face, glyph_size << 6, glyph_size << 6, 72, 72 );
+      if (error) Panic( "could not set character sizes" );
+
+      glyph = (TT_GlyphSlot)face->root.glyph;
+
+      /* Now load glyph */
+      error = FT_Load_Glyph( (FT_Face)face, glyph_index, FT_LOAD_DEFAULT );
+      if (error) Panic( "could not load glyph" );
+    }
+
+    Reset_Keyboard();
+    return 0;
+  }
diff --git a/docs/BUILD b/docs/BUILD
new file mode 100644
index 0000000..34ba3e5
--- /dev/null
+++ b/docs/BUILD
@@ -0,0 +1,375 @@
+                       The FreeType Build System Internals
+                       -----------------------------------
+
+Introduction:
+
+  This document describes the details of the FreeType build system. The
+  build system is a set of Makefiles and other configuration files used
+  to select, compile and link together the various FreeType components
+  according to the current platform, compiler and requested feature set.
+
+  This document also explains how to use the build system to develop
+  third-party font drivers or extensions to the engine, without altering
+  the general FreeType hierarchy;
+
+
+I. Portability issues :
+
+  Given that the design of FreeType 2 is much more modular and flexible than
+  in previous versions, its build system is entirely based on GNU Make. There
+  are several reasons for this :
+
+    - It is by far the most available make tool on the planet, and
+      has probably been ported to every development environment known
+      to homo programmaticus.
+
+    - It provides useful features (like conditional defines, pattern
+      and wildcard matching) which are essential when implementing a
+      flexible configuration system, as described below
+
+  Note that you do not need to have a unix-like shell (like "sh" or "csh")
+  on your system in order to build FreeType.
+  
+
+
+
+II. The library design :
+
+  FreeType is made of several components, each with a specific role :
+
+    - THE BASE LAYER:
+      It is used to implement generic font services as well as provide
+      the high-level API used by client applications.
+
+    - ONE OR MORE FONT DRIVERS:
+      Each driver is a small component used to read and process a given
+      font format. Note that with FreeType 2, it is possible to add,
+      remove or upgrade a font driver at *runtime*.
+
+    - ONE OR MORE RASTERS:
+      A raster is a module used to render a vectorial glyph outline into
+      a bitmap or an anti-aliased pixmap. They differ in their output
+      quality, speed and memory usage.
+
+    - A LOW-LEVEL MODULE, CALLED "FTSYSTEM":
+      It is used to implement memory management and file i/o. Uses the
+      Ansi C Library by default, though some system-specific replacements
+      are provided in order to improve performance.
+
+    - AN "INIT" LAYER:
+      A tiny module used to implement the library initialisation routine,
+      i.e. FT_Init_FreeType. It is in charge of registering the font drivers
+      and rasters selected at build time.
+
+    - AN "OLD API" LAYER:
+      A simple layer used to link legacy applications using the FreeType
+      1.x API. Note that it is binary backwards compatible, which means that
+      applications do not need to be recompiled, only re-linked to this
+      layer.
+
+  For more details, please read the "FreeType Internals" Document.      
+
+
+  The FreeType build system is in charge of the following tasks :
+
+    - detect (or select) the current platform in order to select the
+      best version of the "ftsystem" module. By default, it will use
+      the pure-ANSI version.
+
+    - determine which font drivers, and which rasters, should be
+      statically linked to the library at build time. These will always
+      be available after the library has been initialised through a call
+      to FT_Init_FreeType.
+
+    - eventually compile other font drivers or rasters in order to later
+      link them dynamically to the library at runtime, through
+      FT_Add_Driver / FT_Upgrade_Driver..
+
+    - compile the "init" layer, putting code in the implementation of
+      the FT_Init_FreeType function to register each selected font driver
+      or raster to the library.
+
+
+
+III. General overview :
+
+  The FreeType build system uses a hierarchy of included sub-Makefiles
+  to compile and link the library.
+
+  Each included sub-Makefile is called a "rules" file, and has a very
+  specific purpose. The suffix for rules files is ".mk" as in :
+
+       detect.mk
+       config.mk
+       rules.mk
+       etc...
+
+
+  Here's a simple diagram of the build hierarchy, which is then explained
+  with details :
+
+
+
+                       Makefile            ( ./Makefile )
+
+                          |
+                          |
+                          v
+
+                     Config Rules          ( ./config/<system>/config.mk )
+
+                          |
+                          |
+                          v
+
+                    Library  Rules         ( ./config/freetype.mk )
+
+                      |   |   |
+                      |   |   |
+                      v   v   v
+
+                  Component(s) Rules       ( ./src/<component>/rules.mk )
+
+
+
+  1. The "root" Makefile :
+
+     This file must be invoked from the "freetype" directory with GNU Make.
+
+     a. Host platform auto-detection:
+
+       When run for the first time, this Makefile will try to auto-detect
+       the current host platform, by running the rules file named
+       `./config/detect.mk'. If the host system cannot be detected,
+       it will default to the `ansi' system.
+
+       It will then copy the rules file `./config/<system>/config.mk' to
+       the current directory and display the results of the auto-detection.
+
+       You can, at any time, re-run the auto-detection routine by invoking
+       the root Makefile with the "setup" target, as in :
+
+              % make setup
+
+       Note also that it is possible to use a second argument to indicate
+	   a specific compiler. For example, here are the lignes to be used
+	   in order to configure a build with LCC, Visual C++ and Visual Age
+	   on a Win32 machine
+	   
+	          > gmake setup lcc
+			  > gmake setup visualc
+			  > gmake setup visualage
+
+       The list of compilers is platform-specific and should be contained
+	   in `config/<system>/detect.mk'.
+
+       If the detection results do not correspond to your platform or
+       settings, refer to chapter VI which describes the auto-detection
+       system in great details..
+
+
+     b. Building the library:
+
+       Once the host platform has been detected, you can run `make' once
+       again. The root Makefile will then detect the configuration rules
+       file in the current directory then include it.
+
+     Note also that the root Makefile is responsible for defining, if it
+     is not already part of the current environment, the variable TOP, which
+     designates the top of the FreeType source hierarchy.
+
+     When undefined, it defaults to `.'
+
+
+  2. The Configuration file :
+
+     The configuration rules file is used to set many important variables
+     before including/calling the library rules file (see below).
+
+     These variables are mainly used to describe the host environment
+     and compilers. Indeed, this file defines, among others, the following:
+
+       SEP     The directory path separator. This can be `/',`\' or ':'
+               depending on the current platform. Note that all pathnames
+               are composed with $(SEP) in all rules file (except in
+               `include' statements which work well with '/' on all
+               platforms)
+
+       CC      The compiler to use
+
+       CFLAGS  The compiler flags used to compile a given source to an
+               object file. Usually contains flags for optimisation,
+               debugging and/or ansi-compliance
+
+       I       The flag to be used to indicate an additionnal include path
+               to the compiler. This defaults to `-I' for an "ansi" system,
+               but can be different for others (e.g. `/i=',`-J ', etc..)
+
+       D       The flag to be used to indicate a macro definition to the
+               compiler. This defaults to `-D' for an ANSI system.
+
+       T       The flag to be used to indicate a target object file to the
+               compiler. This defaults to `-o ' for an ANSI system. Note the
+               space after the `o'.        
+
+       O       The object file extension to be used on the current platform.
+               Defaults to `o' for an ANSI system, but can be `obj', `coff'
+               or others.. There is no dot in the extension !
+
+       A       The library file extension to be used on the current platform.
+               Defaults to 'a' for an ANSI system, but can be `lib', `so',
+               `dll' or others.. There is no dot in the extension !
+
+
+       BUILD   The directory where the build system should grab the
+               configuration header file `ftconfig.h' as well as the
+               system-specific implementation of `ftsystem'.
+
+       OBJ     The directory where all object files will be placed
+
+
+  3. The Library Rules files :
+
+     Once the variables defined in the configuration rules file, the
+     library rules file is included. This one contains all rules required
+     to build the library objects into OBJ
+
+     Its structure works as follows:
+
+       - provide rules to compile the low-level `ftsystem' module
+
+       - include the rules files from each font driver or component
+
+       - include the rules file for the "old api" layer
+
+       - provide rules to compile the initialisation layer
+
+       - provide additional targets like `clean', ..
+
+
+     Note that linking all objects files together into a library is not
+     performed in this file, though it might seem reasonable at first
+     glance. The reason for this is that not all linkers have a simple
+     syntax of the form:
+
+         librarian archive_file  object1 object2 ....
+
+     hence, linking is performed through rules provided in the configuration
+     rules file, using the phony `library' target, which has been defined for
+     this very specific purpose.
+
+
+  4. The Components Rules files :
+
+     Each font driver has its own rules file, called `rules.mk' located
+     in its own directory. The library rules file includes these component
+     rules for each font driver.
+
+     These rules must perform the following:
+
+       - provide rules to compile the component, either into a single `large'
+         object, or into multiple small ones
+
+       - for font drivers and rasters, update some variables, that are
+         initially defined in the library rules file, which indicate wether
+         the component must be registered in the library initialisation code
+
+
+     a. Component Compile Modes :     
+
+       There are two ways to compile a given component :
+
+         i. Single-object compilation:
+
+            In this mode, the component is compiled into a single object
+            file. This is performed easily by defining a single C file whose
+            sole purpose is to include all other component sources. For
+            example, the truetype driver is compiled as a single object
+            named `truetype.o'.
+
+
+         ii. Multiple objects compilation:
+
+            In this mode, all source files for a single component are compiled
+            individually into an object file.
+
+       Due to the way the FreeType source code is written, single mode
+       has the following advantages over multiple mode:
+
+         - with many compilers, the resulting object code is smaller than
+           the concatenation of all individual objects from multiple mode.
+           this, because all functions internal to the component as a whole
+           are declared static, allowing more optimisation. It often also
+           compiles much faster.
+
+
+         - most importantly, the single object only contains the external
+           symbols it needs to be linked to the base layer (all extern that
+           are due to inter-source calls within the component are removed).
+           this can reduce tremendously the size of dynamic libraries on
+           some platforms
+
+       Multiple mode is useful however to check some dependencies problems
+       that might not appear when compiling in single mode, so it has been
+       kept as a possibility.
+
+
+     b. Driver initialisation code :
+
+       The source file `./src/base/ftinit.c' contains the implementation
+       of the FT_Init_FreeType function which must, among other things,
+       register all font drivers that are statically linked to the library.
+
+       Controlling which drivers are registered at initialisation time is
+	   performed by exploiting the state of the C-preprocessor in order to
+	   build a linked list (a "chain") of driver interfaces.
+
+       More precisely, each font driver interface file (like `ttdriver.h'
+	   or `t1driver.h') has some special lines that look like this :
+	   
+  			
+    			#ifdef FTINIT_DRIVER_CHAIN
+ 			
+    			static
+    			const FT_DriverChain  ftinit_<FORMAT>_driver_chain =
+    			{
+      			FT_INIT_LAST_DRIVER_CHAIN,
+      			&<FORMAT>_driver_interface
+    			};
+  			
+    			#undef  FT_INIT_LAST_DRIVER_CHAIN
+    			#define FT_INIT_LAST_DRIVER_CHAIN   &ftinit_<FORMAT>_driver_chain
+ 			
+    			#endif 
+				
+  		As one can see, this code is strictly reserved for `ftinit.c' which
+		defines FTINIT_DRIVER_CHAIN before including all font driver header
+		files.
+		
+		When the C-processor parses these headers, it builds a linked list of
+		FT_DriverChain element. For exemple, the sequence :
+		
+		   #define FTINIT_DRIVER_CHAIN
+		   #include <ttdriver.h>
+		   #include <t1driver.h>
+		   
+		Will really generate something like:
+		
+    			static
+    	*---->	const FT_DriverChain  ftinit_tt_driver_chain =
+    	|		{
+      	|		0,
+      	|		&tt_driver_interface
+    	|		};
+  		|	
+    	|		static
+    	|		const FT_DriverChain  ftinit_t1_driver_chain =
+    	|		{
+      	*------	&ftinit_tt_driver_chain,
+      			&t1_driver_interface
+    			};
+ 	   
+	   with the FT_INIT_LAST_DRIVER_CHAIN set to "&ftinit_t1_driver_chain"
+	   
+	   Hence, the last included driver will be registered first in the library
+	   
diff --git a/docs/DESIGN b/docs/DESIGN
new file mode 100644
index 0000000..b939362
--- /dev/null
+++ b/docs/DESIGN
@@ -0,0 +1,216 @@
+The Design of FreeType 2.0
+==========================
+
+Introduction:
+
+  This short document presents the design of version 2 of the FreeType
+  library. It is a must read for anyone willing to port, debug or hack
+  the FreeType sources.
+
+
+I. Goals :
+
+  FreeType 2 was designed to provide a unified and universal API to
+  manage (i.e. read) the content of font files.
+
+  Its main features are :
+
+
+    - A FORMAT-INDEPENDENT HIGH-LEVEL API
+
+        Used to open, read and manage font files.
+
+
+    - THE USE OF PLUGGABLE "FONT DRIVERS"
+
+        Each font driver is used to support a given font format. For
+        example, the default build of FreeType 2 comes with drivers for the
+        TrueType and Type 1 font formats.
+
+        Font drivers can also be added, removed or upgraded at *runtime*,
+        in order to support more font formats, or improve the current ones.
+
+        Each font driver also provides its own "public interface" to client
+        applications who would like to use format-specific features.
+
+   
+    - THE USE OF PLUGGABLE "RASTERS"
+
+        A raster is a tiny module used to render a glyph image
+        into a bitmap or anti-aliased pixmap. Rasters differ in their
+        output quality (especially with regards to anti-aliasing), speed
+        and memory usage.
+
+        An application can also provide its own raster if it needs to.
+
+        
+    - HIGH PORTABILITY AND PERFORMANCE
+
+        The FreeType source code is written in industry-standard ANSI C.
+
+        Moreover, it abstracts memory management and i/o operations within
+        a single module, called "ftsystem". The FreeType build system tries
+        to auto-detect the host platform in order to select its most
+        efficient implementation. It defaults otherwise to using the
+        standard ANSI C Library.
+        
+        Note that, independently of the host platform and build, an
+        application is able to provide its own memory and i/o routines.
+
+        This make FreeType suitable for use in any kind of environment,
+        from embedded to distributed systems.
+
+
+II. Components Layout :
+
+  FreeType 2 is made of distinct components which relate directly to the
+  design described previously:
+
+
+  1. THE BASE LAYER:
+
+     The base layer implements the high-level API, as well as provide
+     generic font services that can be used by each font driver.
+     
+
+  2. THE FONT DRIVERS:
+
+     Each font driver can be registered in the base layer by providing
+     an "interface", which really is a table of function pointers.
+
+     At build time, the set of default font drivers is selected. These
+     drivers are then compiled and statically linked to the library.
+
+     They will then be available after the library initialisation.
+
+
+  3. THE RASTERS:
+
+     FreeType 2 provides the ability to hook various raster modules into
+     its base layer. This provides several advantages :
+
+       - different systems mean different requirements, hence the need for
+         flexibility.
+
+       - for now, FreeType 2 only supports glyph images stored in the
+         following formats :
+
+           * bitmaps
+           * gray-level pixmaps
+           * monochrome vectorial outlines (using bezier control points)
+
+         should a new "technology" come for glyph images, it is possible
+         to write a new raster for it, without altering the rest of the
+         engine. Some examples could be :
+
+           * multi-colored vectorial outlines
+           * on-the-fly rendering of TeX's MetaFonts !!
+
+
+
+  4. THE SYSTEM MODULE "FTSYSTEM":
+
+     The system module is used to implement basic memory and i/o management
+     services. By default, it uses the ANSI C library, but some replacements
+     are also provided (and automatically selected by the build system) when
+     available.
+
+     As a simple example, the unix build uses memory-mapped files to read
+     font files, instead of the slow ANSI "fopen/fseek/fread". This results
+     in tremendous performance enhancements.
+
+     Note that, even if the build system chooses an implementation for
+     "ftsystem" at compile time, an application is still able to provide
+     its own memory or i/o routines to the library at runtime.
+
+
+
+
+  5. THE "INIT" LAYER:
+
+     A tiny module used to implement the function FT_Init_FreeType.
+
+     As its name suggests, it is responsible for initialising the library,
+     which really means the following :
+
+        - bind the implementation of "ftsystem" that best matches the
+          host platform to the library. This choice can be overriden
+          later by client applications however.
+
+        - register the set of default font drivers within the base layer.
+          these drivers are statically linked to the library. Other drivers
+          can be added at runtime later through FT_Add_Driver though..
+
+        - register the set of default rasters. Client applications are
+          able to add their own rasters at runtime though.
+
+     The details regarding these operations is given in the document
+     named "FreeType Build Internals"
+
+
+
+III. Objects Layout :
+
+  Even though it is written in ANSI C, the desing of FreeType 2 is object
+  oriented, as it's the best way to implement the flexible font format
+  support that we wanted.
+
+  Indeed, the base layer defines a set of base classes that can be derived
+  by each font driver in order to support a given format. The base layer
+  also includes many book-keeping routines that need not be included in the
+  drivers.
+
+  The base classes are the following:
+
+
+  1. FACE OBJECTS:
+
+    As in FreeType 1.x, a face object models the content of a given font
+    that isn't dependent on a given size, transformation or glyph index.
+
+    This includes, for example, the font name, font style(s), available
+    charmaps and encodings, and all other kinds of data and tables that
+    help describe the font as a whole.
+
+
+  2. SIZE OBJECTS: (previously known as INSTANCE OBJECTS in 1.x)
+
+    A face object can have one or more associated size objects. A Size
+    object is used to stored the font data that is dependent on the current
+    character size or transform used to load glyphs.
+
+    Typical data in a size object include scaled metrics, factors, and
+    various kind of control data related to grid-fitting. The size object
+    is changed each time the character size is modified.
+
+
+  3. GLYPH SLOT OBJECTS:
+
+    Each face object has one "glyph slot", which is a simple container
+    where individual glyph images can be loaded and processed.
+
+    The glyph image can be stored in the following formats in the glyph
+    slot :
+
+        - monochrome bitmaps
+        - gray-level pixmaps
+        - vectorial glyph outlines (defined with bezier control points)
+
+    Note that a module, called the "raster" is provided to convert vector
+    outlines into either monochrome or anti-aliased bitmaps. The outline
+    is also directly accessible and can be walked or processed freely by
+    client applications.
+
+    more glyph images formats can be defined, but they will require
+    a specific raster module if one wants to display them on a typical
+    display surface.
+
+  4. CHARMAP OBJECTS:
+
+    A charmap is used to convert character codes, for a given encoding,
+    into glyph indices. A given face might contain several charmaps, for
+    example, most TrueType fonts contain both the "Windows Unicode" and
+    "
+    it is not rare to see TrueType fonts with both the
+    "Windows Unicode" and "Apple Roman" charmap
+
diff --git a/docs/essai b/docs/essai
new file mode 100644
index 0000000..fca6338
--- /dev/null
+++ b/docs/essai
@@ -0,0 +1,173 @@
+Un apercu du layout des fichiers sources de FreeType 2:
+
+  docs/            - documentation
+      html/        - documentation au format html
+      
+      txt/         - documentation au format texte
+    
+    
+  include/         - les headers publiques de la librairie, ce sont ceux
+                     qui sont installes avec le paquet freetype-devel.rpm
+
+  config/          - le repertoire de configuration.
+      ansi/       
+        ft_conf.h  - fichier de configuration
+	ftsys.c    - fichier implementation bas-niveau
+
+      unix/
+      
+      os2/
+      
+      dos/
+      
+      amiga/
+      
+      debug/
+      
+      
+  src/              - sources de la librairie
+      base/         - couche de base (services generiques + API)
+      
+      truetype/     - pilote truetype
+          options/  - options du pilote truetype
+          extend/   - extensions du pilote truetype
+      
+      type1/        - pilote type 1
+          options/  - options du pilote type 1
+	  extend/   - extensions du pilote type 1
+      
+      type2/        - pilote type 2
+      
+      speedo/       - pilote speedo
+      
+      shared/       - sources partagees par plusieurs pilotes
+      
+
+  tests/            - programmes de test
+      data/         - donnees des tests = fichiers de police => copies dans bin
+      test1/        - source du test numero 1
+      test2/        - source du test numero 2
+      test3/        - ...
+      ...
+
+  obj/              - emplacement des fichiers objets compiles + librairie ?
+  bin/              - emplacement des executables (demos+tests)
+  
+  demos/            - programmes de demonstration
+      graph/        - sous-systeme graphique des programmes de demo
+      
+  
+  contrib/          - contributions de toutes sortes..
+
+
+=============================================================================
+Quelques autres idees au hasard :
+
+- virer le controle des threads, on s'en tape magistralement
+
+- separer l'allocation memoire de l'acces disque (+flexible)
+
+- l'api de base doit permettre "d'ouvrir" un fichier de police se trouvant
+  deja en memoire..  
+  
+- expliquer les differents types de dictionnaires :
+
+    char_code    ->  glyph_index         charmap    (truetype)
+    char_code    ->  glyph_name          encoding   (type 1)
+    glyph_index  ->  glyph_name          repertoire (...)
+
+- plusieurs "raster" possibles (le raster par defaut peut etre déterminé à la compilation,
+  sinon l'ajout se fait simplement en passant un pointeur d'interface..)
+
+
+- l'api de base doit etre simplifiee. La plupart des developpeurs ne veulent
+  pas savoir ce qu'est une "size", un "glyph_slot", etc.., on conseille donc
+  d'en creer une par defaut, lors de l'appel de :
+  
+     ------------------- initialisation et lecture des polices ------------
+  
+     FT_Init_FreeType( &library );
+     
+     FT_Set_Memory_Manager( library, &mem_manager_rec );
+     
+     FT_Set_IO_Manager( library, &io_manager_rec );
+  
+  
+     FT_New_Face( library, file_pathname, face_index, &face );
+     
+     FT_New_Memory_Face( library, first_byte, length, face_index, &face );
+
+     ou encore:
+     
+       FT_New_Face( library, &new_face_rec, &face );
+       
+       avec new_face_rec ::
+       
+          face_index
+       
+          pathname
+	  
+	  memory_address
+	  bytes_size
+     
+
+     FT_Flush_Face( face );   // ferme le stream correspondant..
+
+
+     ------------------------------------------ changement de taille ------
+     
+     FT_Set_Size( face, &face_size_rec );
+     
+       face_size_rec ::
+         char_height
+	 char_width
+	 horz_resolution
+	 vert_resolution
+     
+     FT_Set_Pixel_Sizes( face, 64, 64 );
+
+
+     ----------------------------------------- selection de la charmap ----
+     
+     FT_Select_Charmap( face, ft_charmap_unicode );
+     
+     FT_Select_Charmap_Index( face, index );
+     
+     FT_List_Charmaps( face, buffer, max, first );
+
+     face->charmap => pointe vers la charmap actuelle..
+
+
+     -------------------------------------- chargement des glyphes --------
+     
+     FT_Load_Glyph( face, glyph_index ); 
+     
+     FT_Load_Char( face, char_code );
+     
+     FT_Transform_Glyph( face->glyph, &trans );
+     
+     
+     ---------------------------------------------- rendu final -----------
+     
+     FT_Get_Outline_Bitmap( library, face->glyph, &bit );
+     
+     FT_Set_Raster( library, "default" );
+     
+     FT_Set_Raster_Mode( library, major_mode, minor_mode );
+     
+     
+     
+     
+=======================================================================================
+
+Système de configuration automatique
+
+ freetype2/
+     Makefile
+     config/
+         ansi/
+            config.mk
+
+  make setup  => autodetection du système + copie de fichier include ???
+
+  make
diff --git a/docs/glyph_conventions/bbox1.gif b/docs/glyph_conventions/bbox1.gif
new file mode 100644
index 0000000..b173caa
--- /dev/null
+++ b/docs/glyph_conventions/bbox1.gif
Binary files differ
diff --git a/docs/glyph_conventions/bbox2.gif b/docs/glyph_conventions/bbox2.gif
new file mode 100644
index 0000000..5076556
--- /dev/null
+++ b/docs/glyph_conventions/bbox2.gif
Binary files differ
diff --git a/docs/glyph_conventions/body_comparison.gif b/docs/glyph_conventions/body_comparison.gif
new file mode 100644
index 0000000..c682e31
--- /dev/null
+++ b/docs/glyph_conventions/body_comparison.gif
Binary files differ
diff --git a/docs/glyph_conventions/bravo_kerned.gif b/docs/glyph_conventions/bravo_kerned.gif
new file mode 100644
index 0000000..b71350c
--- /dev/null
+++ b/docs/glyph_conventions/bravo_kerned.gif
Binary files differ
diff --git a/docs/glyph_conventions/bravo_unkerned.gif b/docs/glyph_conventions/bravo_unkerned.gif
new file mode 100644
index 0000000..db5f34e
--- /dev/null
+++ b/docs/glyph_conventions/bravo_unkerned.gif
Binary files differ
diff --git a/docs/glyph_conventions/build_diagram.gif b/docs/glyph_conventions/build_diagram.gif
new file mode 100644
index 0000000..bda9855
--- /dev/null
+++ b/docs/glyph_conventions/build_diagram.gif
Binary files differ
diff --git a/docs/glyph_conventions/clipping.gif b/docs/glyph_conventions/clipping.gif
new file mode 100644
index 0000000..d28f701
--- /dev/null
+++ b/docs/glyph_conventions/clipping.gif
Binary files differ
diff --git a/docs/glyph_conventions/down_flow.gif b/docs/glyph_conventions/down_flow.gif
new file mode 100644
index 0000000..83b2b7c
--- /dev/null
+++ b/docs/glyph_conventions/down_flow.gif
Binary files differ
diff --git a/docs/glyph_conventions/glyph_conventions.html b/docs/glyph_conventions/glyph_conventions.html
new file mode 100644
index 0000000..54cccc1
--- /dev/null
+++ b/docs/glyph_conventions/glyph_conventions.html
@@ -0,0 +1,1626 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="blob">
+   <meta name="GENERATOR" content="Mozilla/4.5 [fr] (Win98; I) [Netscape]">
+   <title>FreeType Glyph Conventions</title>
+</head>
+<body>
+
+<body text="#000000"
+      bgcolor="#FFFFFF"
+      link="#0000EF"
+      vlink="#51188E"
+      alink="#FF0000">
+
+<center>
+<h1>
+FreeType Glyph Conventions</h1></center>
+
+<center>
+<h2>
+version 2.0</h2></center>
+
+<center>
+<h3>
+Copyright 1998-1999David Turner (<a href="mailto:david@freetype.org">david@freetype.org</a>)<br>
+Copyright 1999 The FreeType Development Team (<a href="devel@freetype.org">devel@freetype.org</a>)</h3></center>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+Introduction</h2>
+
+<blockquote>This document discusses in great details the definition of
+various concepts related to digital typography, as well as a few specific
+to the FreeType library. It also explains the ways typographic information,
+like glyph metrics, kerning distances, etc.. is to be managed and used.
+It relates to the layout and display of text strings, either in a conventional
+(i.e. Roman) layout, or with right-to-left or vertical ones. Some aspects
+like rotation and transformation are explained too.
+<p>Comments and corrections are highly welcomed, and can be sent to the
+<a href="devel@freetype.org">FreeType
+developers list</a>.</blockquote>
+
+<hr WIDTH="100%">
+<h2>
+I. Basic typographic concepts</h2>
+
+<blockquote>
+<h3>
+1. Font files, format and information</h3>
+
+<blockquote>A font is a collection of various character images that can
+be used to display or print text. The images in a single font share some
+common properties, including look, style, serifs, etc.. Typographically
+speaking, one has to distinguish between a <b>font family</b> and its multiple
+<b>font
+faces</b>, which usually differ in style though come from the same template.
+For example, "<i>Palatino Regular</i>" and "<i>Palatino Italic</i>" are
+two distinct <i>faces</i> from the same famous <i>family</i>, called "<i>Palatino</i>"
+itself.
+<p>The single term font is nearly always used in ambiguous ways to refer
+to either a given family or given face, depending on the context. For example,
+most users of word-processors use "font" to describe a font family (e.g.
+Courier, Palatino, etc..); however most of these families are implemented
+through several data files depending on the file format : for TrueType,
+this is usually one per face (i.e. ARIAL.TFF for "Arial Regular", ARIALI.TTF
+for "Arial Italic", etc..). The file is also called a "font" but really
+contains a font face.
+<p>A <i>digital font</i> is thus a data file that may contain <i>one or
+more font faces</i>. For each of these, it contains character images, character
+metrics, as well as other kind of information important to the layout of
+text and the processing of specific character encodings. In some awkward
+formats, like Adobe Type1, a single font face is described through several
+files (i.e. one contains the character images, another one the character
+metrics). We will ignore this implementation issue in most of this document
+and consider digital fonts as single files, though FreeType 2.0 is able
+to support multiple-files fonts correctly.
+<p>As a convenience, a font file containing more than one face is called
+a font collection. This case is rather rare but can be seen in many asian
+fonts, which contain images for two or more scripts for a given language.</blockquote>
+
+<h3>
+2. Character images and mappings :</h3>
+
+<blockquote>The character images are called <b>glyphs</b>. A single character
+can have several distinct images, i.e. several glyphs, depending on script,
+usage or context. Several characters can also take a single glyph (good
+examples are roman ligatures like "oe" and "fi" which can be represented
+by a single glyph like "œ" and "?"). The relationships between characters
+and glyphs can be a very complex one but won't be detailed in this document.
+Moreover, some formats use more or less awkward schemes to store and access
+the glyphs. For the sake of clarity, we'll only retain the following notions
+when working with FreeType :
+<br>&nbsp;
+<ul>
+<li>
+A font file contains a set of glyphs, each one can be stored as a bitmap,
+a vector representation or any other scheme (e.g. most scalable formats
+use a combination of math representation and control data/programs). These
+glyphs can be stored in any order in the font file, and is typically accessed
+through a simple glyph index.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<ul>
+<ul>
+<ul>
+<li>
+The font file contains one (or more) table, called a character map (or
+charmap in short), which is used to convert character codes for a given
+encoding (e.g. ASCII, Unicode, DBCS, Big5, etc..) into glyph indexes relative
+to the font file. A single font face may contain several charmaps. For
+example, most TrueType fonts contain an Apple-specific charmap as well
+as a Unicode charmap, which makes them usable on both Mac and Windows platforms.</li>
+</ul>
+</ul>
+
+<h3>
+3. Character and font metrics :</h3>
+
+<ul>Each glyph image is associated to various metrics which are used to
+describe the way it must be placed and managed when rendering text. Though
+they are described in more details in section III, they relate to glyph
+placement, cursor advances as well as text layouts. They are extremely
+important to compute the flow of text when rendering string of text.
+<p>Each scalable format also contains some global metrics, expressed in
+notional units, used to describe some properties of all glyphs in a same
+face. For example : the maximum glyph bounding box, the ascender, descender
+and text height for the font.
+<p>Though these metrics also exist for non-scalable formats, they only
+apply for a set of given character dimensions and resolutions, and they're
+usually expressed in pixels then.</ul>
+</ul>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+II. Glyph Outlines</h2>
+
+<blockquote>This section describes the vectorial representation of glyph
+images, called outlines.
+<br>&nbsp;
+<h3>
+1. Pixels, Points and Device Resolutions :</h3>
+
+<blockquote>Though it is a very common assumption when dealing with computer
+graphics programs, the physical dimensions of a given pixel (be it for
+screens or printers) are not squared. Often, the output device, be it a
+screen or printer exhibits varying resolutions in the horizontal and vertical
+directions, and this must be taken care of when rendering text.
+<p>It is thus common to define a device's characteristics through two numbers
+expressed in <b>dpi</b> (dots per inch). For example, a printer with a
+resolution of 300x600 dpi has 300 pixels per inch in the horizontal direction,
+and 600 in the vertical one. The resolution of a typical computer monitor
+varies with its size (a 15" and 17" monitors don't have the same pixel
+sizes at 640x480), and of course the graphics mode resolution.
+<p>As a consequence, the size of text is usually given in <b>points</b>,
+rather than device-specific pixels. Points are a simple <i>physical</i>
+unit, where 1 point = 1/72th of an inch, in digital typography. As an example,
+most roman books are printed with a body text which size is chosen between
+10 and 14 points.
+<p>It is thus possible to compute the size of text in pixels from the size
+in points through the following computation :
+<center>
+<p><tt>pixel_size = point_size * resolution / 72</tt></center>
+
+<p>Where resolution is expressed in dpi. Note that because the horizontal
+and vertical resolutions may differ, a single point size usually defines
+different text width and height in pixels.
+<br>&nbsp;
+<p><b>IMPORTANT NOTE:</b>
+<br><i>Unlike what is often thought, the "size of text in pixels" is not
+directly related to the real dimensions of characters when they're displayed
+or printed. The relationship between these two concepts is a bit more complex
+and relate to some design choice made by the font designer. This is described
+in more details the next sub-section (see the explanations on the EM square).</i></blockquote>
+
+<h3>
+2. Vectorial representation :</h3>
+
+<blockquote>The source format of outlines is a collection of closed paths
+called <b>contours</b>. Each contour delimits an outer or inner <i>region</i>
+of the glyph, and can be made of either <b>line segments</b> or <b>bezier
+arcs</b>.
+<p>The arcs are defined through <b>control points</b>, and can be either
+second-order (these are "conic beziers") or third-order ("cubic" beziers)
+polynomials, depending on the font format. Hence, each point of the outline
+has an associated <b>flag</b> indicating its type (normal or control point).
+And scaling the points will scale the whole outline.
+<p>Each glyph's original outline points are located on a grid of indivisible
+units. The points are usually stored in a font file as 16-bit integer grid
+coordinates, with the grid origin's being at (0,0); they thus range from
+-16384 to 16383. (even though point coordinates can be floats in other
+formats such as Type 1, we'll restrict our analysis to integer ones, driven
+by the need for simplicity..).
+<p><b>IMPORTANT NOTE:</b>
+<br><i>The grid is always oriented like the traditional mathematical 2D
+plane, i.e. the X axis from the left to the right, and the Y axis from
+bottom to top.</i>
+<p>In creating the glyph outlines, a type designer uses an imaginary square
+called the "EM square". Typically, the EM square can be thought of as a
+tablet on which the character are drawn. The square's size, i.e., the number
+of grid units on its sides, is very important for two reasons:
+<br>&nbsp;
+<blockquote>
+<li>
+it is the reference used to scale the outlines to a given text dimension.
+For example, a size of 12pt at 300x300 dpi corresponds to 12*300/72 = 50
+pixels. This is the size the EM square would appear on the output device
+if it was rendered directly. In other words, scaling from grid units to
+pixels uses the formula:</li>
+</blockquote>
+
+<center><tt>pixel_size = point_size * resolution / 72</tt>
+<br><tt>pixel_coordinate = grid_coordinate * pixel_size / EM_size</tt></center>
+
+<blockquote>
+<li>
+the greater the EM size is, the larger resolution the designer can use
+when digitizing outlines. For example, in the extreme example of an EM
+size of 4 units, there are only 25 point positions available within the
+EM square which is clearly not enough. Typical TrueType fonts use an EM
+size of 2048 units (note: with Type 1 PostScript fonts, the EM size is
+fixed to 1000 grid units. However, point coordinates can be expressed in
+floating values).</li>
+</blockquote>
+Note that glyphs can freely extend beyond the EM square if the font designer
+wants so. The EM is used as a convenience, and is a valuable convenience
+from traditional typography.
+<center>
+<p><b>Note : Grid units are very often called "font units" or "EM units".</b></center>
+
+<p><b>NOTE:</b>
+<br><i>As said before, the pixel_size computed in&nbsp; the above formula
+does not relate directly to the size of characters on the screen. It simply
+is the size of the EM square if it was to be displayed directly. Each font
+designer is free to place its glyphs as it pleases him within the square.
+This explains why the letters of the following text have not the same height,
+even though they're displayed at the same point size with distinct fonts
+:</i>
+<center>
+<p><img SRC="body_comparison.gif" height=40 width=580></center>
+
+<p>As one can see, the glyphs of the Courier family are smaller than those
+of Times New Roman, which themselves are slightly smaller than those of
+Arial, even though everything is displayed or printed&nbsp; at a size of
+16 points. This only reflect design choices.
+<br>&nbsp;</blockquote>
+
+<h3>
+3. Hinting and Bitmap rendering</h3>
+
+<blockquote>The outline as stored in a font file is called the "master"
+outline, as its points coordinates are expressed in font units. Before
+it can be converted into a bitmap, it must be scaled to a given size/resolution.
+This is done through a very simple transform, but always creates undesirable
+artifacts, e.g. stems of different widths or heights in letters like "E"
+or "H".
+<p>As a consequence, proper glyph rendering needs the scaled points to
+be aligned along the target device pixel grid, through an operation called
+"grid-fitting", and often "hinting". One of its main purpose is to ensure
+that important widths and heights are respected throughout the whole font
+(for example, it is very often desirable that the "I" and the "T" have
+their central vertical line of the same pixel width), as well as manage
+features like stems and overshoots, which can cause problems at small pixel
+sizes.
+<p>There are several ways to perform grid-fitting properly, for example
+most scalable formats associate some control data or programs with each
+glyph outline. Here is an overview :
+<br>&nbsp;
+<blockquote>
+<blockquote><b>explicit grid-fitting :</b>
+<blockquote>The TrueType format defines a stack-based virtual machine,
+for which programs can be written with the help of more than 200 opcodes
+(most of these relating to geometrical operations). Each glyph is thus
+made of both an outline and a control program, its purpose being to perform
+the actual grid-fitting in the way defined by the font designer.</blockquote>
+
+<p><br><b>implicit grid-fitting (also called hinting) :</b>
+<blockquote>The Type 1 format takes a much simpler approach : each glyph
+is made of an outline as well as several pieces called "hints" which are
+used to describe some important features of the glyph, like the presence
+of stems, some width regularities, and the like. There aren't a lot of
+hint types, and it's up to the final renderer to interpret the hints in
+order to produce a fitted outline.</blockquote>
+
+<p><br><b>automatic grid-fitting :</b>
+<blockquote>Some formats simply include no control information with each
+glyph outline, apart metrics like the advance width and height. It's then
+up to the renderer to "guess" the more interesting features of the outline
+in order to perform some decent grid-fitting.</blockquote>
+</blockquote>
+</blockquote>
+
+<center>
+<p><br>The following table summarises the pros and cons of each scheme
+:</center>
+</blockquote>
+
+<center><table BORDER=0 WIDTH="80%" BGCOLOR="#CCCCCC" >
+<tr BGCOLOR="#999999">
+<td>
+<blockquote>
+<center><b><font color="#000000">Grid-fitting scheme</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Pros</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Cons</font></b></center>
+</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote>
+<center><b><font color="#000000">Explicit</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Quality</font></b>
+<br><font color="#000000">excellence at small sizes is possible. This is
+very important for screen display.</font>
+<p><b><font color="#000000">Consistency</font></b>
+<br><font color="#000000">all renderers produce the same glyph bitmaps.</font></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Speed</font></b>
+<br><font color="#000000">intepreting bytecode can be slow if the glyph
+programs are complex.</font>
+<p><b><font color="#000000">Size</font></b>
+<br><font color="#000000">glyph programs can be long</font>
+<p><b><font color="#000000">Technicity</font></b>
+<br><font color="#000000">it is extremely difficult to write good hinting
+programs. Very few tools available.</font></center>
+</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote>
+<center><b><font color="#000000">Implicit</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Size</font></b>
+<br><font color="#000000">hints are usually much smaller than explicit
+glyph programs.</font>
+<p><b><font color="#000000">Speed</font></b>
+<br><font color="#000000">grid-fitting is usually a fast process</font></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Quality</font></b>
+<br><font color="#000000">often questionable at small sizes. Better with
+anti-aliasing though.</font>
+<p><b><font color="#000000">Inconsistency</font></b>
+<br><font color="#000000">results can vary between different renderers,
+or even distinct versions of the same engine.</font></center>
+</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote>
+<center><b><font color="#000000">Automatic</font></b></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Size</font></b>
+<br><font color="#000000">no need for control information, resulting in
+smaller font files.</font>
+<p><b><font color="#000000">Speed</font></b>
+<br><font color="#000000">depends on the grid-fitting algo.Usually faster
+than explicit grid-fitting.</font></center>
+</blockquote>
+</td>
+
+<td>
+<blockquote>
+<center><b><font color="#000000">Quality</font></b>
+<br><font color="#000000">often questionable at small sizes. Better with
+anti-aliasing though</font>
+<p><b><font color="#000000">Speed</font></b>
+<br><font color="#000000">depends on the grid-fitting algo.</font>
+<p><b><font color="#000000">Inconsistency</font></b>
+<br><font color="#000000">results can vary between different renderers,
+or even distinct versions of the same engine.</font></center>
+</blockquote>
+</td>
+</tr>
+</table></center>
+</blockquote>
+
+<hr WIDTH="100%">
+<h2>
+III. Glyph metrics</h2>
+
+<blockquote>
+<h3>
+1. Baseline, Pens and Layouts</h3>
+The baseline is an imaginary line that is used to "guide" glyphs when rendering
+text. It can be horizontal (e.g. Roman, Cyrillic, Arabic, etc.) or vertical
+(e.g. Chinese, Japanese, Korean, etc). Moreover, to render text, a virtual
+point, located on the baseline, called the "pen position" or "origin",
+is used to locate glyphs.
+<p>Each layout uses a different convention for glyph placement:
+<br>&nbsp;
+<blockquote>
+<li>
+with horizontal layout, glyphs simply "rest" on the baseline. Text is rendered
+by incrementing the pen position, either to the right or to the left.</li>
+</blockquote>
+</blockquote>
+
+<ul>
+<ul>the distance between two successive pen positions is glyph-specific
+and is called the "advance width". Note that its value is _always_ positive,
+even for right-to-left oriented alphabets, like Arabic. This introduces
+some differences in the way text is rendered.
+<p>IMPORTANT NOTE:&nbsp; The pen position is always placed on the baseline.</ul>
+
+<center><img SRC="Image1.gif" height=179 width=458></center>
+
+<ul>
+<li>
+with a vertical layout, glyphs are centered around the baseline:</li>
+</ul>
+
+<center><img SRC="Image2.gif" height=275 width=162></center>
+
+<p><br>
+<h3>
+2. Typographic metrics and bounding boxes</h3>
+
+<ul>A various number of face metrics are defined for all glyphs in a given
+font.
+<p><b>the ascent</b>
+<ul>this is the distance from the baseline to the highest/upper grid coordinate
+used to place an outline point. It is a positive value, due to the grid's
+orientation with the Y axis upwards.</ul>
+
+<p><br><b>the descent</b>
+<ul>the distance from the baseline to the lowest grid coordinate used to
+place an outline point. This is a negative value, due to the grid's orientation.</ul>
+
+<p><br><b>the linegap</b>
+<ul>the distance that must be placed between two lines of text. The baseline-to-baseline
+distance should be computed as:
+<center>
+<p><tt>ascent - descent + linegap</tt></center>
+if you use the typographic values.</ul>
+Other, simpler metrics are:
+<p><b>the glyph's bounding box</b>, also called "<b>bbox</b>"
+<ul>this is an imaginary box that encloses all glyphs from the font, as
+tightly as possible. It is represented by four fields, namely <tt>xMin</tt>,
+<tt>yMin</tt>,
+<tt>xMax</tt>,
+and <tt>yMax</tt>, that can be computed for any outline. Their values can
+be in font units (if measured in the original outline) or in fractional/integer
+pixel units (when measured on scaled outlines).
+<p>Note that if it wasn't for grid-fitting, you wouldn't need to know a
+box's complete values, but only its dimensions to know how big is a glyph
+outline/bitmap. However, correct rendering of hinted glyphs needs the preservation
+of important grid alignment on each glyph translation/placement on the
+baseline.</ul>
+<b>the internal leading</b>
+<ul>this concept comes directly from the world of traditional typography.
+It represents the amount of space within the "leading" which is reserved
+for glyph features that lay outside of the EM square (like accentuation).
+It usually can be computed as:
+<center>
+<p><tt>internal leading = ascent - descent - EM_size</tt></center>
+</ul>
+<b>the external leading</b>
+<ul>this is another name for the line gap.</ul>
+</ul>
+
+<h3>
+3. Bearings and Advances</h3>
+
+<ul>Each glyph has also distances called "bearings" and "advances". Their
+definition is constant, but their values depend on the layout, as the same
+glyph can be used to render text either horizontally or vertically:
+<p><b>the left side bearing: a.k.a. bearingX</b>
+<ul>this is the horizontal distance from the current pen position to the
+glyph's left bbox edge. It is positive for horizontal layouts, and most
+generally negative for vertical one.</ul>
+
+<p><br><b>the top side bearing: a.k.a. bearingY</b>
+<ul>this is the vertical distance from the baseline to the top of the glyph's
+bbox. It is usually positive for horizontal layouts, and negative for vertical
+ones</ul>
+
+<p><br><b>the advance width: a.k.a. advanceX</b>
+<ul>is the horizontal distance the pen position must be incremented (for
+left-to-right writing) or decremented (for right-to-left writing) by after
+each glyph is rendered when processing text. It is always positive for
+horizontal layouts, and null for vertical ones.</ul>
+
+<p><br><b>the advance height: a.k.a. advanceY</b>
+<ul>is the vertical distance the pen position must be decremented by after
+each glyph is rendered. It is always null for horizontal layouts, and positive
+for vertical layouts.</ul>
+
+<p><br><b>the glyph width</b>
+<ul>this is simply the glyph's horizontal extent. More simply it is (bbox.xMax-bbox.xMin)
+for unscaled font coordinates. For scaled glyphs, its computation requests
+specific care, described in the grid-fitting chapter below.</ul>
+
+<p><br><b>the glyph height</b>
+<ul>this is simply the glyph's vertical extent. More simply, it is (bbox.yMax-bbox.yMin)
+for unscaled font coordinates. For scaled glyphs, its computation requests
+specific care, described in the grid-fitting chapter below.</ul>
+
+<p><br><b>the right side bearing</b>
+<ul>is only used for horizontal layouts to describe the distance from the
+bbox's right edge to the advance width. It is in most cases a non-negative
+number.</ul>
+
+<center><tt>advance_width - left_side_bearing - (xMax-xMin)</tt></center>
+
+<p>Here is a picture giving all the details for horizontal metrics :
+<center>
+<p><img SRC="Image3.gif" height=253 width=388></center>
+
+<p>And here is another one for the vertical metrics :
+<center>
+<p><img SRC="Image4.gif" height=278 width=294></center>
+</ul>
+
+<h3>
+4. The effects of grid-fitting</h3>
+
+<ul>Because hinting aligns the glyph's control points to the pixel grid,
+this process slightly modifies the dimensions of character images in ways
+that differ from simple scaling.
+<p>For example, the image of the lowercase "m" letter sometimes fits a
+square in the master grid. However, to make it readable at small pixel
+sizes, hinting tends to enlarge its scaled outline in order to keep its
+three legs distinctly visible, resulting in a larger character bitmap.
+<p>The glyph metrics are also influenced by the grid-fitting process. Mainly
+because :
+<br>&nbsp;
+<ul>
+<li>
+The image's width and height are altered. Even if this is only by one pixel,
+it can make a big difference at small pixel sizes</li>
+
+<li>
+The image's bounding box is modified, thus modifying the bearings</li>
+
+<li>
+The advances must be updated. For example, the advance width must be incremented
+when the hinted bitmap is larger than the scaled one, to reflect the augmented
+glyph width.</li>
+</ul>
+
+<p><br>Note also that :
+<br>&nbsp;
+<ul>
+<li>
+Because of hinting, simply scaling the font ascent or descent might not
+give correct results. A simple solution consists in keeping the ceiling
+of the scaled ascent, and floor of the scaled descent.</li>
+</ul>
+
+<ul>
+<li>
+There is no easy way to get the hinted glyph and advance widths of a range
+of glyphs, as hinting works differently on each outline. The only solution
+is to hint each glyph separately and record the returned values. Some formats,
+like TrueType, even include a table of pre-computed values for a small
+set of common character pixel sizes.</li>
+</ul>
+
+<ul>
+<li>
+Hinting depends on the final character width and height in pixels, which
+means that it is highly resolution-dependent. This property makes correct
+WYSIWYG layouts difficult to implement.</li>
+</ul>
+
+<p><br><b>IMPORTANT NOTE:</b>
+<br>Performing 2D transforms on glyph outlines is very easy with FreeType.
+However, when using translation on a hinted outlines, one should aways
+take care of&nbsp; <b>exclusively using integer pixel distances</b> (which
+means that the parameters to the FT_Translate_Outline API should all be
+multiples of 64, as the point coordinates are in 26.6 fixed float format).
+<p><b>Otherwise</b>, the translation will simply <b>ruin the hinter's work</b>,
+resulting in a very low quality bitmaps.
+<br>&nbsp;
+<br>&nbsp;</ul>
+
+<h3>
+&nbsp;5. Text widths and bounding box :</h3>
+
+<ul>As seen before, the "origin" of a given glyph corresponds to the position
+of the pen on the baseline. It is not necessarily located on one of the
+glyph's bounding box corners, unlike many typical bitmapped font formats.
+In some cases, the origin can be out of the bounding box, in others, it
+can be within it, depending on the shape of the given glyph.
+<p>Likewise, the glyph's "advance width" is the increment to apply to the
+pen position during layout, and is not related to the glyph's "width",
+which really is the glyph's bounding width.
+<br>&nbsp;
+<p>The same conventions apply to strings of text. This means that :
+<br>&nbsp;
+<ul>
+<ul>
+<li>
+The bounding box of a given string of text doesn't necessarily contain
+the text cursor, nor is the latter located on one of its corners.</li>
+</ul>
+
+<ul>
+<li>
+The string's advance width isn't related to its bounding box's dimensions.
+Especially if it contains beginning and terminal spaces or tabs.</li>
+</ul>
+
+<ul>
+<li>
+Finally, additional processing like kerning creates strings of text whose
+dimensions are not directly related to the simple juxtaposition of individual
+glyph metrics. For example, the advance width of "VA" isn't the sum of
+the advances of "V" and "A" taken separately.</li>
+</ul>
+</ul>
+</ul>
+</ul>
+
+<hr WIDTH="100%">
+<h2>
+&nbsp;IV. Kerning</h2>
+
+<blockquote>The term 'kerning' refers to specific information used to adjust
+the relative positions of coincident glyphs in a string of text. This section
+describes several types of kerning information, as well as the way to process
+them when performing text layout.
+<br>&nbsp;
+<h3>
+1. Kerning pairs</h3>
+
+<blockquote>Kerning consists in modifying the spacing between two successive
+glyphs according to their outlines. For example, a "T" and a "y" can be
+easily moved closer, as the top of the "y" fits nicely under the "T"'s
+upper right bar.
+<p>When laying out text with only their standard widths, some consecutive
+glyphs sometimes seem a bit too close or too distant. For example, the
+space between the 'A' and the 'V' in the following word seems a little
+wider than needed.
+<center>
+<p><img SRC="bravo_unkerned.gif" height=37 width=116></center>
+
+<p>Compare this to the same word, when the distance between these two letters
+has been slightly reduced :
+<center>
+<p><img SRC="bravo_kerned.gif" height=37 width=107></center>
+
+<p>As you can see, this adjustment can make a great difference. Some font
+faces thus include a table containing kerning distances for a set of given
+glyph pairs, used during text layout. Note that :
+<br>&nbsp;
+<blockquote>
+<ul>
+<li>
+The pairs are ordered, i.e. the space for pair (A,V) isn't necessarily
+the space for pair (V,A). They also index glyphs, and not characters.</li>
+</ul>
+
+<ul>
+<li>
+Kerning distances can be expressed in horizontal or vertical directions,
+depending on layout and/or script. For example, some horizontal layouts
+like arabic can make use of vertical kerning adjustments between successive
+glyphs. A vertical script can have vertical kerning distances.</li>
+</ul>
+
+<ul>
+<li>
+Kerning distances are expressed in grid units. They are usually oriented
+in the X axis, which means that a negative value indicates that two glyphs
+must be set closer in a horizontal layout.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<h3>
+2. Applying kerning</h3>
+
+<blockquote>Applying kerning when rendering text is a rather easy process.
+It merely consists in adding the scaled kern distance to the pen position
+before writing each next glyph. However, the typographically correct renderer
+must take a few more details in consideration.
+<p>The "sliding dot" problem is a good example : many font faces include
+a kerning distance between capital letters like "T" or "F" and a following
+dot ("."), in order to slide the latter glyph just right to their main
+leg. I.e.
+<center>
+<p><img SRC="twlewis1.gif" height=38 width=314></center>
+
+<p>However, this sometimes requires additional adjustments between the
+dot and the letter following it, depending on the shapes of the enclosing
+letters. When applying "standard" kerning adjustments, the previous sentence
+would become :
+<center>
+<p><img SRC="twlewis2.gif" height=36 width=115></center>
+
+<p>Which clearly is too contracted. The solution here, as exhibited in
+the first example is to only slide the dots when possible. Of course, this
+requires a certain knowledge of the text's meaning. The above adjustments
+would not necessarily be welcomed if we were rendering the final dot of
+a given paragraph.
+<p>This is only one example, and there are many others showing that a real
+typographer is needed to layout text properly. If not available, some kind
+of user interaction or tagging of the text could be used to specify some
+adjustments, but in all cases, this requires some support in applications
+and text libraries.
+<p>For more mundane and common uses, however, we can have a very simple
+algorithm, which&nbsp; avoids the sliding dot problem, and others, though
+not producing optimal results. It can be seen as :
+<br>&nbsp;
+<blockquote>
+<ol>
+<li>
+place the first glyph on the baseline</li>
+
+<li>
+save the location of the pen position/origin in pen1</li>
+
+<li>
+adjust the pen position with the kerning distance between the first and
+second glyph</li>
+
+<li>
+place the second glyph and compute the next pen position/origin in pen2.</li>
+
+<li>
+use pen1 as the next pen position if it is beyond pen2, use pen2 otherwise.</li>
+</ol>
+</blockquote>
+</blockquote>
+</blockquote>
+
+<h2>
+
+<hr WIDTH="100%"></h2>
+
+<h2>
+V. Text processing</h2>
+
+<blockquote>This section demonstrates how to use the concepts previously
+defined to render text, whatever the layout you use.
+<br>&nbsp;
+<h3>
+1. Writing simple text strings :</h3>
+
+<blockquote>In this first example, we'll generate a simple string of Roman
+text, i.e. with a horizontal left-to-right layout. Using exclusively pixel
+metrics, the process looks like :
+<blockquote><tt>1) convert the character string into a series of glyph
+indexes.</tt>
+<br><tt>2) place the pen to the cursor position.</tt>
+<br><tt>3) get or load the glyph image.</tt>
+<br><tt>4) translate the glyph so that its 'origin' matches the pen position</tt>
+<br><tt>5) render the glyph to the target device</tt>
+<br><tt>6) increment the pen position by the glyph's advance width in pixels</tt>
+<br><tt>7) start over at step 3 for each of the remaining glyphs</tt>
+<br><tt>8) when all glyphs are done, set the text cursor to the new pen
+position</tt></blockquote>
+Note that kerning isn't part of this algorithm.</blockquote>
+
+<h3>
+2. Sub-pixel positioning :</h3>
+
+<blockquote>It is somewhat useful to use sub-pixel positioning when rendering
+text. This is crucial, for example, to provide semi-WYSIWYG text layouts.
+Text rendering is very similar to the algorithm described in sub-section
+1, with the following few differences :
+<ul>
+<li>
+The pen position is expressed in fractional pixels.</li>
+
+<li>
+Because translating a hinted outline by a non-integer distance will ruin
+its grid-fitting, the position of the glyph origin must be rounded before
+rendering the character image.</li>
+
+<li>
+The advance width is expressed in fractional pixels, and isn't necessarily
+an integer.</li>
+</ul>
+
+<p><br>Which finally looks like :
+<blockquote><tt>1. convert the character string into a series of glyph
+indexes.</tt>
+<br><tt>2. place the pen to the cursor position. This can be a non-integer
+point.</tt>
+<br><tt>3. get or load the glyph image.</tt>
+<br><tt>4. translate the glyph so that its 'origin' matches the rounded
+pen position.</tt>
+<br><tt>5. render the glyph to the target device</tt>
+<br><tt>6. increment the pen position by the glyph's advance width in fractional
+pixels.</tt>
+<br><tt>7. start over at step 3 for each of the remaining glyphs</tt>
+<br><tt>8. when all glyphs are done, set the text cursor to the new pen
+position</tt></blockquote>
+Note that with fractional pixel positioning, the space between two given
+letters isn't fixed, but determined by the accumulation of previous rounding
+errors in glyph positioning.</blockquote>
+
+<h3>
+3.&nbsp; Simple kerning :</h3>
+
+<blockquote>Adding kerning to the basic text rendering algorithm is easy
+: when a kerning pair is found, simply add the scaled kerning distance
+to the pen position before step 4. Of course, the distance should be rounded
+in the case of algorithm 1, though it doesn't need to for algorithm 2.
+This gives us :
+<p>Algorithm 1 with kerning:
+<blockquote><tt>3) get or load the glyph image.</tt>
+<br><tt>4) Add the rounded scaled kerning distance, if any, to the pen
+position</tt>
+<br><tt>5) translate the glyph so that its 'origin' matches the pen position</tt>
+<br><tt>6) render the glyph to the target device</tt>
+<br><tt>7) increment the pen position by the glyph's advance width in pixels</tt>
+<br><tt>8) start over at step 3 for each of the remaining glyphs</tt></blockquote>
+
+<p><br>Algorithm 2 with kerning:
+<blockquote><tt>3) get or load the glyph image.</tt>
+<br><tt>4) Add the scaled unrounded kerning distance, if any, to the pen
+position.</tt>
+<br><tt>5) translate the glyph so that its 'origin' matches the rounded
+pen position.</tt>
+<br><tt>6) render the glyph to the target device</tt>
+<br><tt>7) increment the pen position by the glyph's advance width in fractional
+pixels.</tt>
+<br><tt>8) start over at step 3 for each of the remaining glyphs</tt></blockquote>
+Of course, the algorithm described in section IV can also be applied to
+prevent the sliding dot problem if one wants to..</blockquote>
+
+<h3>
+4. Right-To-Left Layout :</h3>
+
+<blockquote>The process of laying out arabic or hebrew text is extremely
+similar. The only difference is that the pen position must be decremented
+before the glyph rendering (remember : the advance width is always positive,
+even for arabic glyphs). Thus, algorithm 1 becomes :
+<p>Right-to-left Algorithm 1:
+<blockquote><tt>3) get or load the glyph image.</tt>
+<br><tt>4) Decrement the pen position by the glyph's advance width in pixels</tt>
+<br><tt>5) translate the glyph so that its 'origin' matches the pen position</tt>
+<br><tt>6) render the glyph to the target device</tt>
+<br><tt>7) start over at step 3 for each of the remaining glyphs</tt></blockquote>
+
+<p><br>The changes to Algorithm 2, as well as the inclusion of kerning
+are left as an exercise to the reader.
+<br>&nbsp;
+<br>&nbsp;</blockquote>
+
+<h3>
+5. Vertical layouts :</h3>
+
+<blockquote>Laying out vertical text uses exactly the same processes, with
+the following significant differences :
+<br>&nbsp;
+<blockquote>
+<li>
+The baseline is vertical, and the vertical metrics must be used instead
+of the horizontal one.</li>
+
+<li>
+The left bearing is usually negative, but this doesn't change the fact
+that the glyph origin must be located on the baseline.</li>
+
+<li>
+The advance height is always positive, so the pen position must be decremented
+if one wants to write top to bottom (assuming the Y axis is oriented upwards).</li>
+</blockquote>
+Through the following algorithm :
+<blockquote><tt>1) convert the character string into a series of glyph
+indexes.</tt>
+<br><tt>2) place the pen to the cursor position.</tt>
+<br><tt>3) get or load the glyph image.</tt>
+<br><tt>4) translate the glyph so that its 'origin' matches the pen position</tt>
+<br><tt>5) render the glyph to the target device</tt>
+<br><tt>6) decrement the vertical pen position by the glyph's advance height
+in pixels</tt>
+<br><tt>7) start over at step 3 for each of the remaining glyphs</tt>
+<br><tt>8) when all glyphs are done, set the text cursor to the new pen
+position</tt></blockquote>
+</blockquote>
+
+<h3>
+6. WYSIWYG text layouts :</h3>
+
+<blockquote>As you probably know, the acronym WYSIWYG stands for '<i>What
+You See Is What You Get</i>'. Basically, this means that the output of
+a document on the screen should match "perfectly" its printed version.
+A <b><i>true</i></b> wysiwyg system requires two things :
+<p><b>device-independent text layout</b>
+<blockquote>Which means that the document's formatting is the same on the
+screen than on any printed output, including line breaks, justification,
+ligatures, fonts, position of inline images, etc..</blockquote>
+
+<p><br><b>matching display and print character sizes</b>
+<blockquote>Which means that the displayed size of a given character should
+match its dimensions when printed. For example, a text string which is
+exactly 1 inch tall when printed should also appear 1 inch tall on the
+screen (when using a scale of 100%).</blockquote>
+
+<p><br>It is clear that matching sizes cannot be possible if the computer
+has no knowledge of the physical resolutions of the display device(s) it
+is using. And of course, this is the most common case ! That's not too
+unfortunate, however&nbsp; because most users really don't care about this
+feature. Legibility is much more important.
+<p>When the Mac appeared, Apple decided to choose a resolution of 72 dpi
+to describe the Macintosh screen to the font sub-system (whatever the monitor
+used). This choice was most probably driven by the fact that, at this resolution,
+1 point = 1 pixel. However; it neglected one crucial fact : as most users
+tend to choose a document character size between 10 and 14 points, the
+resultant displayed text was rather small and not too legible without scaling.
+Microsoft engineers took notice of this problem and chose a resolution
+of 96 dpi on Windows, which resulted in slightly larger, and more legible,
+displayed characters (for the same printed text size).
+<p>These distinct resolutions explain some differences when displaying
+text at the same character size on a Mac and a Windows machine. Moreover,
+it is not unusual to find some TrueType fonts with enhanced hinting (tech
+note: through delta-hinting) for the sizes of 10, 12, 14 and 16 points
+at 96 dpi.
+<br>&nbsp;
+<p>As for device-independent text, it is a notion that is, unfortunately,
+often abused. For example, many word processors, including MS Word, do
+not really use device-independent glyph positioning algorithms when laying
+out text. Rather, they use the target printer's resolution to compute <i>hinted</i>
+glyph metrics for the layout. Though it guarantees that the printed version
+is always the "nicest" it can be, especially for very low resolution printers
+(like dot-matrix), it has a very sad effect : changing the printer can
+have dramatic effects on the <i>whole</i> document layout, especially if
+it makes strong use of justification, uses few page breaks, etc..
+<p>Because the glyph metrics vary slightly when the resolution changes
+(due to hinting), line breaks can change enormously, when these differences
+accumulate over long runs of text. Try for example printing a very long
+document (with no page breaks) on a 300 dpi ink-jet printer, then the same
+one on a 3000 dpi laser printer : you'll be extremely lucky if your final
+page count didn't change between the prints ! Of course, we can still call
+this WYSIWYG, as long as the printer resolution is fixed !!
+<p>Some applications, like Adobe Acrobat, which targeted device-independent
+placement from the start, do not suffer from this problem. There are two
+ways to achieve this : either use the scaled and unhinted glyph metrics
+when laying out text both in the rendering and printing processes, or simply
+use wathever metrics you want and store them with the text in order to
+get sure they're printed the same on all devices (the latter being probably
+the best solution, as it also enables font substitution without breaking
+text layouts).
+<p>Just like matching sizes, device-independent placement isn't necessarily
+a feature that most users want. However, it is pretty clear that for any
+kind of professional document processing work, it <b><i>is</i></b> a requirement.</blockquote>
+</blockquote>
+
+<h2>
+
+<hr WIDTH="100%"></h2>
+
+<h2>
+VI. FreeType outlines :</h2>
+
+<blockquote>The purpose of this section is to present the way FreeType
+manages vectorial outlines, as well as the most common operations that
+can be applied on them.
+<br>&nbsp;
+<h3>
+1. FreeType outline description and structure :</h3>
+
+<blockquote>
+<h4>
+a. Outline curve decomposition :</h4>
+
+<blockquote>An outline is described as a series of closed contours in the
+2D plane. Each contour is made of a series of line segments and bezier
+arcs. Depending on the file format, these can be second-order or third-order
+polynomials. The former are also called quadratic or conic arcs, and they
+come from the TrueType format. The latter are called cubic arcs and mostly
+come from the Type1 format.
+<p>Each arc is described through a series of start, end and control points.
+Each point of the outline has a specific tag which indicates wether it
+is used to describe a line segment or an arc. The tags can take the following
+values :
+<br>&nbsp;
+<br>&nbsp;</blockquote>
+
+<center><table CELLSPACING=5 CELLPADDING=5 WIDTH="60%" >
+<tr VALIGN=TOP>
+<td>
+<blockquote><b>FT_Curve_Tag_On&nbsp;</b></blockquote>
+</td>
+
+<td VALIGN=TOP>
+<blockquote>Used when the point is "on" the curve. This corresponds to
+start and end points of segments and arcs. The other tags specify what
+is called an "off" point, i.e. one which isn't located on the contour itself,
+but serves as a control point for a bezier arc.</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote><b>FT_Curve_Tag_Conic</b></blockquote>
+</td>
+
+<td>
+<blockquote>Used for an "off" point used to control a conic bezier arc.</blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote><b>FT_Curve_Tag_Cubic</b></blockquote>
+</td>
+
+<td>
+<blockquote>Used for an "off" point used to control a cubic bezier arc.</blockquote>
+</td>
+</tr>
+</table></center>
+
+<blockquote>&nbsp;
+<p>The following rules are applied to decompose the contour's points into
+segments and arcs :
+<blockquote>
+<li>
+two successive "on" points indicate a line segment joining them.</li>
+</blockquote>
+</blockquote>
+
+<ul>
+<ul>
+<li>
+one conic "off" point amidst two "on" points indicates a conic bezier arc,
+the "off" point being the control point, and the "on" ones the start and
+end points.</li>
+</ul>
+</ul>
+
+<ul>
+<ul>
+<li>
+Two successive cubic "off" points amidst two "on" points indicate a cubic
+bezier arc. There must be exactly two cubic control points and two on points
+for each cubic arc (using a single cubic "off" point between two "on" points
+is forbidden, for example).</li>
+</ul>
+</ul>
+
+<ul>
+<ul>
+<li>
+finally, two successive conic "off" points forces the rasterizer to create
+(during the scan-line conversion process exclusively) a virtual "on" point
+amidst them, at their exact middle. This greatly facilitates the definition
+of successive conic bezier arcs. Moreover, it's the way outlines are described
+in the TrueType specification.</li>
+</ul>
+
+<p><br>Note that it is possible to mix conic and cubic arcs in a single
+contour, even though no current font driver produces such outlines.
+<br>&nbsp;</ul>
+
+<center><table>
+<tr>
+<td>
+<blockquote><img SRC="points_segment.gif" height=166 width=221></blockquote>
+</td>
+
+<td>
+<blockquote><img SRC="points_conic.gif" height=183 width=236></blockquote>
+</td>
+</tr>
+
+<tr>
+<td>
+<blockquote><img SRC="points_cubic.gif" height=162 width=214></blockquote>
+</td>
+
+<td>
+<blockquote><img SRC="points_conic2.gif" height=204 width=225></blockquote>
+</td>
+</tr>
+</table></center>
+
+<h4>
+b. Outline descriptor :</h4>
+
+<blockquote>A FreeType outline is described through a simple structure,
+called <tt>FT_Outline</tt>, which fields are :
+<br>&nbsp;
+<br>&nbsp;
+<center><table CELLSPACING=3 CELLPADDING=3 BGCOLOR="#CCCCCC" >
+<tr>
+<td><b><tt>n_points</tt></b></td>
+
+<td>the number of points in the outline</td>
+</tr>
+
+<tr>
+<td><b><tt>n_contours</tt></b></td>
+
+<td>the number of contours in the outline</td>
+</tr>
+
+<tr>
+<td><b><tt>points</tt></b></td>
+
+<td>array of point coordinates</td>
+</tr>
+
+<tr>
+<td><b><tt>contours</tt></b></td>
+
+<td>array of contour end indices</td>
+</tr>
+
+<tr>
+<td><b><tt>flags</tt></b></td>
+
+<td>array of point flags</td>
+</tr>
+</table></center>
+
+<p>Here, <b><tt>points</tt></b> is a pointer to an array of <tt>FT_Vector</tt>
+records, used to store the vectorial coordinates of each outline point.
+These are expressed in 1/64th of a pixel, which is also known as the <i>26.6
+fixed float format</i>.
+<p><b><tt>contours</tt></b> is an array of point indices used to delimit
+contours in the outline. For example, the first contour always starts at
+point 0, and ends a point <b><tt>contours[0]</tt></b>. The second contour
+starts at point "<b><tt>contours[0]+1</tt></b>" and ends at <b><tt>contours[1]</tt></b>,
+etc..
+<p>Note that each contour is closed, and that <b><tt>n_points</tt></b>
+should be equal to "<b><tt>contours[n_contours-1]+1</tt></b>" for a valid
+outline.
+<p>Finally, <b><tt>flags</tt></b> is an array of bytes, used to store each
+outline point's tag.
+<br>&nbsp;
+<br>&nbsp;</blockquote>
+</blockquote>
+
+<h3>
+2. Bounding and control box computations :</h3>
+
+<blockquote>A <b>bounding box</b> (also called "<b>bbox</b>") is simply
+the smallest possible rectangle that encloses the shape of a given outline.
+Because of the way arcs are defined, bezier control points are not necessarily
+contained within an outline's bounding box.
+<p>This situation happens when one bezier arc is, for example, the upper
+edge of an outline and an off point happens to be above the bbox. However,
+it is very rare in the case of character outlines because most font designers
+and creation tools always place on points at the extrema of each curved
+edges, as it makes hinting much easier.
+<p>We thus define the <b>control box</b> (a.k.a. the "<b>cbox</b>") as
+the smallest possible rectangle that encloses all points of a given outline
+(including its off points). Clearly, it always includes the bbox, and equates
+it in most cases.
+<p>Unlike the bbox, the cbox is also much faster to compute.
+<br>&nbsp;
+<center><table>
+<tr>
+<td><img SRC="bbox1.gif" height=264 width=228></td>
+
+<td><img SRC="bbox2.gif" height=229 width=217></td>
+</tr>
+</table></center>
+
+<p>Control and bounding boxes can be computed automatically through the
+functions <b><tt>FT_Get_Outline_CBox</tt></b> and <b><tt>FT_Get_Outline_BBox</tt></b>.
+The former function is always very fast, while the latter <i>may</i> be
+slow in the case of "outside" control points (as it needs to find the extreme
+of conic and cubic arcs for "perfect" computations). If this isn't the
+case, it's as fast as computing the control box.
+<p>Note also that even though most glyph outlines have equal cbox and bbox
+to ease hinting, this is not necessary the case anymore when a
+<br>transform like rotation is applied to them.
+<br>&nbsp;</blockquote>
+
+<h3>
+&nbsp;3. Coordinates, scaling and grid-fitting :</h3>
+
+<blockquote>An outline point's vectorial coordinates are expressed in the
+26.6 format, i.e. in 1/64th of a pixel, hence coordinates (1.0, -2.5) is
+stored as the integer pair ( x:64, y: -192 ).
+<p>After a master glyph outline is scaled from the EM grid to the current
+character dimensions, the hinter or grid-fitter is in charge of aligning
+important outline points (mainly edge delimiters) to the pixel grid. Even
+though this process is much too complex to be described in a few lines,
+its purpose is mainly to round point positions, while trying to preserve
+important properties like widths, stems, etc..
+<p>The following operations can be used to round vectorial distances in
+the 26.6 format to the grid :
+<center>
+<p><tt>round(x)&nbsp;&nbsp; ==&nbsp; (x+32) &amp; -64</tt>
+<br><tt>floor(x)&nbsp;&nbsp; ==&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x &amp;
+-64</tt>
+<br><tt>ceiling(x) ==&nbsp; (x+63) &amp; -64</tt></center>
+
+<p>Once a glyph outline is grid-fitted or transformed, it often is interesting
+to compute the glyph image's pixel dimensions before rendering it. To do
+so, one has to consider the following :
+<p>The scan-line converter draws all the pixels whose <i>centers</i> fall
+inside the glyph shape. It can also detect "<b><i>drop-outs</i></b>", i.e.
+discontinuities coming from extremely thin shape fragments, in order to
+draw the "missing" pixels. These new pixels are always located at a distance
+less than half of a pixel but one cannot predict easily where they'll appear
+before rendering.
+<p>This leads to the following computations :
+<br>&nbsp;
+<ul>
+<li>
+compute the bbox</li>
+</ul>
+
+<ul>
+<li>
+grid-fit the bounding box with the following :</li>
+</ul>
+
+<ul>
+<ul><tt>xmin = floor( bbox.xMin )</tt>
+<br><tt>xmax = ceiling( bbox.xMax )</tt>
+<br><tt>ymin = floor( bbox.yMin )</tt>
+<br><tt>ymax = ceiling( bbox.yMax )</tt></ul>
+
+<li>
+return pixel dimensions, i.e. <tt>width = (xmax - xmin)/64</tt> and <tt>height
+= (ymax - ymin)/64</tt></li>
+</ul>
+
+<p><br>By grid-fitting the bounding box, one guarantees that all the pixel
+centers that are to be drawn, <b><i>including those coming from drop-out
+control</i></b>, will be <b><i>within</i></b> the adjusted box. Then the
+box's dimensions in pixels can be computed.
+<p>Note also that, when <i>translating</i> a <i>grid-fitted outline</i>,
+one should <b><i>always</i></b> use <b><i>integer distances</i></b> to
+move an outline in the 2D plane. Otherwise, glyph edges won't be aligned
+on the pixel grid anymore, and the hinter's work will be lost, producing
+<b><i>very
+low quality </i></b>bitmaps and pixmaps..</blockquote>
+</blockquote>
+
+<hr WIDTH="100%">
+<h2>
+VII. FreeType bitmaps :</h2>
+
+<blockquote>The purpose of this section is to present the way FreeType
+manages bitmaps and pixmaps, and how they relate to the concepts previously
+defined. The relationships between vectorial and pixel coordinates is explained.
+<br>&nbsp;
+<h3>
+1. FreeType bitmap and pixmap descriptor :</h3>
+
+<blockquote>A bitmap or pixmap is described through a single structure,
+called <tt>FT_Raster_Map</tt>. It is a simple descriptor whose fields are
+:
+<br>&nbsp;
+<br>&nbsp;
+<center><table CELLSPACING=3 CELLPADDING=5 BGCOLOR="#CCCCCC" >
+<caption><tt>FT_Raster_Map</tt></caption>
+
+<tr>
+<td><b>rows</b></td>
+
+<td>the number of rows, i.e. lines, in the bitmap</td>
+</tr>
+
+<tr>
+<td><b>width</b></td>
+
+<td>the number of horizontal pixels in the bitmap</td>
+</tr>
+
+<tr>
+<td><b>cols</b></td>
+
+<td>the number of "columns", i.e. bytes per line, in the bitmap</td>
+</tr>
+
+<tr>
+<td><b>flow</b></td>
+
+<td>the bitmap's flow, i.e. orientation of rows (see below)</td>
+</tr>
+
+<tr>
+<td><b>pix_bits</b></td>
+
+<td>the number of bits per pixels. valid values are 1, 4, 8 and 16</td>
+</tr>
+
+<tr>
+<td><b>buffer</b></td>
+
+<td>a typeless pointer to the bitmap pixel bufer</td>
+</tr>
+</table></center>
+
+<p>The bitmap's <b><tt>flow</tt></b> determines wether the rows in the
+pixel buffer are stored in ascending or descending order. Possible values
+are <b><tt>FT_Flow_Up</tt></b> (value 1) and <b><tt>FT_Flow_Down</tt></b>
+(value -1).
+<p>Remember that FreeType uses the <i>Y upwards</i> convention in the 2D
+plane. Which means that a coordinate of (0,0) always refer to the <i>lower-left
+corner</i> of a bitmap.
+<p>In the case of an '<i>up</i>' flow, the rows are stored in increasing
+vertical position, which means that the first bytes of the pixel buffer
+are part of the <i>lower</i> bitmap row. On the opposite, a '<i>down</i>'
+flow means that the first buffer bytes are part of the <i>upper</i> bitmap
+row, i.e. the last one in ascending order.
+<p>As a hint, consider that when rendering an outline into a Windows or
+X11 bitmap buffer, one should always use a down flow in the bitmap descriptor.
+<br>&nbsp;
+<center><table>
+<tr>
+<td><img SRC="up_flow.gif" height=298 width=291></td>
+
+<td><img SRC="down_flow.gif" height=298 width=313></td>
+</tr>
+
+<tr>
+<td></td>
+
+<td></td>
+</tr>
+</table></center>
+</blockquote>
+
+<h3>
+2. Vectorial versus pixel coordinates :</h3>
+
+<blockquote>This sub-section explains the differences between vectorial
+and pixel coordinates. To make things clear, brackets will be used to describe
+pixel coordinates, e.g. [3,5], while parentheses will be used for vectorial
+ones, e.g. (-2,3.5).
+<p>In the pixel case, as we use the <i>Y upwards</i> convention, the coordinate
+[0,0] always refers to the <i>lower left pixel</i> of a bitmap, while coordinate
+[width-1, rows-1] to its <i>upper right pixel</i>.
+<p>In the vectorial case, point coordinates are expressed in floating units,
+like (1.25, -2.3). Such a position doesn't refer to a given pixel, but
+simply to an immaterial point in the 2D plane
+<p>The pixels themselves are indeed <i>square boxes</i> of the 2D plane,
+which centers lie in half pixel coordinates. For example, the <i>lower
+left pixel</i> of a bitmap is delimited by the <i>square</i> (0,0)-(1,1),
+its center being at location (0.5,0.5).
+<p>This introduces some differences when computing distances. For example,
+the "<i>length</i>" in pixels of the line [0,0]-[10,0] is 11. However,
+the vectorial distance between (0,0)-(10,0) covers exactly 10 pixel centers,
+hence its length if 10.
+<center><img SRC="grid_1.gif" height=390 width=402></center>
+</blockquote>
+
+<h3>
+3. Converting outlines into bitmaps and pixmaps :</h3>
+
+<blockquote>Generating a bitmap or pixmap image from a vectorial image
+is easy with FreeType. However, one must understand a few points regarding
+the positioning of the outline in the 2D plane before calling the function
+<b><tt>FT_Get_Outline_Bitmap</tt></b>.
+These are :
+<br>&nbsp;
+<ul>
+<li>
+The glyph loader and hinter always places the outline in the 2D plane so
+that (0,0) matches its character origin. This means that the glyphÂ’s outline,
+and corresponding bounding box, can be placed anywhere in the 2D plane
+(see the graphics in section III).</li>
+</ul>
+
+<ul>
+<li>
+The target bitmapÂ’s area is mapped to the 2D plane, with its lower left
+corner at (0,0). This means that a bitmap or pixmap of dimensions [<tt>w,h</tt>]
+will be mapped to a 2D rectangle window delimited by (0,0)-(<tt>w,h</tt>).</li>
+</ul>
+
+<ul>
+<li>
+When calling <b><tt>FT_Get_Outline_Bitmap</tt></b>, everything that falls
+within the bitmap window is rendered, the rest is ignored.</li>
+</ul>
+
+<p><br>A common mistake made by many developers when they begin using FreeType
+is believing that a loaded outline can be directly rendered in a bitmap
+of adequate dimensions. The following images illustrate why this is a problem
+:
+<ul>
+<ul>
+<li>
+the first image shows a loaded outline in the 2D plane.</li>
+
+<li>
+the second one shows the target window for a bitmap of arbitrary dimensions
+[w,h]</li>
+
+<li>
+the third one shows the juxtaposition of the outline and window in the
+2D plane</li>
+
+<li>
+the last image shows what will really be rendered in the bitmap.</li>
+</ul>
+</ul>
+
+<center><img SRC="clipping.gif" height=151 width=539></center>
+
+<p><br>
+<br>
+<br>
+<br>
+<br>
+<p>Indeed, in nearly all cases, the loaded or transformed outline must
+be translated before it is rendered into a target bitmap, in order to adjust
+its position relative to the target window.
+<p>For example, the correct way of creating a <i>standalone</i> glyph bitmap
+is thus to :
+<br>&nbsp;
+<ul>
+<li>
+Compute the size of the glyph bitmap. It can be computed directly from
+the glyph metrics, or by computing its bounding box (this is useful when
+a transform has been applied to the outline after the load, as the glyph
+metrics are not valid anymore).</li>
+</ul>
+
+<ul>
+<li>
+Create the bitmap with the computed dimensions. DonÂ’t forget to fill the
+pixel buffer with the background color.</li>
+</ul>
+
+<ul>
+<li>
+Translate the outline so that its lower left corner matches (0,0). DonÂ’t
+forget that in order to preserve hinting, one should use integer, i.e.
+rounded distances (of course, this isnÂ’t required if preserving hinting
+information doesnÂ’t matter, like with rotated text). Usually, this means
+translating with a vector <tt>( -ROUND(xMin), -ROUND(yMin) )</tt>.</li>
+</ul>
+
+<ul>
+<li>
+Call the function <b><tt>FT_Get_Outline_Bitmap</tt></b>.</li>
+</ul>
+
+<p><br>In the case where one wants to write glyph images directly into
+a large bitmap, the outlines must be translated so that their vectorial
+position correspond to the current text cursor/character origin.</blockquote>
+</blockquote>
+
+<h2>
+
+<hr WIDTH="100%"></h2>
+
+<h2>
+VII. FreeType anti-aliasing :</h2>
+<b><i>IMPORTANT NOTE :</i></b>
+<br>This section is still in progress, as the way FreeType 2 handles anti-aliased
+rendering hasn't been definitely set yet. The main reason being that a
+flexible way of doing things is needed in order to allow further improvements
+in the raster (i.e. number of gray levels > 100, etc..).
+<blockquote>
+<h3>
+1. What is anti-aliasing :</h3>
+
+<blockquote>Anti-aliasing works by using various levels of grays to reduce
+the "staircase" artefacts visible on the diagonals and curves of glyph
+bitmaps. It is a way to artificially enhance the display resolution of
+the target device. It can smooth out considerably displayed or printed
+text.</blockquote>
+
+<h3>
+2. How does it work with FreeType :</h3>
+
+<blockquote>FreeType's scan-line converter is able to produce anti-aliased
+output directly. It is however limited to 8-bit pixmaps and 5 levels of
+grays (or 17 levels, depending on a build configuration option). Here's
+how one should use it :
+<h4>
+a. Set the gray-level palette :</h4>
+
+<blockquote>The scan-line converter uses 5 levels for anti-aliased output.
+Level 0 corresponds to the text background color (e.g. white), and level
+5 to the text foreground color. Intermediate levels are used for intermediate
+shades of grays.
+<p>You must set the raster's palette when you want to use different colors,
+use the function <b><tt>FT_Raster_Set_Palette</tt></b> as in :
+<p><tt>{</tt>
+<br><tt>&nbsp; static const char&nbsp; gray_palette[5] = { 0, 7, 15, 31,
+63 };</tt>
+<br><tt>&nbsp; Â…</tt>
+<br><tt>&nbsp; error = FT_Set_Raster_Palette( library, 5, palette );</tt>
+<br><tt>}</tt>
+<br>&nbsp;
+<ul>
+<li>
+The first parameter is a handle to a FreeType library object. See the user
+guide for more details (the library contains a scan-line converter object).</li>
+</ul>
+
+<ul>
+<li>
+The second parameter is the number of entries in the gray-level palette.
+Valid values are 5 and 17 for now, but this may change in later implementations.</li>
+</ul>
+
+<ul>
+<li>
+The last parameter is a pointer to a char table containing the pixel value
+for each of the gray-levels. In this example, we use a background color
+of 0, a foreground color of 63, and intermediate values in-between.</li>
+</ul>
+
+<p><br>The palette is copied in the raster object, as well as processed
+to build several lookup-tables necessary for the internal anti-aliasing
+algorithm.
+<br>&nbsp;</blockquote>
+
+<h4>
+b. Render the pixmap :</h4>
+
+<blockquote>The scan-line converter doesn't create bitmaps or pixmaps,
+it simply renders into those that are passed as parameters to the function
+<b><tt>FT_Get_Outline_Bitmap</tt></b>.
+To render an anti-aliased pixmap, simply set the target bitmapÂ’s depth
+to 8. Note however that this target 8-bit pixmap must always have a '<b><tt>cols</tt></b>'
+field padded to 32-bits, which means that the number of bytes per lines
+of the pixmap must be a multiple of 4 !
+<p>Once the palette has been set, and the pixmap buffer has been created
+to receive the glyph image, simply call <b><tt>FT_Get_Outline_Bitmap</tt></b>.
+Take care of clearing the target pixmap with the background color before
+calling this function. For the sake of simplicity and efficiency, the raster
+is not able to compose anti-aliased glyph images on a pre-existing images.
+<p>Here's some code demonstrating how to load and render a single glyph
+pixmap :
+<p><tt>{</tt>
+<br><tt>&nbsp; FT_Outline&nbsp;&nbsp;&nbsp;&nbsp; outline;</tt>
+<br><tt>&nbsp; FT_Raster_Map&nbsp; pixmap;</tt>
+<br><tt>&nbsp; FT_BBox&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cbox;</tt>
+<br><tt>&nbsp; Â…</tt>
+<p><i><tt>&nbsp; // load the outline</tt></i>
+<br><tt>&nbsp; Â…</tt>
+<p><i><tt>&nbsp; // compute glyph dimensions (grid-fit cbox, etc..)</tt></i>
+<br><tt>&nbsp; FT_Get_Outline_CBox( &amp;outline, &amp;cbox );</tt>
+<p><tt>&nbsp; cbox.xMin = cbox.xMin &amp; -64;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// floor(xMin)</tt>
+<br><tt>&nbsp; cbox.yMin = cbox.yMin &amp; -64;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// floor(yMin)</tt>
+<br><tt>&nbsp; cbox.xMax = (cbox.xMax+32) &amp; -64;&nbsp; // ceiling(xMax)</tt>
+<br><tt>&nbsp; cbox.yMax = (cbox.yMax+32) &amp; -64;&nbsp; // ceiling(yMax)</tt>
+<p><tt>&nbsp; pixmap.width = (cbox.xMax - cbox.xMin)/64;</tt>
+<br><tt>&nbsp; pixmap.rows&nbsp; = (cbox.yMax - cbox.yMin)/64;</tt>
+<p><i><tt>&nbsp; // fill the pixmap descriptor and create the pixmap buffer</tt></i>
+<br><i><tt>&nbsp; // don't forget to pad the 'cols' field to 32 bits</tt></i>
+<br><tt>&nbsp; pixmap.pix_bits = 8;</tt>
+<br><tt>&nbsp; pixmap.flow&nbsp;&nbsp;&nbsp;&nbsp; = FT_Flow_Down;</tt>
+<br><tt>&nbsp; pixmap.cols&nbsp;&nbsp;&nbsp;&nbsp; = (pixmap.width+3) &amp;
+-4;&nbsp; // pad 'cols' to 32 bits</tt>
+<br><tt>&nbsp; pixmap.buffer&nbsp;&nbsp; = malloc( pixmap.cols * pixmap.rows
+);</tt>
+<p><i><tt>&nbsp; // fill the pixmap buffer with the background color</tt></i>
+<br><i><tt>&nbsp; //</tt></i>
+<br><tt>&nbsp; memset( pixmap.buffer, 0, pixmap.cols*pixmap.rows );</tt>
+<p><i><tt>&nbsp; // translate the outline to match (0,0) with the glyph's</tt></i>
+<br><i><tt>&nbsp; // lower left corner (ignore the bearings)</tt></i>
+<br><i><tt>&nbsp; // the cbox is grid-fitted, we won't ruin the hinting.</tt></i>
+<br><i><tt>&nbsp; //</tt></i>
+<br><tt>&nbsp; FT_Translate_Outline( &amp;outline, -cbox.xMin, -cbox.yMin
+);</tt>
+<p><i><tt>&nbsp; // render the anti-aliased glyph pixmap</tt></i>
+<br><tt>&nbsp; error = FT_Get_Outline_Bitmap( library, &amp;outline, &amp;pixmap
+);</tt>
+<p><tt>&nbsp; // save the bearings for later use..</tt>
+<br><tt>&nbsp; corner_x = cbox.xMin / 64;</tt>
+<br><tt>&nbsp; corner_y = cbox.yMin / 64;</tt>
+<br><tt>}</tt>
+<p>The resulting pixmap is always anti-aliased.</blockquote>
+</blockquote>
+
+<h3>
+3. Possible enhancements :</h3>
+
+<blockquote>FreeType's raster (i.e. its scan-line converter) is currently
+limited to producing either 1-bit bitmaps or anti-aliased 8-bit pixmaps.
+It is not possible, for example, to draw directly a bitmapped glyph image
+into a 4, 8 or 16-bit pixmap through a call to FT_Get_Outline_Bitmap.
+<p>Moreover, the anti-aliasing filter is limited to use 5 or 17 levels
+of grays (through 2x2 and 4x4 sub-sampling). There are cases where this
+could seem insufficient for optimal results and where a higher number of
+levels like 64 or 128 would be a good thing.
+<p>These enhancements are all possible but not planned for an immediate
+future of the FreeType engine.</blockquote>
+</blockquote>
+
+</body>
+</html>
diff --git a/docs/glyph_conventions/grid_1.gif b/docs/glyph_conventions/grid_1.gif
new file mode 100644
index 0000000..31291a8
--- /dev/null
+++ b/docs/glyph_conventions/grid_1.gif
Binary files differ
diff --git a/docs/glyph_conventions/objects_diagram.gif b/docs/glyph_conventions/objects_diagram.gif
new file mode 100644
index 0000000..c8e1843
--- /dev/null
+++ b/docs/glyph_conventions/objects_diagram.gif
Binary files differ
diff --git a/docs/glyph_conventions/objects_diagram2.gif b/docs/glyph_conventions/objects_diagram2.gif
new file mode 100644
index 0000000..0c2bbfe
--- /dev/null
+++ b/docs/glyph_conventions/objects_diagram2.gif
Binary files differ
diff --git a/docs/glyph_conventions/points_conic.gif b/docs/glyph_conventions/points_conic.gif
new file mode 100644
index 0000000..b9bd200
--- /dev/null
+++ b/docs/glyph_conventions/points_conic.gif
Binary files differ
diff --git a/docs/glyph_conventions/points_conic2.gif b/docs/glyph_conventions/points_conic2.gif
new file mode 100644
index 0000000..9617a7b
--- /dev/null
+++ b/docs/glyph_conventions/points_conic2.gif
Binary files differ
diff --git a/docs/glyph_conventions/points_cubic.gif b/docs/glyph_conventions/points_cubic.gif
new file mode 100644
index 0000000..4624468
--- /dev/null
+++ b/docs/glyph_conventions/points_cubic.gif
Binary files differ
diff --git a/docs/glyph_conventions/points_segment.gif b/docs/glyph_conventions/points_segment.gif
new file mode 100644
index 0000000..e14053d
--- /dev/null
+++ b/docs/glyph_conventions/points_segment.gif
Binary files differ
diff --git a/docs/glyph_conventions/twlewis1.gif b/docs/glyph_conventions/twlewis1.gif
new file mode 100644
index 0000000..3b2d4ba
--- /dev/null
+++ b/docs/glyph_conventions/twlewis1.gif
Binary files differ
diff --git a/docs/glyph_conventions/twlewis2.gif b/docs/glyph_conventions/twlewis2.gif
new file mode 100644
index 0000000..46d06ce
--- /dev/null
+++ b/docs/glyph_conventions/twlewis2.gif
Binary files differ
diff --git a/docs/glyph_conventions/up_flow.gif b/docs/glyph_conventions/up_flow.gif
new file mode 100644
index 0000000..04f0b5a
--- /dev/null
+++ b/docs/glyph_conventions/up_flow.gif
Binary files differ
diff --git a/docs/internals/Image1.gif b/docs/internals/Image1.gif
new file mode 100644
index 0000000..0725ca4
--- /dev/null
+++ b/docs/internals/Image1.gif
Binary files differ
diff --git a/docs/internals/Image2.gif b/docs/internals/Image2.gif
new file mode 100644
index 0000000..d95e09c
--- /dev/null
+++ b/docs/internals/Image2.gif
Binary files differ
diff --git a/docs/internals/Image3.gif b/docs/internals/Image3.gif
new file mode 100644
index 0000000..6b5ae26
--- /dev/null
+++ b/docs/internals/Image3.gif
Binary files differ
diff --git a/docs/internals/Image4.gif b/docs/internals/Image4.gif
new file mode 100644
index 0000000..509b10a
--- /dev/null
+++ b/docs/internals/Image4.gif
Binary files differ
diff --git a/docs/internals/freetype_internals.html b/docs/internals/freetype_internals.html
new file mode 100644
index 0000000..8659e7e
--- /dev/null
+++ b/docs/internals/freetype_internals.html
@@ -0,0 +1,788 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="David Turner">
+   <meta name="GENERATOR" content="Mozilla/4.5 [fr] (Win98; I) [Netscape]">
+   <title>FreeType 2 Internals</title>
+</head>
+<body>
+
+<body text="#000000"
+      bgcolor="#FFFFFF"
+      link="#0000EF"
+      vlink="#51188E"
+      alink="#FF0000">
+
+<center>
+<h1>
+FreeType 2.0 Internals</h1></center>
+
+<center>
+<h2>
+Version 1.0</h2></center>
+
+<center>
+<h3>
+&copy; 1999 David Turner (<a href="fichier :///david@freetype.org">david@freetype.org</a>)<br>
+&copy; 1999 The FreeType Development Team (<a href="fichier :///devel@freetype.org">devel@freetype.org</a>)</h3></center>
+
+<p><br>
+<hr WIDTH="100%">
+<br>&nbsp;
+<h2>
+Introduction:</h2>
+
+<blockquote>This document describes in great details the internals of the
+FreeType 2.0 library. It is a must read for porters and developers alike.
+Its purpose is to present the engine's objects, their roles and interactions.
+It is assumed that the <b><i>FreeType Glyph Conventions</i></b> document
+has been read.
+<p>We advise porters to also read the <b><i>FreeType Porting Guide</i></b>
+after this document. Would-be hackers and maintainers are of course encouraged
+to read the <b><i>FreeType Coding Conventions</i></b> document too. The
+development of a new driver is described in more details in the <b><i>FreeType
+Driver HowTo</i></b> document.</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+I. Overview :</h2>
+
+<blockquote>
+<h3>
+1. Features (and what's new) :</h3>
+
+<blockquote>FreeType 2.0 has a number of important new features that were
+not found in the 1.x releases :
+<br>&nbsp;
+<blockquote><b>font-format independent API</b>
+<br>FreeType 2.0 is able to support any kind of font format, be it fixed
+or scalable, through the use of pluggable "font drivers". These drivers
+can be added or replaced at run time, while applications use a new font
+format-independent API.
+<p><b>advanced stream caching</b>
+<br>2.0 is able to control the number of concurrently opened streams when
+using fonts. It is thus possible to open dozens or hundreds of font faces
+without running out of system resources.
+<p><b>real reentrancy support</b>
+<br>It is now possible to use FreeType as a shared library with no static
+data in a multi-threaded environment. The synchronization model has also
+been simplified in order to make font driver writing easier. Of course,
+you can build FreeType with no thread support to get a smaller library.
+<p><b>support for cubic beziers and 17-levels anti-aliasing</b>
+<br>The FreeType scan-line converter (a.k.a. raster) now supports cubic
+bezier arcs seamlessly. It also provides a new anti-aliasing mode which
+uses a palette of 17 levels of grays.
+<br>&nbsp;</blockquote>
+It also features the following :
+<blockquote><b>performance improvements :</b>
+<br>The FreeType raster has been optimized, and the generation of anti-aliased
+pixmaps is now 60% faster than in the 1.x release. Moreover, the TrueType
+bytecode interpreter has been profiled and greatly optimised.
+<p><b>easier portability</b>
+<br>Porting and configuring FreeType is now much easier. A single file
+must be provided for system-specific operations (like memory, i/o, thread
+management), and a single configuration header is used to select the build
+you need.
+<br>&nbsp;</blockquote>
+</blockquote>
+
+<h3>
+2. Architecture :</h3>
+
+<blockquote>The engine is now split in several parts, which are :
+<h4>
+a. The base layer :</h4>
+
+<blockquote>This part contains all the font-format independent features
+of the engine which are :
+<ul>
+<li>
+computations/scaling</li>
+
+<li>
+list processing</li>
+
+<li>
+outline processing</li>
+
+<li>
+scan-line converter</li>
+
+<li>
+stream manager</li>
+
+<li>
+base object classes</li>
+
+<li>
+debugging &amp; traces</li>
+
+<li>
+high-level API functions</li>
+
+<li>
+low-level system object (memory, i/o, threads)</li>
+</ul>
+</blockquote>
+
+<h4>
+b. The font drivers :</h4>
+
+<blockquote>Each font format is managed with the use of a single font driver
+object. The base layer is able to manage several drivers, and these can
+be easily added, removed or upgraded at runtime. Each driver has the following
+features and functions :
+<ul>
+<li>
+auto-check font format when opening a font resource (i.e. file)</li>
+
+<li>
+access, load and/or extract all tables and data from the font file</li>
+
+<li>
+grid-fit/hint the glyph outlines (in the case of scalable formats like
+TrueType or Type1)</li>
+
+<li>
+provide extensions to access font format-specific data and tables from
+the font file</li>
+</ul>
+Note that FreeType 2.0 is a font service. Its purpose is to provide a unified
+API for all kinds of fonts and extract individual glyph images and metrics.
+However, it does not render text itself, as this operation is left to the
+developer, or to higher-level libraries built on top of FreeType. Here
+are a few features that are thus not implemented :
+<blockquote>1) Text string rendering
+<br>2) Glyph bitmap/outline caching for improved performance
+<br>3) Synthetic fonts (i.e. italicising, emboldening, underlining)
+<br>4) Contextual glyph substitution and other advanced layout processes</blockquote>
+Note that features 1 through 3 should be provided by the SemTex library,
+which may soon become part of the standard FreeType distribution.</blockquote>
+</blockquote>
+</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+II. Design :</h2>
+
+<blockquote>
+<h3>
+1. Objects :</h3>
+
+<blockquote>They are several kinds of objects in FreeType, which can be
+described as follows :
+<blockquote><b>Base objects</b>
+<br>These objects do not relate directly to font data, but to the way it
+is organised and managed. It is the basic core and provides functions that
+are heavily used by each font driver. Examples are the resource objects,
+used to describe font files, the system object used to manage low-level
+system operations, or the raster object, used to convert vector outlines
+into bitmaps or anti-aliased pixmaps. Most of the base objects are not
+directly visible for client applications of FreeType.
+<p><b>Font objects</b>
+<br>The font objects directly model the data as it is found in font files.
+The root classes implemented in the base layer like <tt>FT_Face</tt>, <tt>FT_Size</tt>,
+<tt>FT_GlyphSlot</tt>,
+must be derived in each font driver.</blockquote>
+Objects are defined in the files "<tt>base/freetype.h</tt>" and "<tt>base/ftobjs.h</tt>".
+The former contains all the public object definitions usable by client
+applications. The latter contains private definitions used by the rest
+of the base layer and each font driver.</blockquote>
+
+<h3>
+2. List management</h3>
+
+<blockquote>The "<tt>base/ftlist.c</tt>" component a very simple doubly-linked
+list facility which is used by the rest of the engine to create and process
+lists, including iteration and finalisation. The definition of the list
+node and functions are placed in the "<tt>base/freetype.h</tt>" to let
+client applications access listed objects as they like.
+<p>The base list type is <tt>FT_List</tt>, which links nodes of type <tt>FT_ListNode</tt>
+together.
+<br>&nbsp;</blockquote>
+
+<h3>
+3. Limited encapsulation</h3>
+
+<blockquote>Unlike what happened in the 1.x releases, the <tt>FT_Face</tt>,
+<tt>FT_Size</tt>,
+<tt>FT_GlyphSlot</tt> and <tt>FT_CharMap</tt> types are no longer blind
+pointers to opaque types. Rather, the corresponding structures are now
+public (and defined in "<tt>base/freetype.h</tt>", see <tt>FT_FaceRec</tt>,
+<tt>FT_SizeRec</tt>,
+etc..) in order to let client applications read directly the various object
+attributes they're interested in.
+<p>This breaks encapsulation of implementation, famed by OOP, but was chosen
+because:
+<br>&nbsp;
+<ul>
+<li>
+it simplifies a lot the work of client applications and libraries which
+don't need to perform a function call everytime they want to read one important
+object attribute (nor does it force them to cache these attributes in their
+own structures).</li>
+</ul>
+
+<ul>
+<li>
+It reduces greatly the API, as many <tt>FT_Get_XXX</tt> functions are avoided.</li>
+</ul>
+
+<ul>
+<li>
+Higher-level libraries are able to&nbsp; access data directly. When it
+is used frequently, they don't need to cache it in their own structures.</li>
+</ul>
+
+<ul>
+<li>
+It is possible to tightly link FreeType objects with higher-level ones,
+in a clearer and more efficient way. This is very important when one wants
+to write a C++ wrapper or a text rendering library on top of FreeType (actually,
+both projects were performed in an earlier version of FreeType 2.0 which
+featured classic encapsulation through get/set methods. The resulting code
+was ugly and slow. Moving to a limited encapsulation approach simplified
+so many things that the compiled code size was reduced by a factor of two
+!).</li>
+</ul>
+
+<ul>
+<li>
+Finally, the API and font object structures were designed after the creation
+of two scalable font drivers and one bitmap font driver. They are now very
+stable and the public (visible) attributes are not going to change.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+III. Base objects :</h2>
+
+<blockquote>This section describes the FreeType base object classes :
+<br>&nbsp;
+<h3>
+1. System objects :</h3>
+
+<blockquote>The system class is in charge of managing all low-level and
+system-specific operations. This means simply memory management, i/o access
+and thread synchronisation. It is implemented by the "<tt>ftsys.c</tt>"
+component, whose source must be located in the configuration directory
+when building FreeType. (e.g. "<tt>lib/arch/ansi/ftsys.c</tt>" for an ANSI
+build, "<tt>lib/arch/unix/ftsys.c</tt>" for a Unix one, etc..).
+<p>Porting FreeType 2.0 really means providing a new implementation of
+<tt>ftsys</tt>
+(along with a few configuration file changes). Note however that its interface
+is common to all ports, and located in "<tt>base/ftsys.h</tt>".</blockquote>
+
+<h3>
+2. Resources and Streams:</h3>
+
+<blockquote>The concepts of files as storages, and files as streams has
+been separated for FreeType 2.0. The "<b><i>resource</i></b>" concept was
+introduced while the "<b><i>stream</i></b>" one has been redefined. Here
+is how they work together :
+<ul>
+<li>
+a "<b>resource</b>" is an object which models a file, seen as a storage.
+There are several classes of resources, which differ usually in two ways
+: the way their data is accessed by applications, and the way they're named
+within the system.</li>
+</ul>
+
+<ul>For example, when parsing files with the ANSI C library, data has to
+be read (through fseek/fread) into intermediate buffers before it can be
+decoded. This scheme is highly portable, but rather inefficient; when using
+it, we'll describe the file as a disk-based resource.
+<p>As most modern operating systems now provide memory-mapped files, which
+allow direct access while improving performance and reducing memory usage.
+Because data can be read directly in memory, we'll speak of a memory-based
+resource in this case. For embedded systems (like printers, PDAs, etc..),
+ROM-fonts fit into this category as well.
+<p>Regarding naming, most systems use a string to name files in their storage
+hierarchy. Though a typical pathname is an ASCII string (<tt>'c:\windows\fonts\times.ttf'</tt>
+on Windows, <tt>'/home/fonts/times.ttf'</tt> on Unix), some OSes use different
+schemes, varying from Unicode character strings to file i-node numbers.
+These details are platform-specific and must be hidden to the rest of the
+library in resource objects.
+<p>A resource encapsulates the lowest details regarding a file, though
+it should have NO STATE. Note that the nature or type of a resource (i.e.
+disk or memory based) is important to the "stream" component only. The
+rest of the library and font drivers work transparently from their implementation.
+<p>Note also that it is perfectly possible to mix resources of distinct
+natures in a single build</ul>
+
+<ul>
+<li>
+a "<b>stream</b>" is an object which is used to extract bytes from a resource.
+Only resource objects can create streams, through its <i><tt>Open_Stream()</tt></i>
+method. A stream has state, which typically consist of a file "cursor",
+some intermediate buffers, a "current frame" and, of course, methods used
+to extract the data from streams, resolving endianess and alignement issues.</li>
+</ul>
+Data can be extracted from streams through direct reads, or through the
+use of <b>frames</b>. A frame models <i>a run of contiguous bytes</i> starting
+from the current stream position, and of liberal size.
+<p>Methods exist to extract successive integers of any sizes, while resolving
+endianess and alignement issues. Rather than a long rethorical explanation,
+here's how frames are typically used :
+<blockquote><tt>{</tt>
+<br><tt>&nbsp; Â…</tt>
+<br><tt>&nbsp; FT_Error&nbsp; error;</tt>
+<p><tt>&nbsp; error = FT_Access_Frame( stream, 14 );</tt>
+<br><tt>&nbsp; if (error) goto Fail;</tt>
+<p><tt>&nbsp; val1 = FT_Get_Short(stream);</tt>
+<br><tt>&nbsp; val2 = FT_Get_Long(stream);</tt>
+<br><tt>&nbsp; val3 = FT_Get_Long(stream);</tt>
+<br><tt>&nbsp; val4 = FT_Get_Long(stream);</tt>
+<p><tt>&nbsp; FT_Forget_Frame(stream);</tt>
+<br><tt>&nbsp; Â…</tt>
+<br><tt>}</tt></blockquote>
+This code does the following :
+<blockquote>
+<ol>
+<li>
+&nbsp;first, it "loads" the next 14 bytes from the current cursor position
+into the stream's frame, using the <tt>FT_Access_Frame</tt> API. An error
+is returned if, for example, less than 14 bytes are left in the stream
+when the call occurs..</li>
+</ol>
+
+<ol>
+<li>
+&nbsp;it extract four integers (one 16-bit short, three 32-bit longs) from
+the frame using <tt>FT_Get_Short</tt> and <tt>FT_Get_Long</tt>. These function
+increment the frame's cursor finally, it "releases" the stream's frame.</li>
+</ol>
+
+<ol>
+<li>
+&nbsp;Each stream has its own frame which can be accessed independently,
+however, nested frame accesses are not allowed. Note also that the bytes
+are effectively read from the stream on the call to <tt>FT_Access_Frame</tt>.
+Any subsequent read will occur after these 14 bytes, even if less are extracted
+through <tt>FT_Get_xxxx</tt> functions.</li>
+</ol>
+</blockquote>
+The implementation of the resource class is located in the system component
+(i.e. "<tt>arch/<i>&lt;system></i>/ftsys.c</tt>") and can thus be tailored
+for a specific port of the engine.
+<p>A resource can be created through the <tt>FT_New_Resource</tt> API;
+however this function only accepts an 8-bit pathname to name the target
+font file, which may be inappropriate for systems using a different naming
+scheme (e.g. UTF-16 pathname, i-node number, etc..). It's up to the porter
+then to provide its own resource creation function (like. <tt>FT_New_UTF16_Resource</tt>,
+for example) in its version of "<tt>ftsys.c</tt>".
+<p>Note that <tt>FT_New_Resource</tt> will fail and return an error code
+if the font file cannot be found, or when its font format isn't recognized
+by one of the drivers installed in the library. The list or resources created
+for a given library instance is thus the list of "installed font files".
+<br>&nbsp;</blockquote>
+
+<h3>
+3. Stream Manager :</h3>
+
+<blockquote>As said before, resources do not bear states, while streams
+do. Stream creation is also a very lengthy process, depending on the target
+operating system (e.g. "<tt>fopen</tt>" is usually very slow).
+<p>Because a typical font driver will want to use a new stream on each
+access to individual glyphs, being able to cache the most recently used
+streams is a requirement in order to avoid considerable performance penalties.
+<p>Stream caching is thus implemented in the "<tt>ftstream</tt>" component.
+It maintains a simple LRU list of the least recently used streams. Each
+stream in the cache is still opened and available for immediate processing.
+When a resource is destroyed, the stream cache is parsed to remove all
+related cached streams.
+<p>Stream caching can also be disabled with a configuration macro when
+using only ROM based resources (where stream opening is really quick).
+It is implemented through a Stream Manager object (see <tt>ftstream.c</tt>).
+<br>&nbsp;</blockquote>
+
+<h3>
+4. Raster :</h3>
+
+<blockquote>The raster is the component is charge of generating bitmaps
+and anti-aliased pixmaps from vectorial outline definitions. It is also
+sometimes called the scan-line converter. It has been completely rewritten
+for FreeType 2.0 in order to support third-order bezier arcs, 17-levels
+anti-aliasing (through 4x4 sub-sampling), improved performance, as well
+as stand-alone compilation (in order to include it in other graphics package
+without requiring the rest of the FreeType engine).
+<p>Because it was designed for easy re-use and embedded systems, the raster
+is a rtaher 'unusual' piece of code, because it doesn't perform a single
+memory allocation, nor contain any static or global variable. Rather, it
+is up to client applications to allocate a raster object in their own heap
+or memory space.
+<p>Each raster object also needs a rather large block of memory called
+its render pool. The pool is used during rendering (and only during it)
+in order to perform the scan-line conversion. Because it accesses and manages
+data directly within the pool, the raster yelds impressive performance
+as well as bounded memory consumption. It can also automatically decompose
+large requests into smaller individual sub-tasks.
+<p>Finally, it never creates bitmaps or pixmaps, but simply renders into
+them (providing clipping too). These must be described to the raster with
+the help of a <tt>FT_Raster_Map</tt> structure (a very simple bitmap/pixmap
+descriptor).
+<p>Note that when rendering anti-aliased pixmaps, the raster doesn't use
+an intermediate bitmap buffer, as filtering is part of the scan-line conversion
+process.
+<br>&nbsp;</blockquote>
+
+<h3>
+5. Library objects :</h3>
+
+<blockquote>A library object models a single instance of the FreeType engine.
+This is useful when FreeType is compiled as a shared object (DLL), as it
+can then be used by several applications, each with its own resources and
+objects.
+<p>The <tt>FT_Library</tt> type is an opaque handle to a library object.
+Such an object is created through a call&nbsp; to <tt>FT_Init_FreeType</tt>.
+Once you don't need it anymore, one can destroy a library object through
+<tt>FT_Done_FreeType</tt>.
+<p>Note that in reentrant builds, several threads can access a single library
+object concurrently. Such a build can be chosen by switching one configuration
+macro in the file '<tt>arch/<i>&lt;system></i>/ftconfig.h</tt>'</blockquote>
+
+<h3>
+6. Driver objects :</h3>
+
+<blockquote>A driver object models an instance of a given font driver,
+i.e. an element of FreeType code in charge of handling a given font format,
+like TrueType, Type1, FNT, PCF, etc..
+<p>Each library object contains a given set of driver objects when it is
+created through FT_Init_FreeType, this set being determined at compile
+time (see the file 'base/ftapi.c'). However, removing or adding drivers
+is possible at run-time, in order to make upgrades easy.</blockquote>
+
+<h3>
+7. Diagram</h3>
+
+<blockquote>This diagram show the object relationships for the sole base
+layer. The library object is the root of the object graph :
+<center>
+<p><img SRC="objects_diagram.gif" height=300 width=562></center>
+
+<p>It can be read as follows :
+<br>&nbsp;
+<ul>
+<li>
+Each library object has one system, one raster and one stream manager objects.
+These objects can only belong to one given library.</li>
+</ul>
+
+<ul>
+<li>
+Each library contains one list of 0 or more resources, as well as one list
+of 0 or more driver objects.</li>
+</ul>
+
+<ul>
+<li>
+Each stream manager holds a bounded list ("0..n" where 'n' is the stream
+cache's size) of stream objects. Each stream is related to one given resource
+object. Each resource may be related to zero or one stream.</li>
+</ul>
+
+<ul>
+<li>
+Each resource is related to one driver object. A driver is related to 0
+or more resources.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+IV. Font objects :</h2>
+
+<blockquote>Font objects are used to directly map the information found
+in font files into several categories :
+<br>&nbsp;
+<h3>
+1. Face objects :</h3>
+
+<blockquote>Face objects are used to model individual font faces. They
+encapsulate data which isn't related to a specific character size, or a
+specific glyph or glyph set. Usually, this means :
+<ul>
+<li>
+the font face's family and style names (e.g. "Palatino" + "Regular")</li>
+
+<li>
+some flags indicating which kind of font this is (scalable or fixed ? fixed-width
+or proportional ? horizontal or vertical ? etcÂ…)</li>
+
+<li>
+the number of glyphs, charmaps and eventually fixed character sizes (for
+bitmap formats) found in the font face.</li>
+
+<li>
+for scalable formats, some important metrics like the ascender, descender,
+global font bounding box, maximum advance width, etc.. expressed in notional
+font/grid units (as well as the number of units on the EM grid).</li>
+</ul>
+A face is created from a resource object, with the <tt>FT_New_Face</tt>
+API. Each driver contains a list of opened face objects for the resources
+it manages. When a driver is removed or destroyed, all its child faces
+are discarded automatically with it.</blockquote>
+
+<h3>
+2. Size objects :</h3>
+
+<blockquote>Size objects are used to model a given character dimension
+for a given device resolution (which really means a given character pixel
+dimensions).
+<p>Each size object is created from a parent face object. The object can
+be reset to new dimensions at any time. Each face object holds a list of
+all its child sizes, these are destroyed automatically when the face object
+is discarded.
+<p>The metrics contains metrics, expressed in pixels, for the ascender,
+descender, maximum advance width, etc..
+<br>&nbsp;</blockquote>
+
+<h3>
+3. Glyph Slot objects :</h3>
+
+<blockquote>A glyph slot is a container where one can load individual glyphs,
+be they in vector of bitmap format. Each slot also contains metrics for
+the glyph it contains.
+<p>Each face object contains one or more glyph slot object : the first
+glyph slot is created automatically with its parent face, and it is possible
+to add new glyph slots (this is rarely used outside of debugging purposes).
+<br>&nbsp;</blockquote>
+
+<h3>
+4. CharMap objects :</h3>
+
+<blockquote>A charmap object is a sort of dictionary whose task is to translate
+character codes in a given character encoding (like ShiftJIS, Unicode,
+ANSI, etc..) into glyph indexes in a given font face.
+<p>A face object contains one or more charmap objects. All charmap objects
+are created when the parent face is created, though they're not directly
+visible to client applications (rather, they can be enumerated through
+FT_Get_First_CharMap and FT_Get_Next_CharMap, or more simply picked adequately
+with FT_Find_CharMap for a set of given encodings).
+<br>&nbsp;</blockquote>
+
+<h3>
+5. Diagram</h3>
+
+<blockquote>The following diagram illustrates the relationships between
+font objects :
+<center>
+<p><img SRC="objects_diagram2.gif" height=327 width=561></center>
+
+<p>Which can be read as :
+<br>&nbsp;
+<ul>
+<li>
+each resource may have zero or more child face objects "opened" for it.
+The number of faces is bounded by the number of font faces within the font
+resource.</li>
+</ul>
+
+<ul>
+<li>
+each driver holds a list of all the faces opened for the resources it manages.
+When the driver is removed, its child faces are discarded automatically.</li>
+</ul>
+
+<ul>
+<li>
+each face object has one single parent resource, and one single driver.</li>
+</ul>
+
+<ul>
+<li>
+each face has one or more charmaps, and one or more glyph slots</li>
+</ul>
+
+<ul>
+<li>
+each face holds a list of zero or more child size objects</li>
+</ul>
+
+<ul>
+<li>
+each charmap, glyph slot and size is related to one given parent face.
+These objects are destroyed automatically when the parent face is discarded.</li>
+</ul>
+</blockquote>
+</blockquote>
+
+<p><br>
+<hr WIDTH="100%">
+<h2>
+V. Driver Interface :</h2>
+
+<blockquote>A font driver is added to a given library object through the
+<tt>FT_Add_Driver</tt>
+API. This function receives a structure known as a <tt>FT_DriverInterface</tt>,
+which describes the driver's basic properties.
+<p>The <tt>FT_DriverInterface</tt> contains a set of function pointers
+used for the base FreeType functionalities. However, each driver can also
+provide a font-format-specific extended interface to allow client applications
+to use more advanced features.
+<br>&nbsp;
+<h3>
+1. Common Interface</h3>
+
+<blockquote>The structure of <tt>FT_DriverInterface</tt> is rather simple,
+and defined in "<tt>base/ftdriver.h</tt>". It must be well known by any
+developer who wants to write a new driver for the engine. We advise reading
+the <b><i>FreeType Driver HowTo</i></b> as well as the source code of existing
+drivers. Source comments.</blockquote>
+
+<h3>
+2. Driver-specific extensions</h3>
+
+<blockquote>The field of the <tt>FT_DriverInterface</tt> structure is a
+typeless pointer to a format-specific interface. This extended interface
+is usually a structure containing function pointers as well as other kind
+of information related to the driver.
+<p>It is assumed that client applications that wish to use the driver-specific
+extensions are able to <tt>#include</tt> the relevant header files to understand
+the format-specific interface structure.</blockquote>
+</blockquote>
+
+<hr WIDTH="100%">
+<h2>
+VI. Configuration:</h2>
+
+<blockquote>This section relates to the configuration of the FreeType library.
+By configuration, we mean selection of build options as well as the choice
+of font drivers to be used for each new library object.
+<br>&nbsp;
+<h3>
+1. Configuration files :</h3>
+
+<blockquote>A single file is used to configure the FreeType base engine.
+As it is considered system-specific, it is located in the architecture
+directories of the library, under the name "arch/&lt;system>/ftconfig.h".
+Note that the same directory should also contain a platform-specific implementation
+of "ftsys.c".
+<p>The configuration files is a simple C header which is included by the
+engine's sources during compilation. It is not included in "freetype.h",
+and hence doesn't need to be copied when installing the FreeType headers
+on your system.
+<p>It is made of a series of #define or #undef statements, which are used
+to select or turn off a specific option. Each option is documented with
+heavy comments, and some of them are explained below.</blockquote>
+
+<h3>
+2. Building and Makefiles :</h3>
+
+<blockquote>FreeType 2.0 is more complex than its 1.x release. In order
+to facilitate maintenance, as well as ease considerably the writing of
+new font drivers, <b><i>only GNU Make is supported with FreeType 2.0</i></b>.
+However, it is possible to use any compiler, as well as any object or library
+prefix (<tt>.o, .obj, .a, .lib</tt> etc..) with them.
+<p>To build FreeType 2.0, one has to be in the library directory, then
+invoke its platform-specific makefile. For a Unix system, this would be
+:
+<blockquote>
+<blockquote><tt>% cd freetype2/lib</tt>
+<br><tt>% make -f arch/unix/Makefile</tt>
+<p>where '<tt>make</tt>' is really GNU Make !</blockquote>
+</blockquote>
+The system-specific <tt>Makefile</tt> located in '<tt>arch/<i>&lt;system></i></tt>'
+is a tiny file used to define several variables. It then includes the file
+<tt>freetype2/lib/Makefile.lib</tt>,
+which contains all the gory details about library compilation. The system-specific
+<tt>Makefile</tt> can be very easily modified to accomodate a new compiler/platform
+(see the comments within one of these files).
+<p>Each font driver is located in a directory like "<tt>freetype2/lib/drivers/<i>&lt;formatdir></i></tt>".
+For example, the TrueType driver is located in "<tt>drivers/truetype</tt>".
+Each driver directory must contain a <tt>Makefile</tt> which will be included
+by <tt>Makefile.lib</tt>. The former is used to define and build driver
+object files.
+<br>&nbsp;
+<p><br>
+<center>
+<p><img SRC="build_diagram.gif" height=284 width=559></center>
+</blockquote>
+
+<h3>
+3. Make options :</h3>
+
+<blockquote>The base layer, as well as each font driver, are made up of
+several C sources. Traditionally, one compiles each source (i.e. '<tt>.c</tt>'
+file) into an object ('<tt>.o</tt>' or '<tt>.obj</tt>') file, and all of
+them are grouped into a library file (i.e. '<tt>.a</tt>' or '<tt>.lib</tt>').
+<p>By default, FreeType takes a slightly different approach when it comes
+to compiling each part of the engine. Usually, a single tiny source is
+compiled, which includes all other component sources. This results in a
+single object files, with the benefits or reduced code size, usually better
+compilation as well as a drastic reduction of the number of symbols exported
+by the library. Of course, it is made possible through the use of specific
+declaration macros in the FreeType source (see the definition of <tt>LOCAL_DEF</tt>
+and <tt>LOCAL_FUNC</tt> in <tt>ftconfig.h</tt> for details).
+<p>For a concrete example, see the source code in "<tt>base/ftbase.c</tt>"
+which generates the whole base layer in a single object file. The same
+build process is applied to font drivers, in order to generate one single
+object file per given font format (e.g. <tt>truetype.o</tt>, <tt>type1.o</tt>,
+etc..).
+<p>Compiling the library and drivers in "normal" mode is possible, through
+the use of the '<tt>multi</tt>' target (which really means &laquo; multiple
+objects &raquo;). For example, calling :
+<blockquote><tt>% make -f arch/ansi/Makefile multi</tt></blockquote>
+Will build the FreeType library by compiling each source file to an individual
+object, then linking them together. You'll notice that the library is significantly
+bigger in this case. Creating a shared dll from a 'multi' build is certainly
+a very poor idea, as this will export a huge quantity of symbols that aren't
+useful to any client application.</blockquote>
+
+<h3>
+4. Adding a driver at compile time</h3>
+
+<blockquote>A driver can be included very easily in the build process by
+including its <tt>Makefile</tt> in <tt>Makefile.lib</tt>. For example,
+the TrueType driver is simply included with the following lines (see <tt>Makefile.lib</tt>):
+<blockquote><tt># TrueType driver rules</tt>
+<br><tt>#</tt>
+<br><tt>include $(DRIVERS_DIR)/truetype/Makefile</tt></blockquote>
+
+<p><br>Where <tt>DRIVERS_DIR</tt> really is "<tt>freetype2/lib/drivers</tt>",
+though this can be redefined. You can, of course specify a different path
+if you want to place your driver sources in another location.
+<p>Note that this only adds the driver's object files to the generated
+library file. A few more steps are needed to make your <tt>FT_Library</tt>
+objects use the driver. They consist in modifying the file "<tt>base/ftinit.c</tt>",
+whose sole purpose is to define the set of driver objects that are to be
+created with each new library object.
+<br>&nbsp;</blockquote>
+
+<h3>
+5. Adding a driver at run time</h3>
+
+<blockquote>New driver objects can be added at run-time through the <tt>FT_Add_Driver</tt>
+API. This function takes a handle to an existing library object, as well
+as a pointer to a given driver interface. This interface is used to create
+a new driver object and register it within the library.
+<p>Similarly, a single driver can be removed from a library anytime through
+<tt>FT_Remove_Driver</tt>.
+This will automatically discard the resources and face objects managed
+by the driver.</blockquote>
+
+<h3>
+6. Custom library objects :</h3>
+
+<blockquote>Finally, it is possible to build custom library objects. You
+need to pass a handle to a valid <tt>FT_System</tt> object to the <tt>FT_Build_Library</tt>
+API. The function will return a handle to the new fresh library object.
+Note that the library has no registered drivers after the call, developers
+have to add them by hand with <tt>FT_Add_Driver</tt>.
+<p>It is thus possible to create two distinct library objects with distinct
+<tt>FT_System</tt>
+implementations in the same session, which can be useful for debugging
+purpose.</blockquote>
+
+<br>&nbsp;</blockquote>
+
+</body>
+</html>
diff --git a/include/freetype.h b/include/freetype.h
new file mode 100644
index 0000000..4edaec5
--- /dev/null
+++ b/include/freetype.h
@@ -0,0 +1,2156 @@
+/***************************************************************************/
+/*                                                                         */
+/*  freetype.h                                                             */
+/*                                                                         */
+/*    FreeType high-level API and common types (specification only).       */
+/*                                                                         */
+/*  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 FREETYPE_H
+#define FREETYPE_H
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The `raster' component duplicates some of the declarations in         */
+  /* freetype.h for stand-alone use if _FREETYPE_ isn't defined.           */
+  /*                                                                       */
+#define _FREETYPE_
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The FREETYPE_MAJOR and FREETYPE_MINOR macros are used to version the  */
+  /* new FreeType design, which is able to host several kinds of font      */
+  /* drivers.  It starts at 2.0.  Note that each driver has its own        */
+  /* version number (for example, the TrueType driver is at 1.2, as        */
+  /* defined by the macros TT_FREETYPE_MAJOR and TT_FREETYPE_MINOR in the  */
+  /* file `ttlib/truetype.h'.                                              */
+  /*                                                                       */
+#define FREETYPE_MAJOR 2
+#define FREETYPE_MINOR 0
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* To make freetype.h independent from configuration files we check      */
+  /* whether EXPORT_DEF has been defined already.                          */
+  /*                                                                       */
+  /* On some systems and compilers (Win32 mostly), an extra keyword is     */
+  /* necessary to compile the library as a DLL.                            */
+  /*                                                                       */
+#ifndef EXPORT_DEF
+#define EXPORT_DEF  extern
+#endif
+
+#include <fterrors.h>
+#include <ftsystem.h>
+#include <ftimage.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Bool                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef of unsigned char, used for simple booleans.              */
+  /*                                                                       */
+  typedef unsigned char  FT_Bool;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_FWord                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 16-bit integer used to store a distance in original font  */
+  /*    units.                                                             */
+  /*                                                                       */
+  typedef signed short    FT_FWord;   /* Distance in FUnits */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_UFWord                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An unsigned 16-bit integer used to store a distance in original    */
+  /*    font units.                                                        */
+  /*                                                                       */
+  typedef unsigned short  FT_UFWord;  /* Unsigned distance */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Char                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the _signed_ char type.                       */
+  /*                                                                       */
+  typedef signed char  FT_Char;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Byte                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the _unsigned_ char type.                     */
+  /*                                                                       */
+  typedef unsigned char  FT_Byte;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_String                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the char type, usually used for strings.      */
+  /*                                                                       */
+  typedef char  FT_String;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Short                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for signed short.                                        */
+  /*                                                                       */
+  typedef signed short  FT_Short;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_UShort                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for unsigned short.                                      */
+  /*                                                                       */
+  typedef unsigned short  FT_UShort;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Int                                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for the int type.                                        */
+  /*                                                                       */
+  typedef int  FT_Int;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_UInt                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for the unsigned int type.                               */
+  /*                                                                       */
+  typedef unsigned int  FT_UInt;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Long                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for signed long.                                         */
+  /*                                                                       */
+  typedef signed long  FT_Long;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_ULong                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for unsigned long.                                       */
+  /*                                                                       */
+  typedef unsigned long  FT_ULong;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_F2Dot14                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 2.14 fixed float type used for unit vectors.              */
+  /*                                                                       */
+  typedef signed short  FT_F2Dot14;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_F26Dot6                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 26.6 fixed float type used for vectorial pixel            */
+  /*    coordinates.                                                       */
+  /*                                                                       */
+  typedef signed long  FT_F26Dot6;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Fixed                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This type is used to store 16.16 fixed float values, like scales   */
+  /*    or matrix coefficients.                                            */
+  /*                                                                       */
+  typedef signed long  FT_Fixed;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Error                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The FreeType error code type.  A value of 0 is always interpreted  */
+  /*    as a successful operation.                                         */
+  /*                                                                       */
+  typedef int  FT_Error;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_UnitVector                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2d vector unit vector.  Uses    */
+  /*    FT_F2Dot14 types.                                                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    x :: Horizontal coordinate.                                        */
+  /*    y :: Vertical coordinate.                                          */
+  /*                                                                       */
+  typedef struct  FT_UnitVector_
+  {
+    FT_F2Dot14  x;
+    FT_F2Dot14  y;
+
+  } FT_UnitVector;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Matrix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2x2 matrix.  Coefficients are   */
+  /*    in 16.16 fixed float format.  The computation performed is:        */
+  /*                                                                       */
+  /*       {                                                               */
+  /*          x' = x*xx + y*xy                                             */
+  /*          y' = x*yx + y*yy                                             */
+  /*       }                                                               */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    xx :: Matrix coefficient.                                          */
+  /*    xy :: Matrix coefficient.                                          */
+  /*    yx :: Matrix coefficient.                                          */
+  /*    yy :: Matrix coefficient.                                          */
+  /*                                                                       */
+  typedef struct  FT_Matrix_
+  {
+    FT_Fixed  xx, xy;
+    FT_Fixed  yx, yy;
+
+  } FT_Matrix;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_BBox                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold an outline's bounding box, i.e., the      */
+  /*    coordinates of its extrema in the horizontal and vertical          */
+  /*    directions.                                                        */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    xMin :: The horizontal minimum (left-most).                        */
+  /*    yMin :: The vertical minimum (bottom-most).                        */
+  /*    xMax :: The horizontal maximum (right-most).                       */
+  /*    yMax :: The vertical maximum (top-most).                           */
+  /*                                                                       */
+  typedef struct  FT_BBox_
+  {
+    FT_Pos  xMin, yMin;
+    FT_Pos  xMax, yMax;
+
+  } FT_BBox;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_MAKE_TAG                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This macro converts four letter tags which are used to label       */
+  /*    TrueType tables into an unsigned long to be used within FreeType.  */
+  /*                                                                       */
+#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
+          (((FT_ULong)_x1 << 24) |        \
+           ((FT_ULong)_x2 << 16) |        \
+           ((FT_ULong)_x3 << 8)  |        \
+            (FT_ULong)_x4)
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*                                                                       */
+  /*                    L I S T   M A N A G E M E N T                      */
+  /*                                                                       */
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_ListNode                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*     Many elements and objects in FreeType are listed through a        */
+  /*     FT_List record (see FT_ListRec).  As its name suggests, a         */
+  /*     FT_ListNode is a handle to a single list element.                 */
+  /*                                                                       */
+  typedef struct FT_ListNodeRec_*  FT_ListNode;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_List                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a list record (see FT_ListRec).                        */
+  /*                                                                       */
+  typedef struct FT_ListRec_*  FT_List;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_ListNodeRec                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold a single list element.                    */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    prev :: Previous element in the list.  NULL if first.              */
+  /*    next :: Next element in the list.  NULL if last.                   */
+  /*    data :: Typeless pointer to the listed object.                     */
+  /*                                                                       */
+  typedef struct  FT_ListNodeRec_
+  {
+    FT_ListNode  prev;
+    FT_ListNode  next;
+    void*        data;
+
+  } FT_ListNodeRec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_ListRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold a simple doubly-linked list.  These are   */
+  /*    used in many parts of FreeType.                                    */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    head :: Head (first element) of doubly-linked list.                */
+  /*    tail :: Tail (last element) of doubly-linked list.                 */
+  /*                                                                       */
+  typedef struct  FT_ListRec_
+  {
+    FT_ListNode  head;
+    FT_ListNode  tail;
+
+  } FT_ListRec;
+
+
+#define FT_IS_EMPTY(list)  ( (list).head == 0 )
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*                                                                       */
+  /*                        B A S I C   T Y P E S                          */
+  /*                                                                       */
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Glyph_Metrics                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model the metrics of a single glyph.  Note     */
+  /*    that values are expressed in 26.6 fractional pixel format or in    */
+  /*    font units, depending on context.                                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    width        :: The glyph's width.                                 */
+  /*    height       :: The glyph's height.                                */
+  /*                                                                       */
+  /*    horiBearingX :: Horizontal left side bearing.                      */
+  /*    horiBearingY :: Horizontal top side bearing.                       */
+  /*    horiAdvance  :: Horizontal advance width.                          */
+  /*                                                                       */
+  /*    vertBearingX :: Vertical left side bearing.                        */
+  /*    vertBearingY :: Vertical top side bearing.                         */
+  /*    vertAdvance  :: Vertical advance height.                           */
+  /*                                                                       */
+  typedef struct  FT_Glyph_Metrics_
+  {
+    FT_Pos  width;         /* glyph width  */
+    FT_Pos  height;        /* glyph height */
+
+    FT_Pos  horiBearingX;  /* left side bearing in horizontal layouts */
+    FT_Pos  horiBearingY;  /* top side bearing in horizontal layouts  */
+    FT_Pos  horiAdvance;   /* advance width for horizontal layout     */
+
+    FT_Pos  vertBearingX;  /* left side bearing in vertical layouts */
+    FT_Pos  vertBearingY;  /* top side bearing in vertical layouts  */
+    FT_Pos  vertAdvance;   /* advance height for vertical layout    */
+
+  } FT_Glyph_Metrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Generic_Finalizer                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Describes a function used to destroy the `client' data of any      */
+  /*    FreeType object.  See the description of the FT_Generic type for   */
+  /*    details of usage.                                                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    The address of the FreeType object which is under finalisation.    */
+  /*    Its client data is accessed through its `generic' field.           */
+  /*                                                                       */
+  typedef void  (*FT_Generic_Finalizer)(void*  object);
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Generic                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Client applications often need to associate their own data to a    */
+  /*    variety of FreeType core objects.  For example, a text layout API  */
+  /*    might want to associate a glyph cache to a given size object.      */
+  /*                                                                       */
+  /*    Most FreeType object contains a `generic' field, of type           */
+  /*    FT_Generic, which usage is left to client applications and font    */
+  /*    servers.                                                           */
+  /*                                                                       */
+  /*    It can be used to store a pointer to client-specific data, as well */
+  /*    as the address of a `finalizer' function, which will be called by  */
+  /*    FreeType when the object is destroyed (for example, the previous   */
+  /*    client example would put the address of the glyph cache destructor */
+  /*    in the `finalizer' field).                                         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    data      :: A typeless pointer to any client-specified data. This */
+  /*                 field is completely ignored by the FreeType library.  */
+  /*                                                                       */
+  /*    finalizer :: A pointer to a `generic finalizer' function, which    */
+  /*                 will be called when the object is destroyed.  If this */
+  /*                 field is set to NULL, no code will be called.         */
+  /*                                                                       */
+  typedef struct  FT_Generic_
+  {
+    void*                 data;
+    FT_Generic_Finalizer  finalizer;
+
+  } FT_Generic;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Bitmap_Size                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An extremely simple structure used to model the size of a bitmap   */
+  /*    strike (i.e., a bitmap instance of the font for a given            */
+  /*    resolution) in a fixed-size font face.  This is used for the       */
+  /*    `available_sizes' field of the FT_Face_Properties structure.       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    height :: The character height in pixels.                          */
+  /*    width  :: The character width in pixels.                           */
+  /*                                                                       */
+  typedef struct  FT_Bitmap_Size_
+  {
+    FT_Short  height;
+    FT_Short  width;
+
+  } FT_Bitmap_Size;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*                                                                       */
+  /*                     O B J E C T   C L A S S E S                       */
+  /*                                                                       */
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Library                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a FreeType library instance.  Each `library' is        */
+  /*    completely independent from the others; it is the `root' of a set  */
+  /*    of objects like fonts, faces, sizes, etc.                          */
+  /*                                                                       */
+  /*    It also embeds a system object (see FT_System), as well as a       */
+  /*    scan-line converter object (see FT_Raster).                        */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Library objects are created through FT_Init_FreeType().            */
+  /*                                                                       */
+  typedef struct FT_LibraryRec_  *FT_Library;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Driver                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a given FreeType font driver object.  Each font driver */
+  /*    is able to create faces, sizes, glyph slots, and charmaps from the */
+  /*    resources whose format it supports.                                */
+  /*                                                                       */
+  /*    A driver can support either bitmap, graymap, or scalable font      */
+  /*    formats.                                                           */
+  /*                                                                       */
+  typedef struct FT_DriverRec_*  FT_Driver;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Face                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a given driver face object.  A face object contains    */
+  /*    all the instance and glyph independent data of a font file         */
+  /*    typeface.                                                          */
+  /*                                                                       */
+  /*    A face object is created from a resource object through the        */
+  /*    new_face() method of a given driver.                               */
+  /*                                                                       */
+  typedef struct FT_FaceRec_*  FT_Face;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Size                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a given driver size object.  Such an object models the */
+  /*    _resolution_ AND _size_ dependent state of a given driver face     */
+  /*    size.                                                              */
+  /*                                                                       */
+  /*    A size object is always created from a given face object.  It is   */
+  /*    discarded automatically by its parent face.                        */
+  /*                                                                       */
+  typedef struct FT_SizeRec_*  FT_Size;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_GlyphSlot                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a given `glyph slot'.  A slot is a container where it  */
+  /*    is possible to load any of the glyphs contained within its parent  */
+  /*    face.                                                              */
+  /*                                                                       */
+  /*    A glyph slot is created from a given face object.  It is discarded */
+  /*    automatically by its parent face.                                  */
+  /*                                                                       */
+  typedef struct FT_GlyphSlotRec_*  FT_GlyphSlot;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_CharMap                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a given character map.  A charmap is used to translate */
+  /*    character codes in a given encoding into glyph indexes for its     */
+  /*    parent's face.  Some font formats may provide several charmaps per */
+  /*    font.                                                              */
+  /*                                                                       */
+  /*    A charmap is created from a given face object.  It is discarded    */
+  /*    automatically by its parent face.                                  */
+  /*                                                                       */
+  typedef struct FT_CharMapRec_*  FT_CharMap;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Enum>                                                                */
+  /*    FT_Encoding                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An enumeration used to specify encodings supported by charmaps.    */
+  /*    Used in the FT_Select_CharMap() API function.                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */
+  /*    all character codes must be expressed as FT_Longs.                 */
+  /*                                                                       */
+  typedef enum  FT_Encoding_
+  {
+    ft_encoding_none    = 0,
+    ft_encoding_symbol  = 0,
+    ft_encoding_unicode = FT_MAKE_TAG('u','n','i','c'),
+    ft_encoding_latin_2 = FT_MAKE_TAG('l','a','t','2'),
+    ft_encoding_sjis    = FT_MAKE_TAG('s','j','i','s'),
+    ft_encoding_big5    = FT_MAKE_TAG('b','i','g','5'),
+
+    ft_encoding_adobe_standard = FT_MAKE_TAG('a','d','o','b'),
+    ft_encoding_adobe_expert   = FT_MAKE_TAG('a','d','b','e'),    
+
+    ft_encoding_apple_roman    = FT_MAKE_TAG('a','r','m','n')
+
+    /* other encodings might be defined in the future */
+
+  } FT_Encoding;
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_CharMapRec                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The base charmap class.                                            */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    face        :: A handle to the parent face object.                 */
+  /*                                                                       */
+  /*    flags       :: A set of bit flags used to describe the charmap.    */
+  /*                   Each bit indicates that a given encoding is         */
+  /*                   supported.                                          */
+  /*                                                                       */
+  /*    platform_id :: An ID number describing the platform for the        */
+  /*                   following encoding ID.  This comes directly from    */
+  /*                   the TrueType specification and should be emulated   */
+  /*                   for other formats.                                  */
+  /*                                                                       */
+  /*    encoding_id :: A platform specific encoding number.  This also     */
+  /*                   comes from the TrueType specification and should be */
+  /*                   emulated similarly.                                 */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    We STRONGLY recommmend emulating a Unicode charmap for drivers     */
+  /*    that do not support TrueType or OpenType.                          */
+  /*                                                                       */
+  typedef struct  FT_CharMapRec_
+  {
+    FT_Face      face;
+    FT_Encoding  encoding;
+    FT_UShort    platform_id;
+    FT_UShort    encoding_id;
+
+  } FT_CharMapRec;
+
+
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*                                                                       */
+  /*                 B A S E   O B J E C T   C L A S S E S                 */
+  /*                                                                       */
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                       FreeType base face class                        */
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_FaceRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    FreeType root face class structure.  A face object models the      */
+  /*    resolution and point-size independent data found in a font file.   */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    driver              :: A handle to the face's parent driver        */
+  /*                           object.                                     */
+  /*                                                                       */
+  /*    memory              :: A handle to the face's parent memory        */
+  /*                           object.  Used for the allocation of         */
+  /*                           subsequent objects.                         */
+  /*                                                                       */
+  /*    stream              :: A handle to the face's stream.              */
+  /*                                                                       */
+  /*    num_faces           :: In the case where the face is located in a  */
+  /*                           collection (i.e., a resource which embeds   */
+  /*                           several faces), this is the total number of */
+  /*                           faces found in the resource.  1 by default. */
+  /*                                                                       */
+  /*    face_index          :: The index of the face in its resource.      */
+  /*                           Usually, this is 0 for all normal font      */
+  /*                           formats.  It can be more in the case of     */
+  /*                           collections (which embed several fonts in a */
+  /*                           single resource/file).                      */
+  /*                                                                       */
+  /*    generic             :: A field reserved for client uses.  See the  */
+  /*                           FT_Generic type description.                */
+  /*                                                                       */
+  /*    glyph               :: The face's associated glyph slot(s).  This  */
+  /*                           object is created automatically with a new  */
+  /*                           face object.  However, certain kinds of     */
+  /*                           applications (mainly tools like converters) */
+  /*                           can need more than one slot to ease their   */
+  /*                           task.                                       */
+  /*                                                                       */
+  /*    sizes_list          :: The list of child sizes for this face.      */
+  /*                                                                       */
+  /*    face_flags          :: A set of bit flags that give important      */
+  /*                           information about the face; see the         */
+  /*                           FT_FACE_FLAG_XXX macros for details.        */
+  /*                                                                       */
+  /*    style_flags         :: A set of bit flags indicating the style of  */
+  /*                           the face (i.e., italic, bold, underline,    */
+  /*                           etc).                                       */
+  /*                                                                       */
+  /*    num_glyphs          :: The total number of glyphs in the face.     */
+  /*                                                                       */
+  /*    num_charmaps        :: The total number of character maps in the   */
+  /*                           face.                                       */
+  /*                                                                       */
+  /*    family_name         :: The face's family name.  This is an ASCII   */
+  /*                           string, usually in English, which describes */
+  /*                           the typeface's family (like `Times New      */
+  /*                           Roman', `Bodoni', `Garamond', etc).  This   */
+  /*                           is a least common denominator used to list  */
+  /*                           fonts.  Some formats (TrueType & OpenType)  */
+  /*                           provide localized and Unicode versions of   */
+  /*                           this string.  Applications should use the   */
+  /*                           format specific interface to access them.   */
+  /*                                                                       */
+  /*    style_name          :: The face's style name.  This is an ASCII    */
+  /*                           string, usually in English, which describes */
+  /*                           the typeface's style (like `Italic',        */
+  /*                           `Bold', `Condensed', etc).  Not all font    */
+  /*                           formats provide a style name, so this field */
+  /*                           is optional, and can be set to NULL.  As    */
+  /*                           for `family_name', some formats provide     */
+  /*                           localized/Unicode versions of this string.  */
+  /*                           Applications should use the format specific */
+  /*                           interface to access them.                   */
+  /*                                                                       */
+  /*    num_fixed_sizes     :: The number of fixed sizes available in this */
+  /*                           face.  This should be set to 0 for scalable */
+  /*                           fonts, unless its resource includes a       */
+  /*                           complete set of glyphs (called a `strike')  */
+  /*                           for the specified size.                     */
+  /*                                                                       */
+  /*    available_sizes     :: An array of sizes specifying the available  */
+  /*                           bitmap/graymap sizes that are contained in  */
+  /*                           in the font resource.  Should be set to     */
+  /*                           NULL if the field `num_fixed_sizes' is set  */
+  /*                           to 0.                                       */
+  /*                                                                       */
+  /*    bbox                :: The font bounding box.  Coordinates are     */
+  /*                           expressed in font units (see units_per_EM). */
+  /*                           The box is large enough to contain any      */
+  /*                           glyph from the font.  Thus, bbox.yMax can   */
+  /*                           be seen as the `maximal ascender',          */
+  /*                           bbox.yMin as the `minimal descender', and   */
+  /*                           the maximum glyph width is given by         */
+  /*                           `bbox.xMax-bbox.xMin' (not to be confused   */
+  /*                           with the maximum _advance_width_).  Only    */
+  /*                           relevant for scalable formats.              */
+  /*                                                                       */
+  /*    units_per_EM        :: The number of font units per EM square for  */
+  /*                           this face.  This is typically 2048 for      */
+  /*                           TrueType fonts, 1000 for Type1 fonts, and   */
+  /*                           should be set to the (unrealistic) value 1  */
+  /*                           for fixed-sizes fonts.  Only relevant for   */
+  /*                           scalable formats.                           */
+  /*                                                                       */
+  /*    ascender            :: The face's ascender is the vertical         */
+  /*                           distance from the baseline to the topmost   */
+  /*                           point of any glyph in the face.  This       */
+  /*                           field's value is positive, expressed in     */
+  /*                           font units.  Some font designs use a value  */
+  /*                           different from `bbox.yMax'.  Only relevant  */
+  /*                           for scalable formats.                       */
+  /*                                                                       */
+  /*    descender           :: The face's descender is the vertical        */
+  /*                           distance from the baseline to the           */
+  /*                           bottommost point of any glyph in the face.  */
+  /*                           This field's value is positive, expressed   */
+  /*                           in font units.  Some font designs use a     */
+  /*                           value different from `-bbox.yMin'.  Only    */
+  /*                           relevant for scalable formats.              */
+  /*                                                                       */
+  /*    height              :: The face's height is the vertical distance  */
+  /*                           from one baseline to the next when writing  */
+  /*                           several lines of text.  Its value is always */
+  /*                           positive, expressed in font units.  The     */
+  /*                           value can be computed as                    */
+  /*                           `ascender+descender+line_gap' where the     */
+  /*                           value of `line_gap' is also called          */
+  /*                           `external leading'.  Only relevant for      */
+  /*                           scalable formats.                           */
+  /*                                                                       */
+  /*    max_advance_width   :: The maximum advance width, in font units,   */
+  /*                           for all glyphs in this face.  This can be   */
+  /*                           used to make word wrapping computations     */
+  /*                           faster.  Only relevant for scalable         */
+  /*                           formats.                                    */
+  /*                                                                       */
+  /*    max_advance_height  :: The maximum advance height, in font units,  */
+  /*                           for all glyphs in this face.  This is only  */
+  /*                           relevant for vertical layouts, and should   */
+  /*                           be set to the `height' for fonts that do    */
+  /*                           not provide vertical metrics.  Only         */
+  /*                           relevant for scalable formats.              */
+  /*                                                                       */
+  /*    underline_position  :: The position, in font units, of the         */
+  /*                           underline line for this face.  It's the     */
+  /*                           center of the underlining stem.  Only       */
+  /*                           relevant for scalable formats.              */
+  /*                                                                       */
+  /*    underline_thickness :: The thickness, in font units, of the        */
+  /*                           underline for this face.  Only relevant for */
+  /*                           scalable formats.                           */
+  /*                                                                       */
+  /*    max_points          :: The maximum number of points used to store  */
+  /*                           the vectorial outline of any glyph in this  */
+  /*                           face.  If this value cannot be known in     */
+  /*                           advance, or if the face isn't scalable,     */
+  /*                           this should be set to 0.  Only relevant for */
+  /*                           scalable formats.                           */
+  /*                                                                       */
+  /*    max_contours        :: The maximum number of contours used to      */
+  /*                           store the vectorial outline of any glyph in */
+  /*                           this face.  If this value cannot be known   */
+  /*                           in advance, or if the face isn't scalable,  */
+  /*                           this should be set to 0.  Only relevant for */
+  /*                           scalable formats.                           */
+  /*                                                                       */
+  typedef struct  FT_FaceRec_
+  {
+    FT_Driver        driver;
+    FT_Memory        memory;
+    FT_Stream        stream;
+
+    FT_Long          num_faces;
+    FT_Long          face_index;
+
+    /* a generic pointer for client use */
+    FT_Generic       generic;
+
+    /* the face's current glyph slot(s) */
+    FT_GlyphSlot     glyph;
+
+    /* the face's current size, may be nil */
+    FT_Size          size;
+
+    /* the face's current charmap */
+    FT_CharMap       charmap;
+    
+    /* the face's table of available charmaps */
+    FT_Int           num_charmaps;
+    FT_CharMap*      charmaps;
+
+    /* the face's current sizes list */
+    FT_ListRec       sizes_list;
+
+    /* a pointer to the face's extensions block, if supported */
+    void*            extensions;
+
+    FT_Long          face_flags;
+    FT_Long          style_flags;
+
+    FT_Long          num_glyphs;
+
+    FT_String*       family_name;
+    FT_String*       style_name;
+
+    FT_Int           num_fixed_sizes;
+    FT_Bitmap_Size*  available_sizes;
+
+    /* the following are only relevant for scalable outlines */
+
+    FT_BBox          bbox;
+
+    FT_UShort        units_per_EM;
+    FT_Short         ascender;
+    FT_Short         descender;
+    FT_Short         height;
+
+    FT_Short         max_advance_width;
+    FT_Short         max_advance_height;
+
+    FT_Short         underline_position;
+    FT_Short         underline_thickness;
+
+    FT_UShort        max_points;
+    FT_Short         max_contours;
+
+  } FT_FaceRec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_SCALABLE                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that a given face provides  */
+  /*    vectorial outlines (i.e., TrueType or Type1).  This doesn't        */
+  /*    prevent embedding of bitmap strikes though, i.e., a given face can */
+  /*    have both this bit set, and a `num_fixed_sizes' property > 0.      */
+  /*                                                                       */
+#define FT_FACE_FLAG_SCALABLE  1
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_FIXED_WIDTH                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that a given face contains  */
+  /*    fixed-width characters (like Courier, MonoType, etc).              */
+  /*                                                                       */
+#define FT_FACE_FLAG_FIXED_WIDTH  4
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_FIXED_WIDTH                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that a given face contains  */
+  /*    `fixed sizes', i.e., bitmap strikes for some given pixel sizes.    */
+  /*    See the `num_fixed_sizes' and `available_sizes' face properties    */
+  /*    for more information.                                              */
+  /*                                                                       */
+#define FT_FACE_FLAG_FIXED_SIZES  2
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_SFNT                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that a given face uses the  */
+  /*    `sfnt' storage fomat.  For now, this means TrueType or OpenType.   */
+  /*                                                                       */
+#define FT_FACE_FLAG_SFNT  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_HORIZONTAL                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that a given face contains  */
+  /*    horizontal glyph metrics.  This should be set for all common       */
+  /*    formats, but who knows...                                          */
+  /*                                                                       */
+#define FT_FACE_FLAG_HORIZONTAL  0x10
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_VERTICAL                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that a given face contains  */
+  /*    vertical glyph metrics.  If not set, the glyph loader will         */
+  /*    synthetize vertical metrics itself to help display vertical text   */
+  /*    correctly.                                                         */
+  /*                                                                       */
+#define FT_FACE_FLAG_VERTICAL  0x20
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_KERNING                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that a given face contains  */
+  /*    kerning information.  When set, this information can be retrieved  */
+  /*    through the function FT_Get_Kerning().  Note that when unset, this */
+  /*    function will always return the kerning vector (0,0).              */
+  /*                                                                       */
+#define FT_FACE_FLAG_KERNING  0x40
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_FAST_GLYPHS                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that the glyphs in a given  */
+  /*    font can be retrieved very quickly, and that a glyph cache is thus */
+  /*    not necessary for any of its child size objects.                   */
+  /*                                                                       */
+  /*    This flag should really be set for fixed-size formats like FNT,    */
+  /*    where each glyph bitmap is available directly in binary form       */
+  /*    without any kind of compression.                                   */
+  /*                                                                       */
+#define FT_FACE_FLAG_FAST_GLYPHS  0x80
+
+
+#define FT_HAS_HORIZONTAL(face)  (face->face_flags & FT_FACE_FLAG_HORIZONTAL)
+#define FT_HAS_VERTICAL(face)    (face->face_flags & FT_FACE_FLAG_VERTICAL)
+#define FT_HAS_KERNING(face)     (face->face_flags & FT_FACE_FLAG_KERNING)
+#define FT_IS_SCALABLE(face)     (face->face_flags & FT_FACE_FLAG_SCALABLE)
+#define FT_IS_SFNT(face)         (face->face_flags & FT_FACE_FLAG_SFNT)
+#define FT_IS_FIXED_WIDTH(face)  (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH)
+#define FT_HAS_FIXED_SIZES(face) (face->face_flags & FT_FACE_FLAG_FIXED_SIZES)
+#define FT_HAS_FAST_GLYPHS(face) (face->face_flags & FT_FACE_FLAG_FAST_GLYPHS)
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_STYLE_FLAG_ITALIC                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that a given face is        */
+  /*    italicized.                                                        */
+  /*                                                                       */
+#define FT_STYLE_FLAG_ITALIC  1
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_STYLE_FLAG_BOLD                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used to indicate that a given face is        */
+  /*    emboldened.                                                        */
+  /*                                                                       */
+#define FT_STYLE_FLAG_BOLD  2
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                    FreeType base size metrics                         */
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Size_Metrics                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The size metrics structure returned scaled important distances for */
+  /*    a given size object.                                               */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    pointSize    :: The current point size in 26.6 points, where       */
+  /*                    1 point equals 1/72 inch.                          */
+  /*                                                                       */
+  /*    x_ppem       :: The character width, expressed in integer pixels.  */
+  /*                    This is the width of the EM square expressed in    */
+  /*                    pixels, hence the term `ppem' (pixels per EM).     */
+  /*                                                                       */
+  /*    y_ppem       :: The character height, expressed in integer pixels. */
+  /*                    This is the height of the EM square expressed in   */
+  /*                    pixels, hence the term `ppem' (pixels per EM).     */
+  /*                                                                       */
+  /*    x_scale      :: A simple 16.16 fixed point format coefficient used */
+  /*                    to scale horizontal distances expressed in font    */
+  /*                    units to fractional (26.6) pixel coordinates.      */
+  /*                                                                       */
+  /*    y_scale      :: A simple 16.16 fixed point format coefficient used */
+  /*                    to scale vertical distances expressed in font      */
+  /*                    units to fractional (26.6) pixel coordinates.      */
+  /*                                                                       */
+  /*    x_resolution :: The horizontal device resolution for this size     */
+  /*                    object, expressed in integer dots per inches       */
+  /*                    (dpi).  As a convention, fixed font formats set    */
+  /*                    this value to 72.                                  */
+  /*                                                                       */
+  /*    y_resolution :: The vertical device resolution for this size       */
+  /*                    object, expressed in integer dots per inches       */
+  /*                    (dpi).  As a convention, fixed font formats set    */
+  /*                    this value to 72.                                  */
+  /*                                                                       */
+  /*    ascender     :: The ascender, expressed in 26.6 fixed point        */
+  /*                    pixels.  Always positive.                          */
+  /*                                                                       */
+  /*    descender    :: The descender, expressed in 26.6 fixed point       */
+  /*                    pixels.  Always positive.                          */
+  /*                                                                       */
+  /*    height       :: The text height, expressed in 26.6 fixed point     */
+  /*                    pixels.  Always positive.                          */
+  /*                                                                       */
+  /*    max_advance  :: Maximum horizontal advance, expressed in 26.6      */
+  /*                    fixed point pixels.  Always positive.              */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This structure doesn't return the vertical ascender, descender,    */
+  /*    and height, as well as a few other esoteric properties.  One can   */
+  /*    however compute these through the size's x_scale and y_scale,      */
+  /*    applied to the relevant face properties.                           */
+  /*                                                                       */
+  typedef struct  FT_Size_Metrics_
+  {
+    FT_UShort   x_ppem;        /* horizontal pixels per EM               */
+    FT_UShort   y_ppem;        /* vertical pixels per EM                 */
+
+    FT_Fixed    x_scale;       /* two scales used to convert font units  */
+    FT_Fixed    y_scale;       /* to 26.6 frac. pixel coordinates..      */
+
+    FT_Pos      ascender;      /* ascender in 26.6 frac. pixels          */
+    FT_Pos      descender;     /* descender in 26.6 frac. pixels         */
+    FT_Pos      height;        /* text height in 26.6 frac. pixels       */
+    FT_Pos      max_advance;   /* max horizontal advance, in 26.6 pixels */
+
+  } FT_Size_Metrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                       FreeType base size class                        */
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_SizeRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    FreeType root size class structure.  A size object models the      */
+  /*    resolution and pointsize dependent data of a given face.           */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    face    :: Handle to the parent face object.                       */
+  /*                                                                       */
+  /*    generic :: A typeless pointer, which is unused by the FreeType     */
+  /*               library or any of its drivers.  It can be used by       */
+  /*               client applications to link their own data to each size */
+  /*               object.                                                 */
+  /*                                                                       */
+  /*    metrics :: Metrics for this size object.  This field is read-only. */
+  /*                                                                       */
+  typedef struct  FT_SizeRec_
+  {
+    FT_Face          face;      /* parent face object              */
+    FT_Generic       generic;   /* generic pointer for client uses */
+    FT_Size_Metrics  metrics;   /* size metrics                    */
+
+  } FT_SizeRec;
+
+
+
+  typedef struct FT_SubGlyph_  FT_SubGlyph;
+  
+  struct FT_SubGlyph_
+  {
+    FT_Int        index;
+    
+    FT_Byte*      control_data;
+    FT_Int        control_len;
+    
+    FT_UShort     flags;
+    
+    FT_Int        arg1;
+    FT_Int        arg2;
+    
+    FT_Matrix     transform;
+    FT_SubGlyph*  parent;
+  };
+
+
+#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS            1
+#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES        2
+#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID          4
+#define FT_SUBGLYPH_FLAG_SCALE                     8
+#define FT_SUBGLYPH_FLAG_XY_SCALE               0x40
+#define FT_SUBGLYPH_FLAG_2X2                    0x80
+#define FT_SUBGLYPH_FLAG_USE_MY_METRICS        0x200
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                  FreeType Glyph Slot base class                       */
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_GlyphSlotRec                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    FreeType root glyph slot class structure. A glyph slot is a        */
+  /*    container where individual glyphs can be loaded, be they           */
+  /*    vectorial or bitmap/graymaps..                                     */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    face     :: A handle to the parent face object.                    */
+  /*                                                                       */
+  /*    next     :: In some cases (like some font tools), several glyph    */
+  /*                slots per face object can be a good thing.  As this is */
+  /*                rare, the glyph slots are listed through a direct,     */
+  /*                single-linked list using its `next' field.             */
+  /*                                                                       */
+  /*    metrics  :: The metrics of the last loaded glyph in the slot.  The */
+  /*                returned values depend on the last load flags (see the */
+  /*                FT_Load_Glyph() API function) and can be expressed     */
+  /*                either in 26.6 fractional pixels or font units.        */
+  /*                                                                       */
+  /*    metrics2 :: This field can be used to return alternate glyph       */
+  /*                metrics after a single load.  It can contain either    */
+  /*                the glyph's metrics in font units, or the scaled but   */
+  /*                unhinted ones.  See the load flags that apply when     */
+  /*                calling the API function FT_Load_Glyph().              */
+  /*                                                                       */
+  /*    generic  :: A typeless pointer which is unused by the FreeType     */
+  /*                library or any of its drivers.  It can be used by      */
+  /*                client applications to link their own data to each     */
+  /*                size object.                                           */
+  /*                                                                       */
+  /*    outline  :: The outline descriptor for the current glyph, if it    */
+  /*                is a vectorial one.  The nature of the last loaded     */
+  /*                glyph can be retrieved through the result value        */
+  /*                returned by FT_Load_Glyph().                           */
+  /*                                                                       */
+  /*    bitmap   :: The bitmap/graymap descriptor for the current glyph,   */
+  /*                if it is a fixed-width one.  The nature of the last    */
+  /*                loaded glyph can be retrieved through the result value */
+  /*                returned by FT_Load_Glyph().                           */
+  /*                                                                       */
+  /*                                                                       */
+  typedef struct  FT_GlyphSlotRec_
+  {
+    FT_Face           face;
+    FT_GlyphSlot      next;
+
+    FT_Glyph_Metrics  metrics;
+    FT_Glyph_Metrics  metrics2;
+
+    FT_Glyph_Tag      format;
+    FT_Bitmap         bitmap;
+    FT_Outline        outline;
+    
+    FT_Int            num_subglyphs;
+    FT_Int            max_subglyphs;
+    FT_SubGlyph*      subglyphs;
+
+    void*             control_data;
+    void*             control_len;
+
+    void*             other;
+
+  } FT_GlyphSlotRec;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*                                                                       */
+  /*                         F U N C T I O N S                             */
+  /*                                                                       */
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Init_FreeType                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a new FreeType library object.  The set of drivers     */
+  /*    that are registered by this function is determined at build time.  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    library :: A handle to a new library object.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Init_FreeType( FT_Library*  library );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_FreeType                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given FreeType library object, and all of its childs,   */
+  /*    including resources, drivers, faces, sizes, etc.                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to a target library object.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Done_FreeType( FT_Library  library );
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Open_Face                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new face object from a given resource and typeface       */
+  /*    index.                                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    resource   :: A handle to a source resource.                       */
+  /*                                                                       */
+  /*    face_index :: The index of the face within the resource.  The      */
+  /*                  first face has index 0.                              */
+  /* <Output>                                                              */
+  /*    face       :: A handle to a new face object.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Unlike FreeType 1.1, this function automatically creates a glyph   */
+  /*    slot for the face object which can be accessed directly through    */
+  /*    `face->slot'.                                                      */
+  /*                                                                       */
+  /*    Note that additional slots can be added to each face through the   */
+  /*    FT_New_GlyphSlot() API function.  Slots are linked in a single     */
+  /*    list through their `next' field.                                   */
+  /*                                                                       */
+  /*    FT_New_Face() can be used to determine and/or check the font       */
+  /*    format of a given font resource.  If the `face_index' field is     */
+  /*    negative, the function will _not_ return any face handle in        */
+  /*    `*face'.  Its return value should be 0 if the resource is          */
+  /*    recognized, or non-zero if not.                                    */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_New_Face( FT_Library   library,
+                         const char*  filepathname,
+                         FT_Long      face_index,
+                         FT_Face*     face );
+
+
+  EXPORT_DEF
+  FT_Error  FT_Open_Face( FT_Library  library,
+                          FT_Stream   stream,
+                          FT_Long     face_index,
+                          FT_Face*    face );
+
+  EXPORT_DEF
+  FT_Error  FT_New_Memory_Face( FT_Library  library,
+                                void*       file_base,
+                                FT_Long     file_size,
+                                FT_Long     face_index,
+                                FT_Face    *face );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_Face                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards a given face object, as well as all of its child slots    */
+  /*    and sizes.                                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to a target face object.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Done_Face( FT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Size                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new size object from a given face object.                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to a parent face object.                          */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    size :: A handle to a new size object.                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_New_Size( FT_Face   face,
+                         FT_Size*  size );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_Size                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards a given size object.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size :: A handle to a target size object                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Done_Size( FT_Size  size );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Char_Size                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets the character dimensions of a given size object.  The         */
+  /*    `char_size' value is used for the width and height, expressed in   */
+  /*    26.6 fractional points.  1 point = 1/72 inch.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size      :: A handle to a target size object.                     */
+  /*    char_size :: The character size, in 26.6 fractional points.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    When dealing with fixed-size faces (i.e., non-scalable formats),   */
+  /*    use the function FT_Set_Pixel_Sizes().                             */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Set_Char_Size( FT_Face     face,
+                              FT_F26Dot6  char_width,
+                              FT_F26Dot6  char_height,
+                              FT_UInt     horz_resolution,
+                              FT_UInt     vert_resolution );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Pixel_Sizes                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets the character dimensions of a given size object.  The width   */
+  /*    and height are expressed in integer pixels.                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size         :: A handle to a target size object.                  */
+  /*    pixel_width  :: The character width, in integer pixels.            */
+  /*    pixel_height :: The character height, in integer pixels.           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Set_Pixel_Sizes( FT_Face    face,
+                                FT_UInt    pixel_width,
+                                FT_UInt    pixel_height );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_GlyphSlot                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    It is sometimes useful to have more than one glyph slot for a      */
+  /*    given face object.  This function is used to create additional     */
+  /*    slots.  All of them are automatically discarded when the face is   */
+  /*    destroyed.                                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to a parent face object.                          */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    slot :: A handle to a new glyph slot object.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_New_GlyphSlot( FT_Face        face,
+                              FT_GlyphSlot*  aslot );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_GlyphSlot                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given glyph slot.  Remember however that all slots are  */
+  /*    automatically destroyed with its parent.  Using this function is   */
+  /*    not always mandatory.                                              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    slot :: A handle to a target glyph slot.                           */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_Done_GlyphSlot( FT_GlyphSlot  slot );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Load_Glyph                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function used to load a single glyph within a given glyph slot,  */
+  /*    for a given size.                                                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: A handle to the target face object where the glyph  */
+  /*                   will be loaded.                                     */
+  /*                                                                       */
+  /*    glyph_index :: The index of the glyph in the font file.            */
+  /*                                                                       */
+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
+  /*                   FT_LOAD_XXX constants can be used to control the    */
+  /*                   glyph loading process (e.g., whether the outline    */
+  /*                   should be scaled, whether to load bitmaps or not,   */
+  /*                   whether to hint the outline, etc).                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Load_Glyph( FT_Face  face,
+                           FT_UInt  glyph_index,
+                           FT_Int   load_flags );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Load_Char                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function used to load a single glyph within a given glyph slot,  */
+  /*    for a given size, according to its character code !                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: A handle to a target face object where the glyph    */
+  /*                   will be loaded.                                     */
+  /*                                                                       */
+  /*    char_code   :: The glyph's character code, according to the        */
+  /*                   current charmap used in the face.                   */
+  /*                                                                       */
+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
+  /*                   FT_LOAD_XXX constants can be used to control the    */
+  /*                   glyph loading process (e.g., whether the outline    */
+  /*                   should be scaled, whether to load bitmaps or not,   */
+  /*                   whether to hint the outline, etc).                  */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    If the face has no current charmap, or if the character code       */
+  /*    is not defined in the charmap, this function will return an        */
+  /*    error..                                                            */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Load_Char( FT_Face   face,
+                          FT_ULong  char_code,
+                          FT_Int    load_flags );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_NO_SCALE                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the vector outline being loaded should not be scaled to 26.6       */
+  /*    fractional pixels, but kept in notional units.                     */
+  /*                                                                       */
+#define FT_LOAD_NO_SCALE  1
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_NO_HINTING                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the vector outline being loaded should not be fitted to the pixel  */
+  /*    grid but simply scaled to 26.6 fractional pixels.                  */
+  /*                                                                       */
+  /*    This flag is ignored when FT_LOAD_NO_SCALE is set.                 */
+  /*                                                                       */
+#define FT_LOAD_NO_HINTING  2
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_NO_OUTLINE                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the function should not load the vector outline of a given glyph.  */
+  /*    If an embedded bitmap exists for the glyph in the font, it will be */
+  /*    loaded, otherwise nothing is returned and an error is produced.    */
+  /*                                                                       */
+#define FT_LOAD_NO_OUTLINE  4
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_NO_BITMAP                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the function should not load the bitmap or pixmap of a given       */
+  /*    glyph.  If an outline exists for the glyph in the font, it is      */
+  /*    loaded, otherwise nothing is returned and an error is produced.    */
+  /*                                                                       */
+#define FT_LOAD_NO_BITMAP  8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_LINEAR                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the function should return the linearly scaled metrics for the     */
+  /*    glyph in `slot->metrics2' (these metrics are not grid-fitted).     */
+  /*    Otherwise, `metrics2' gives the original font units values.        */
+  /*                                                                       */
+#define FT_LOAD_LINEAR  16
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_PEDANTIC                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the glyph loader should perform a pedantic bytecode.               */
+  /*    interpretation.  Many popular fonts come with broken glyph         */
+  /*    programs.  When this flag is set, loading them will return an      */
+  /*    error.  Otherwise, errors are ignored by the loader, sometimes     */
+  /*    resulting in ugly glyphs.                                          */
+  /*                                                                       */
+#define FT_LOAD_PEDANTIC  128
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_NO_RECURSE                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the glyph loader should not load composite glyph recursively.      */
+  /*    Rather, when a composite glyph is encountered, it should set       */
+  /*    the values of `num_subglyphs' and `subglyphs', as well as set      */
+  /*    `face->glyph.format' to ft_glyph_format_composite.                 */
+  /*                                                                       */
+  /*    XXXXX : IMPORTANT NOTE, THIS FLAG IS NOT YET IMPLEMENTED !!        */
+  /*                                                                       */
+#define FT_LOAD_NO_RECURSE 256
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_DEFAULT                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the function should try to load the glyph normally, i.e.,          */
+  /*    embedded bitmaps are favored over outlines, vectors are always     */
+  /*    scaled and grid-fitted.                                            */
+  /*                                                                       */
+#define FT_LOAD_DEFAULT  0
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Glyph_Bitmap                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Renders a given glyph into a bitmap or pixmap. This function will  */
+  /*    use the registered rasters to render the glyph image.              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face    :: handle to the face object whose glyph slot contains     */
+  /*               the glyph image                                         */
+  /*    map     :: A pointer to the target bitmap descriptor.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    YES.  Rendering is synchronized, so that concurrent calls to the   */
+  /*    scan-line converter will be serialized.                            */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function does NOT CREATE the bitmap, it only renders a        */
+  /*    glyph image into it!                                               */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Get_Glyph_Bitmap( FT_Face     face,
+                                 FT_Bitmap*  map );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Kerning                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the kerning vector between two glyphs of a same face.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: A handle to a 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 method.  Other layouts, or more sophisticated    */
+  /*    kernings, are out of the scope of this API function -- they can be */
+  /*    implemented through format-specific interfaces.                    */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Get_Kerning( FT_Face     face,
+                            FT_UInt     left_glyph,
+                            FT_UInt     right_glyph,
+                            FT_Vector*  kerning );
+
+
+
+/* XXX : Not implemented yet, but should come soon */
+#if 0
+  EXPORT_DEF
+  FT_Error  FT_Select_Charmap( FT_Face      face,
+                               FT_Encoding  encoding );
+
+
+  EXPORT_DEF
+  FT_Error  FT_Set_Charmap( FT_Face     face,
+                            FT_CharMap  charmap );
+#endif
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Char_Index                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the glyph index of a given character code.  This function  */
+  /*    uses a charmap object to do the translation.                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    charmap  :: A handle to a filter charmap object.                   */
+  /*    charcode :: The character code.                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The glyph index.  0 means `undefined character code'.              */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_UInt  FT_Get_Char_Index( FT_Face   face,
+                              FT_ULong  charcode );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_MulDiv                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very simple function used to perform the computation `(A*B)/C'   */
+  /*    with maximum accuracy (it uses a 64-bit intermediate integer       */
+  /*    whenever necessary).                                               */
+  /*                                                                       */
+  /*    This function isn't necessarily as fast as some processor specific */
+  /*    operations, but is at least completely portable.                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: The first multiplier.                                         */
+  /*    b :: The second multiplier.                                        */
+  /*    c :: The divisor.                                                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `(a*b)/c'.  This function never traps when trying to */
+  /*    divide by zero, it simply returns `MaxInt' or `MinInt' depending   */
+  /*    on the signs of `a' and `b'.                                       */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Long  FT_MulDiv( FT_Long  a,
+                      FT_Long  b,
+                      FT_Long  c );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_MulFix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very simple function used to perform the computation             */
+  /*    `(A*B)/0x10000' with maximum accuracy.  Most of the time, this is  */
+  /*    used to multiply a given value by a 16.16 fixed float factor.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: The first multiplier.                                         */
+  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */
+  /*         possible (see note below).                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `(a*b)/0x10000'.                                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function has been optimized for the case where the absolute   */
+  /*    value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */
+  /*    As this happens mainly when scaling from notional units to         */
+  /*    fractional pixels in FreeType, it resulted in noticeable speed     */
+  /*    improvements between versions 2.0 and 1.x.                         */
+  /*                                                                       */
+  /*    As a conclusion, always try to place a 16.16 factor as the         */
+  /*    _second_ argument of this function; this can make a great          */
+  /*    difference.                                                        */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Long  FT_MulFix( FT_Long  a,
+                      FT_Long  b );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_DivFix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very simple function used to perform the computation             */
+  /*    `(A*0x10000)/B' with maximum accuracy.  Most of the time, this is  */
+  /*    used to divide  a given value by a 16.16 fixed float factor.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: The first multiplier.                                         */
+  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */
+  /*         possible (see note below).                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `(a*0x10000)/b'.                                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The optimisation for FT_DivFix() is simple : if (a << 16) fits     */
+  /*    in 32 bits, then the division is computed directly. Otherwise,     */
+  /*    we use a specialised version of the old FT_MulDiv64                */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Long  FT_DivFix( FT_Long  a,
+                      FT_Long  b );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Decompose_Outline                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Walks over an outline's structure to decompose it into individual  */
+  /*    segments and Bezier arcs.  This function is also able to emit      */
+  /*    `move to' and `close to' operations to indicate the start and end  */
+  /*    of new contours in the outline.                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline   :: A pointer to the source target.                       */
+  /*                                                                       */
+  /*    interface :: A table of `emitters', i.e,. function pointers called */
+  /*                 during decomposition to indicate path operations.     */
+  /*                                                                       */
+  /*    user      :: A typeless pointer which is passed to each emitter    */
+  /*                 during the decomposition.  It can be used to store    */
+  /*                 the state during the decomposition.                   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means sucess.                                       */
+  /*                                                                       */
+  EXPORT_DEF
+  int  FT_Decompose_Outline( FT_Outline*        outline,
+                             FT_Outline_Funcs*  interface,
+                             void*              user );
+ 
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Outline                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new outline of a given size.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library     :: A handle to the library object from where the       */
+  /*                   outline is allocated.  Note however that the new    */
+  /*                   outline will NOT necessarily be FREED when          */
+  /*                   destroying the library, by FT_Done_FreeType().      */
+  /*                                                                       */
+  /*    numPoints   :: The maximum number of points within the outline.    */
+  /*                                                                       */
+  /*    numContours :: The maximum number of contours within the outline.  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    outline     :: A handle to the new outline.  NULL in case of       */
+  /*                   error.                                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    No.                                                                */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The reason why this function takes a `library' parameter is simply */
+  /*    to use the library's memory allocator.  You can copy the source    */
+  /*    code of this function, replacing allocations with `malloc()' if    */
+  /*    you want to control where the objects go.                          */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_New_Outline( FT_Library   library,
+                            FT_UInt      numPoints,
+                            FT_Int       numContours,
+                            FT_Outline*  outline );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_Outline                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys an outline created with FT_New_Outline().                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle of the library object used to allocate the     */
+  /*               outline.                                                */
+  /*                                                                       */
+  /*    outline :: A pointer to the outline object to be discarded.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    No.                                                                */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    If the outline's `owner' field is not set, only the outline        */
+  /*    descriptor will be released.                                       */
+  /*                                                                       */
+  /*    The reason why this function takes an `outline' parameter is       */
+  /*    simply to use FT_Alloc()/FT_Free().  You can copy the source code  */
+  /*    of this function, replacing allocations with `malloc()' in your    */
+  /*    application if you want something simpler.                         */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Done_Outline( FT_Library   library,
+                             FT_Outline*  outline );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Outline_CBox                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns an outline's `control box'.  The control box encloses all  */
+  /*    the outline's points, including Bezier control points.  Though it  */
+  /*    coincides with the exact bounding box for most glyphs, it can be   */
+  /*    slightly larger in some situations (like when rotating an outline  */
+  /*    which contains Bezier outside arcs).                               */
+  /*                                                                       */
+  /*    Computing the control box is very fast, while getting the bounding */
+  /*    box can take much more time as it needs to walk over all segments  */
+  /*    and arcs in the outline.  To get the latter, you can use the       */
+  /*    `ftbbox' component which is dedicated to this single task.         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline :: A pointer to the source outline descriptor.             */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    cbox    :: The outline's control box.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Get_Outline_CBox( FT_Outline*  outline,
+                                 FT_BBox*     cbox );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Translate_Outline                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Applies a simple translation to the points of an outline.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline :: A pointer to the target outline descriptor.             */
+  /*    xOffset :: The horizontal offset.                                  */
+  /*    yOffset :: The vertical offset.                                    */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_Translate_Outline( FT_Outline*  outline,
+                              FT_Pos       xOffset,
+                              FT_Pos       yOffset );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Raster                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Register a given raster to the library.                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library   :: A handle to a target library object.                  */
+  /*                                                                       */
+  /*    interface :: pointer to the raster's interface                     */
+  /*                                                                       */
+  /*    raster    :: if this field is nil, this function will allocate     */
+  /*                 a new objet. Otherwise, it will simply use the one    */
+  /*                 provided here.                                        */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Set_Raster( FT_Library            library,
+                           FT_Raster_Interface*  interface,
+                           FT_Raster             raster );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Raster_Mode                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Set a raster-specific mode.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to a target library object.                    */
+  /*    format  :: the glyph format used to select the raster              */
+  /*    mode    :: the raster-specific mode descriptor                     */
+  /*    args    :: the mode arguments                                      */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Set_Raster_Mode( FT_Library    library,
+                                FT_Glyph_Tag  format,
+                                const char*   mode,
+                                const char*   args );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif /* FREETYPE_H */
+
+
+/* END */
diff --git a/include/ftbbox.h b/include/ftbbox.h
new file mode 100644
index 0000000..ea68615
--- /dev/null
+++ b/include/ftbbox.h
@@ -0,0 +1,73 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftbbox.h                                                               */
+/*                                                                         */
+/*    FreeType bbox computation (specification).                           */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This component has a _single_ role: to compute exact outline bounding */
+  /* boxes.                                                                */
+  /*                                                                       */
+  /* It is separated from the rest of the engine for various technical     */
+  /* reasons.  It may well be integrated in `ftoutln' later.               */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef FTBBOX_H
+#define FTBBOX_H
+
+#include <freetype.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Outline_BBox                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the exact bounding box of an outline.  This is slower     */
+  /*    than computing the control box.  However, it uses an advanced      */
+  /*    algorithm which returns _very_ quickly when the two boxes          */
+  /*    coincide.  Otherwise, the outline Bezier arcs are walked over to   */
+  /*    extract their extrema.                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline :: A pointer to the source outline.                        */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    bbox    :: The outline's exact bounding box.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Get_Outline_BBox( FT_Outline*  outline,
+                                 FT_BBox*     bbox );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* FTBBOX_H */
+
+
+/* END */
diff --git a/include/fterrors.h b/include/fterrors.h
new file mode 100644
index 0000000..6df9ae3
--- /dev/null
+++ b/include/fterrors.h
@@ -0,0 +1,82 @@
+/***************************************************************************/
+/*                                                                         */
+/*  fterrors.h                                                             */
+/*                                                                         */
+/*  FreeType error codes (specification).                                  */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#define  FT_Err_Ok                       0x000
+
+#define  FT_Err_Cannot_Open_Resource     0x001
+#define  FT_Err_Unknown_File_Format      0x002
+#define  FT_Err_Invalid_File_Format      0x002
+
+#define  FT_Err_Invalid_Argument         0x003
+#define  FT_Err_Invalid_Handle           0x004
+#define  FT_Err_Invalid_Glyph_Index      0x00A
+#define  FT_Err_Invalid_Character_Code   0x00B
+
+#define  FT_Err_Unimplemented_Feature    0x010
+#define  FT_Err_Invalid_Glyph_Format     0x00D
+
+#define  FT_Err_Invalid_Library_Handle   0x004
+#define  FT_Err_Invalid_Driver_Handle    0x005
+#define  FT_Err_Invalid_Face_Handle      0x006
+#define  FT_Err_Invalid_Size_Handle      0x007
+#define  FT_Err_Invalid_Slot_Handle      0x008
+#define  FT_Err_Invalid_CharMap_Handle   0x009
+#define  FT_Err_Invalid_Outline          0x00B
+#define  FT_Err_Invalid_Dimensions       0x00C
+
+#define  FT_Err_Unavailable_Outline      0x011
+#define  FT_Err_Unavailable_Bitmap       0x012
+#define  FT_Err_Unavailable_Pixmap       0x013
+#define  FT_Err_File_Is_Not_Collection   0x014
+#define  FT_Err_Too_Many_Drivers         0x015
+#define  FT_Err_Too_Many_Glyph_Formats   0x016
+#define  FT_Err_Too_Many_Extensions      0x017
+
+#define  FT_Err_Out_Of_Memory            0x100
+#define  FT_Err_Unlisted_Object          0x101
+
+#define  FT_Err_Invalid_Resource_Handle  0x200
+#define  FT_Err_Invalid_Stream_Handle    0x201
+#define  FT_Err_Cannot_Open_Stream       0x202
+#define  FT_Err_Invalid_Stream_Seek      0x203
+#define  FT_Err_Invalid_Stream_Skip      0x204
+#define  FT_Err_Invalid_Stream_Read      0x205
+#define  FT_Err_Invalid_Stream_Operation 0x206
+#define  FT_Err_Invalid_Frame_Operation  0x207
+#define  FT_Err_Nested_Frame_Access      0x208
+#define  FT_Err_Invalid_Frame_Read       0x209
+
+#define  FT_Err_Too_Many_Points          0x300
+#define  FT_Err_Too_Many_Contours        0x301
+#define  FT_Err_Invalid_Composite        0x302
+#define  FT_Err_Too_Many_Hints           0x303
+#define  FT_Err_Too_Many_Edges           0x304
+#define  FT_Err_Too_Many_Strokes         0x305
+
+/* range 0x400 - 0x4FF is reserved for TrueType specific stuff */
+
+/* range 0x500 - 0x5FF is reserved for TrueDoc  specific stuff */
+
+/* range 0x600 - 0x6FF is reserved for Type1    specific stuff */
+
+#define  FT_Err_Raster_Uninitialized     0xF00
+#define  FT_Err_Raster_Corrupted         0xF01
+#define  FT_Err_Raster_Overflow          0xF02
+
+
+/* END */
diff --git a/include/ftimage.h b/include/ftimage.h
new file mode 100644
index 0000000..f18174b
--- /dev/null
+++ b/include/ftimage.h
@@ -0,0 +1,627 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftimage.h                                                              */
+/*                                                                         */
+/*  This file defines the glyph image formats recognized by FreeType, as   */
+/*  well as the default raster interface.                                  */
+/*                                                                         */
+/*  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 FTIMAGE_H
+#define FTIMAGE_H
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Pos                                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The type FT_Pos is a 32-bit integer used to store vectorial        */
+  /*    coordinates.  Depending on the context, these can represent        */
+  /*    distances in integer font units, or 26.6 fixed float pixel         */
+  /*    coordinates.                                                       */
+  /*                                                                       */
+  typedef signed long  FT_Pos;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Vector                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2d vector; coordinates are of   */
+  /*    the FT_Pos type.                                                   */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    x :: The horizontal coordinate.                                    */
+  /*    y :: The vertical coordinate.                                      */
+  /*                                                                       */
+  typedef struct  FT_Vector_
+  {
+    FT_Pos  x;
+    FT_Pos  y;
+
+  } FT_Vector;
+
+
+ /*************************************************************************
+  *
+  *  <Enum>
+  *    FT_Pixel_Mode
+  *
+  *  <Description>
+  *    An enumeration type used to describe the format of pixels
+  *    in a given bitmap. Note that additional formats may be added
+  *    in the future.
+  *
+  *  <Fields>
+  *    ft_pixel_mode_mono   :: a monochrome bitmap (1 bit/pixel)
+  *
+  *    ft_pixel_mode_grays  :: an 8-bit gray-levels bitmap. Note that
+  *                            the total number of gray levels is given
+  *                            in the `num_grays' field of the FT_Bitmap
+  *                            structure.
+  *
+  *    ft_pixel_mode_pal2   :: a 2-bit paletted bitmap.
+  *                            currently unused by FreeType.
+  *
+  *    ft_pixel_mode_pal4   :: a 4-bit paletted bitmap.
+  *                            currently unused by FreeType.
+  *
+  *    ft_pixel_mode_pal8   :: an 8-bit paletted bitmap.
+  *                            currently unused by FreeType.
+  *
+  *    ft_pixel_mode_rgb15  :: a 15-bit RGB bitmap. Uses 5:5:5 encoding
+  *                            currently unused by FreeType.
+  *
+  *    ft_pixel_mode_rgb16  :: a 16-bit RGB bitmap. Uses 5:6:5 encoding
+  *                            currently unused by FreeType.
+  *
+  *    ft_pixel_mode_rgb24  :: a 24-bit RGB bitmap.
+  *                            currently unused by FreeType.
+  *
+  *    ft_pixel_mode_rgb32  :: a 32-bit RGB bitmap.
+  *                            currently unused by FreeType.
+  *
+  * <Note>
+  *    Some anti-aliased bitmaps might be embedded in TrueType fonts
+  *    using formats pal2 or pal4, though no fonts presenting those
+  *    have been found to date..
+  *
+  *************************************************************************/
+  
+  typedef enum FT_Pixel_Mode_
+  {
+    ft_pixel_mode_none = 0,
+    ft_pixel_mode_mono,
+    ft_pixel_mode_grays,
+    ft_pixel_mode_pal2,
+    ft_pixel_mode_pal4,
+    ft_pixel_mode_pal8,
+    ft_pixel_mode_rgb15,
+    ft_pixel_mode_rgb16,
+    ft_pixel_mode_rgb24,
+    ft_pixel_mode_rgb32,
+  
+    ft_pixel_mode_max      /* do not remove */
+    
+  } FT_Pixel_Mode;
+
+
+
+ /*************************************************************************
+  *
+  *  <Enum>
+  *    FT_Palette_Mode
+  *
+  *  <Description>
+  *    An enumeration type used to describe the format of a bitmap
+  *    palette, used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8
+  *
+  *  <Fields>
+  *    ft_palette_mode_rgb  :: the palette is an array of 3-bytes RGB records
+  *
+  *    ft_palette_mode_rgba :: the palette is an array of 4-bytes RGBA records
+  *
+  *  <Note>
+  *    As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by
+  *    FreeType, these types are not handled by the library itself.
+  *
+  *************************************************************************/
+  
+  typedef enum FT_Palette_Mode_
+  {
+    ft_palette_mode_rgb = 0,
+    ft_palette_mode_rgba,
+    
+    ft_palettte_mode_max   /* do not remove */
+  
+  } FT_Palette_Mode;
+
+
+  /*************************************************************************
+   *                                                                         
+   * <Struct>                                                                
+   *    FT_Bitmap                                                            
+   *                                                                         
+   * <Description>                                                           
+   *    A structure used to describe a bitmap or pixmap to the raster.       
+   *    Note that we now manage pixmaps of various depths through the        
+   *    `pixel_mode' field.
+   *                                                                         
+   * <Fields>                                                                
+   *    rows         :: The number of bitmap rows.                               
+   *                                                                         
+   *    width        :: The number of pixels in bitmap row.                      
+   *                                                                         
+   *    pitch        :: The pitch's absolute value is the number of bytes        
+   *                    taken by one bitmap row, including padding. However,     
+   *                    the pitch is positive when the bitmap has a `down'       
+   *                    flow, and negative when it has an `up' flow. In all      
+   *                    cases, the pitch is an offset to add to a bitmap         
+   *                    pointer in order to go down one row.                     
+   *                                                                         
+   *    buffer       :: A typeless pointer to the bitmap buffer. This value      
+   *                    should be aligned on 32-bit boundaries in most cases.    
+   *                                                                         
+   *    num_grays    :: this field is only used with ft_pixel_mode_grays,      
+   *                    it gives the number of gray levels used in the         
+   *                    bitmap.                                                
+   *                                                                         
+   *    pixel_mode   :: the pixel_mode, i.e. how pixel bits are stored         
+   *                                                                         
+   *    palette_mode :: this field is only used with paletted pixel modes,   
+   *                    it indicates how the palette is stored               
+   *                                                                         
+   *    palette      :: a typeless pointer to the bitmap palette. only used
+   *                    for paletted pixel modes.
+   *
+   * <Note>
+   *   When using pixel modes pal2, pal4 and pal8 with a void `palette'
+   *   field, a gray pixmap with respectively 4, 16 and 256 levels of gray
+   *   is assumed. This, in order to be compatible with some embedded bitmap
+   *   formats defined in the TrueType spec.
+   *
+   *   Note that no font was found presenting such embedded bitmaps, so this
+   *   is currently completely unhandled by the library.
+   *
+   *
+   *************************************************************************/
+   
+  typedef struct FT_Bitmap_
+  {
+    int    rows;
+    int    width;
+    int    pitch;
+    void*  buffer;
+    short  num_grays;
+    char   pixel_mode;
+    char   palette_mode;
+    void*  palette;
+
+  } FT_Bitmap;
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Outline                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This structure is used to describe an outline to the scan-line     */
+  /*    converter.  It's a copy of the TT_Outline type that was defined    */
+  /*    in FreeType 1.x.                                                   */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    n_contours     :: The number of contours in the outline.           */
+  /*                                                                       */
+  /*    n_points       :: The number of points in the outline.             */
+  /*                                                                       */
+  /*    points         :: A pointer to an array of `n_points' FT_Vector    */
+  /*                      elements, giving the outline's point             */
+  /*                      coordinates.                                     */
+  /*                                                                       */
+  /*    flags          :: A pointer to an array of `n_points' chars,       */
+  /*                      giving each outline point's type.  If bit 0 is   */
+  /*                      set, the point is `off' the curve, i.e., a       */
+  /*                      Bezier control point, while it is `on' when      */
+  /*                      unset.                                           */
+  /*                                                                       */
+  /*                      Bit 1 is meaningful for `off' points only.  If   */
+  /*                      set, it indicates a third-order Bezier arc       */
+  /*                      control point; and a second-order control point  */
+  /*                      if unset.                                        */
+  /*                                                                       */
+  /*    contours       :: An array of `n_contours' shorts, giving the end  */
+  /*                      point of each contour within the outline.  For   */
+  /*                      example, the first contour is defined by the     */
+  /*                      points `0' to `contours[0]', the second one is   */
+  /*                      defined by the points `contours[0]+1' to         */
+  /*                      `contours[1]', etc.                              */
+  /*                                                                       */
+  /*    owner          :: This flag is a boolean which is set whenever the */
+  /*                      outline structure/object owns the arrays it      */
+  /*                      refers to in the fields `points', `flags', and   */
+  /*                      `contours'.                                      */
+  /*                                                                       */
+  /*    high_precision :: This flag is set automatically by the FreeType   */
+  /*                      library.  It indicates that the scan-line        */
+  /*                      converter should use a higher precision when     */
+  /*                      rendering the outline.  This is useful at small  */
+  /*                      pixel sizes to get adequate results, though at   */
+  /*                      the price of slower rendering.  Don't try to     */
+  /*                      render large outlines with this flag set.  Note  */
+  /*                      that it may be ignored in later implementations. */
+  /*                                                                       */
+  /*    second_pass    :: A boolean which is set when the scan-line        */
+  /*                      converter should perform a second pass to        */
+  /*                      eliminate vertical drop-outs (only vertical      */
+  /*                      drop-outs are checked on the first pass).  This  */
+  /*                      field may be ignored by later implementations.   */
+  /*                                                                       */
+  /*    dropout_mode   :: Specifies the drop-out control mode to use while */
+  /*                      rendering an outline.  Valid values are 0 (no    */
+  /*                      drop out check), 1, 2, 4, and 5.  See the        */
+  /*                      TrueType specification for more details.  A      */
+  /*                      value of 2 is usually an excellent generic       */
+  /*                      choice. This field may be ignored by some        */
+  /*                      raster implementations.                          */
+  /*                                                                       */
+  /*                                                                       */
+  typedef struct  FT_Outline_
+  {
+    short       n_contours;      /* number of contours in glyph        */
+    short       n_points;        /* number of points in the glyph      */
+
+    FT_Vector*  points;          /* the outline's points               */
+    char*       flags;           /* the points flags                   */
+    short*      contours;        /* the contour end points             */
+
+    char        owner;           /* the outline owns the coordinates,  */
+                                 /* flags, and contours array it uses  */
+
+    char        high_precision;  /* high precision rendering           */
+    char        second_pass;     /* two sweeps rendering               */
+    char        dropout_mode;    /* dropout mode                       */
+
+  } FT_Outline;
+
+
+#define FT_CURVE_TAG( flag )  (flag & 3)
+
+#define FT_Curve_Tag_On       1
+#define FT_Curve_Tag_Conic    0
+#define FT_Curve_Tag_Cubic    2
+
+#define FT_Curve_Tag_Touch_X  8   /* reserved for the TrueType hinter */
+#define FT_Curve_Tag_Touch_Y  16  /* reserved for the TrueType hinter */
+
+#define FT_Curve_Tag_Touch_Both  ( FT_Curve_Tag_Touch_X | \
+                                   FT_Curve_Tag_Touch_Y)
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Outline_MoveTo_Func                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function pointer type used to describe the signature of a `move  */
+  /*    to' function during outline walking/decomposition.                 */
+  /*                                                                       */
+  /*    A `move to' is emitted to start a new contour in an outline.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    to   :: A pointer to the target point of the `move to'.            */
+  /*    user :: A typeless pointer which is passed from the caller of the  */
+  /*            decomposition function.                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  typedef int  (*FT_Outline_MoveTo_Func)( FT_Vector*  to,
+                                          void*       user );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Outline_LineTo_Func                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function pointer type used to describe the signature of a `line  */
+  /*    to' function during outline walking/decomposition.                 */
+  /*                                                                       */
+  /*    A `line to' is emitted to indicate a segment in the outline.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    to   :: A pointer to the target point of the `line to'.            */
+  /*    user :: A typeless pointer which is passed from the caller of the  */
+  /*            decomposition function.                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  typedef int  (*FT_Outline_LineTo_Func)( FT_Vector*  to,
+                                          void*       user );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Outline_ConicTo_Func                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function pointer type use to describe the signature of a `conic  */
+  /*    to' function during outline walking/decomposition.                 */
+  /*                                                                       */
+  /*    A `conic to' is emitted to indicate a second-order Bezier arc in   */
+  /*    the outline.                                                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    control :: An intermediate control point between the last position */
+  /*               and the new target in `to'.                             */
+  /*                                                                       */
+  /*    to      :: A pointer to the target end point of the conic arc.     */
+  /*                                                                       */
+  /*    user    :: A typeless pointer which is passed from the caller of   */
+  /*               the decomposition function.                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  typedef int  (*FT_Outline_ConicTo_Func)( FT_Vector*  control,
+                                           FT_Vector*  to,
+                                           void*       user );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Outline_CubicTo_Func                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function pointer type used to describe the signature of a `cubic */
+  /*    to' function during outline walking/decomposition.                 */
+  /*                                                                       */
+  /*    A `cubic to' is emitted to indicate a third-order Bezier arc.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    control1 :: A pointer to the first Bezier control point.           */
+  /*    control2 :: A pointer to the second Bezier control point.          */
+  /*    to       :: A pointer to the target end point.                     */
+  /*    user     :: A typeless pointer which is passed from the caller of  */
+  /*                the decomposition function.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  typedef int  (*FT_Outline_CubicTo_Func)( FT_Vector*  control1,
+                                           FT_Vector*  control2,
+                                           FT_Vector*  to,
+                                           void*       user );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Outline_Funcs                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure to hold various function pointers used during outline  */
+  /*    decomposition in order to emit segments, conic, and cubic Beziers, */
+  /*    as well as `move to' and `close to' operations.                    */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    move_to  :: The `move to' emitter.                                 */
+  /*    line_to  :: The segment emitter.                                   */
+  /*    conic_to :: The second-order Bezier arc emitter.                   */
+  /*    cubic_to :: The third-order Bezier arc emitter.                    */
+  /*                                                                       */
+  typedef struct  FT_Outline_Funcs_
+  {
+    FT_Outline_MoveTo_Func   move_to;
+    FT_Outline_LineTo_Func   line_to;
+    FT_Outline_ConicTo_Func  conic_to;
+    FT_Outline_CubicTo_Func  cubic_to;
+
+  } FT_Outline_Funcs;
+
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_IMAGE_TAG                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This macro converts four letter tags which are used to label       */
+  /*    TrueType tables into an unsigned long to be used within FreeType.  */
+  /*                                                                       */
+#define FT_IMAGE_TAG( _x1, _x2, _x3, _x4 ) \
+          (((unsigned long)_x1 << 24) |        \
+           ((unsigned long)_x2 << 16) |        \
+           ((unsigned long)_x3 << 8)  |        \
+            (unsigned long)_x4)
+
+
+ /***********************************************************************
+  *
+  * <Enum>
+  *    FT_Glyph_Tag
+  *
+  * <Description>
+  *    An enumeration type used to describethe format of a given glyph
+  *    image. Note that this version of FreeType only supports two image
+  *    formats, even though future font drivers will be able to register
+  *    their own format.
+  *
+  * <Fields>
+  *    ft_glyph_format_bitmap  :: the glyph image is a bitmap, and can
+  *                               be described as a FT_Bitmap
+  *
+  *    ft_glyph_format_outline :: the glyph image is a vectorial image
+  *                               made of bezier control points, and can
+  *                               be described as a FT_Outline
+  *
+  ***********************************************************************/
+  
+  typedef enum FT_Glyph_Tag_
+  {
+    ft_glyph_format_none      = 0,
+    ft_glyph_format_composite = FT_IMAGE_TAG('c','o','m','p'),
+    ft_glyph_format_bitmap    = FT_IMAGE_TAG('b','i','t','s'),
+    ft_glyph_format_outline   = FT_IMAGE_TAG('o','u','t','l')
+  
+  } FT_Glyph_Tag;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Raster                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle (pointer) to a raster object.  Each object can be used    */
+  /*    independently to convert an outline into a bitmap or pixmap.       */
+  /*                                                                       */
+  typedef struct FT_RasterRec_*  FT_Raster;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Raster_Init_Proc                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a fresh raster object which should have been allocated */
+  /*    by client applications.  This function is also used to set the     */
+  /*    object's render pool.  It can be used repeatedly on a single       */
+  /*    object if one wants to change the pool's address or size.          */
+  /*                                                                       */
+  /*    Note that the render pool has no state and is only used during a   */
+  /*    call to FT_Raster_Render().  It is thus theorically possible to    */
+  /*    share it between several non-concurrent components of your         */
+  /*    applications when memory is a scarce resource.                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    raster    :: a handle to the target raster object.                 */
+  /*    pool_base :: the render pool's base address in memory              */
+  /*    pool_size :: the render pool's size in bytes.  this must be at     */
+  /*                 least 4 kByte.                                        */
+  /* <Return>                                                              */
+  /*    An error condition, used as a FT_Error in the FreeType library.    */
+  /*    0 means success.                                                   */
+  /*                                                                       */
+  typedef int (*FT_Raster_Init_Proc)( FT_Raster    raster,
+                                      const char*  pool_base,
+                                      long         pool_size );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Raster_Set_Mode_Proc                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Some raster implementations may have several modes of operation.   */
+  /*    This function is used to select one of them, as well as pass some  */
+  /*    arguments.                                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    raster  :: The target raster object.                               */
+  /*                                                                       */
+  /*    mode    :: A pointer used to describe the mode to set. This is     */
+  /*               completely raster-specific, and could be, for example,  */
+  /*               a text string.                                          */
+  /*                                                                       */
+  /*    args    :: An argument to the set_mode command. This is completely */
+  /*               specific to the raster and the mode used.               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    An error code, used as a FT_Error by the FreeType library.         */
+  /*    0 means success.                                                   */
+  /*                                                                       */
+  typedef int (*FT_Raster_Set_Mode_Proc)( FT_Raster    raster,
+                                          const char*  mode,
+                                          const char*  args );
+                        
+                                          
+  /*************************************************************************
+   *                                                                       
+   * <FuncType>                                                            
+   *    FT_Raster_Render_Proc                                              
+   *                                                                       
+   * <Description>                                                         
+   *    Renders an outline into a target bitmap/pixmap.                    
+   *                                                                       
+   * <Input>                                                               
+   *    raster        :: A handle to a raster object used during rendering.
+   *
+   *    source_image  :: a typeless pointer to the source glyph image.
+   *                     (usually a FT_Outline*).
+   *
+   *    target_bitmap :: descriptor to the target bitmap.
+   *
+   * <Return>                                                              
+   *    Error code, interpreted as a FT_Error by FreeType library.         
+   *    0 means success.                                                   
+   *                                                                       
+   *************************************************************************/
+   
+  typedef int  (*FT_Raster_Render_Proc)( FT_Raster       raster,
+                                         void*           source_image,
+                                         FT_Bitmap*      target_bitmap );
+
+
+ /**************************************************************************
+  *
+  * <Struct>
+  *    FT_Raster_Interface
+  *
+  * <Description>
+  *    A structure used to model the default raster interface. A raster
+  *    is a module in charge of converting a glyph image into a bitmap.
+  * 
+  * <Fields>
+  *    size      :: the size in bytes of the given raster object. This
+  *                 is used to allocate a new raster when calling
+  *                 `FT_Set_Raster'.
+  *
+  *    format    :: the source glyph image format this raster is able to
+  *                 handle.
+  *
+  *    init      :: the raster's initialisation routine
+  *
+  *    set_mode  :: the raster's mode set routine
+  *
+  *    render    :: the raster's rendering routine
+  *
+  **************************************************************************/
+  
+  typedef struct FT_Raster_Interface_
+  {
+    long                     size;
+    FT_Glyph_Tag             format_tag;
+    FT_Raster_Init_Proc      init;
+    FT_Raster_Set_Mode_Proc  set_mode;
+    FT_Raster_Render_Proc    render;
+    
+  
+  } FT_Raster_Interface;
+
+ 
+#endif /* FTIMAGE_H */
+
+
diff --git a/include/ftsystem.h b/include/ftsystem.h
new file mode 100644
index 0000000..5f42e17
--- /dev/null
+++ b/include/ftsystem.h
@@ -0,0 +1,95 @@
+/**************************************************************************
+ *
+ *  ftsystem.h                                                        1.0
+ *
+ *    FreeType low-level system interface definition
+ *
+ *    This file contains the definitions of the stream and memory interfaces
+ *    used by FreeType.                                                  
+ *
+ *
+ *  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 FTSYSTEM_H
+#define FTSYSTEM_H
+
+/*************************************************************************
+ *
+ *                  M E M O R Y   M A N A G E M E N T
+ *
+ *************************************************************************/
+
+  typedef struct FT_MemoryRec_*  FT_Memory;
+  
+  typedef void* (*FT_Alloc_Func)( FT_Memory  memory,
+                                  long       size );
+
+  typedef void  (*FT_Free_Func)( FT_Memory  memory,
+                                 void*      block );
+
+  typedef void* (*FT_Realloc_Func)( FT_Memory  memory,
+                                    long       cur_size,
+                                    long       new_size,
+                                    void*      block );
+
+  struct FT_MemoryRec_
+  {
+    void*            user;
+    FT_Alloc_Func    alloc;
+    FT_Free_Func     free;
+    FT_Realloc_Func  realloc;
+  };
+
+
+
+/*************************************************************************
+ *
+ *                       I / O   M A N A G E M E N T
+ *
+ *************************************************************************/
+  
+  typedef union FT_StreamDesc_
+  {
+    long  value;
+    void* pointer;
+    
+  } FT_StreamDesc;
+
+
+  typedef struct FT_StreamRec_*  FT_Stream;
+
+  typedef  unsigned long (*FT_Stream_IO)( FT_Stream      stream,
+                                          unsigned long  offset,
+                                          char*          buffer,
+                                          unsigned long  count );
+
+  typedef  void (*FT_Stream_Close)( FT_Stream  stream );
+
+  struct FT_StreamRec_
+  {
+    char*           base;
+    unsigned long   size;
+    unsigned long   pos;
+    
+    FT_StreamDesc   descriptor;
+    FT_StreamDesc   pathname;    /* ignored by FreeType - useful for debugging */
+
+    FT_Stream_IO    read;
+    FT_Stream_Close close;
+
+    FT_Memory       memory;
+    char*           cursor;
+    char*           limit;
+  };
+
+
+#endif /* FTSYSTEM_H */
diff --git a/include/ttnamedid.h b/include/ttnamedid.h
new file mode 100644
index 0000000..df7fcb7
--- /dev/null
+++ b/include/ttnamedid.h
@@ -0,0 +1,624 @@
+/*******************************************************************
+ *
+ *  ttnameid.h
+ *
+ *    TrueType Name ID definitions
+ *
+ *  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 TTNAMEID_H
+#define TTNAMEID_H
+
+/*
+ * possible values for the 'Platform' identifier code in the name
+ * records of the TTF "name" table
+ */
+
+#define TT_PLATFORM_APPLE_UNICODE       0
+#define TT_PLATFORM_MACINTOSH           1
+#define TT_PLATFORM_ISO                 2
+#define TT_PLATFORM_MICROSOFT           3
+
+
+/*
+ * possible values of the platform specific encoding identifier field in
+ * the name records of the TTF "name" table when the 'Platform' identifier
+ * code is TT_PLATFORM_APPLE_UNICODE
+ */
+
+#define TT_APPLE_ID_DEFAULT             0
+#define TT_APPLE_ID_UNICODE_1_1         1
+#define TT_APPLE_ID_ISO_10646           2
+#define TT_APPLE_ID_UNICODE_2_0         3
+
+
+/*
+ * possible values of the platform specific encoding identifier field in
+ * the name records of the TTF "name" table when the 'Platform' identifier
+ * code is TT_PLATFORM_MACINTOSH
+ */
+
+#define TT_MAC_ID_ROMAN                 0
+#define TT_MAC_ID_JAPANESE              1
+#define TT_MAC_ID_TRADITIONAL_CHINESE   2
+#define TT_MAC_ID_KOREAN                3
+#define TT_MAC_ID_ARABIC                4
+#define TT_MAC_ID_HEBREW                5
+#define TT_MAC_ID_GREEK                 6
+#define TT_MAC_ID_RUSSIAN               7
+#define TT_MAC_ID_RSYMBOL               8
+#define TT_MAC_ID_DEVANAGARI            9
+#define TT_MAC_ID_GURMUKHI              10
+#define TT_MAC_ID_GUJARATI              11
+#define TT_MAC_ID_ORIYA                 12
+#define TT_MAC_ID_BENGALI               13
+#define TT_MAC_ID_TAMIL                 14
+#define TT_MAC_ID_TELUGU                15
+#define TT_MAC_ID_KANNADA               16
+#define TT_MAC_ID_MALAYALAM             17
+#define TT_MAC_ID_SINHALESE             18
+#define TT_MAC_ID_BURMESE               19
+#define TT_MAC_ID_KHMER                 20
+#define TT_MAC_ID_THAI                  21
+#define TT_MAC_ID_LAOTIAN               22
+#define TT_MAC_ID_GEORGIAN              23
+#define TT_MAC_ID_ARMENIAN              24
+#define TT_MAC_ID_MALDIVIAN             25
+#define TT_MAC_ID_SIMPLIFIED_CHINESE    25
+#define TT_MAC_ID_TIBETAN               26
+#define TT_MAC_ID_MONGOLIAN             27
+#define TT_MAC_ID_GEEZ                  28
+#define TT_MAC_ID_SLAVIC                29
+#define TT_MAC_ID_VIETNAMESE            30
+#define TT_MAC_ID_SINDHI                31
+#define TT_MAC_ID_UNINTERP              32
+
+
+/*
+ * possible values of the platform specific encoding identifier field in
+ * the name records of the TTF "name" table when the 'Platform' identifier
+ * code is TT_PLATFORM_ISO
+ */
+
+#define TT_ISO_ID_7BIT_ASCII    0
+#define TT_ISO_ID_10646         1
+#define TT_ISO_ID_8859_1        2
+
+
+/*
+ * possible values of the platform specific encoding identifier field in
+ * the name records of the TTF "name" table when the 'Platform' identifier
+ * code is TT_PLATFORM_MICROSOFT
+ */
+
+#define TT_MS_ID_SYMBOL_CS      0
+#define TT_MS_ID_UNICODE_CS     1
+#define TT_MS_ID_SJIS           2
+#define TT_MS_ID_GB2312         3
+#define TT_MS_ID_BIG_5          4
+#define TT_MS_ID_WANSUNG        5
+#define TT_MS_ID_JOHAB          6
+
+
+
+/*
+ * possible values of the language identifier field in the name records of
+ * the TTF "name" table when the 'Platform' identifier code is
+ * TT_PLATFORM_MACINTOSH
+ *
+ * the canonical source for the Apple assigned Language ID's is at
+ * http://fonts.apple.com/TTRefMan/RM06/Chap6name.html
+ */
+
+#define TT_MAC_LANGID_ENGLISH                           0
+#define TT_MAC_LANGID_FRENCH                            1
+#define TT_MAC_LANGID_GERMAN                            2
+#define TT_MAC_LANGID_ITALIAN                           3
+#define TT_MAC_LANGID_DUTCH                             4
+#define TT_MAC_LANGID_SWEDISH                           5
+#define TT_MAC_LANGID_SPANISH                           6
+#define TT_MAC_LANGID_DANISH                            7
+#define TT_MAC_LANGID_PORTUGUESE                        8
+#define TT_MAC_LANGID_NORWEGIAN                         9
+#define TT_MAC_LANGID_HEBREW                            10
+#define TT_MAC_LANGID_JAPANESE                          11
+#define TT_MAC_LANGID_ARABIC                            12
+#define TT_MAC_LANGID_FINNISH                           13
+#define TT_MAC_LANGID_GREEK                             14
+#define TT_MAC_LANGID_ICELANDIC                         15
+#define TT_MAC_LANGID_MALTESE                           16
+#define TT_MAC_LANGID_TURKISH                           17
+#define TT_MAC_LANGID_CROATIAN                          18
+#define TT_MAC_LANGID_CHINESE_TRADITIONAL               19
+#define TT_MAC_LANGID_URDU                              20
+#define TT_MAC_LANGID_HINDI                             21
+#define TT_MAC_LANGID_THAI                              22
+#define TT_MAC_LANGID_KOREAN                            23
+#define TT_MAC_LANGID_LITHUANIAN                        24
+#define TT_MAC_LANGID_POLISH                            25
+#define TT_MAC_LANGID_HUNGARIAN                         26
+#define TT_MAC_LANGID_ESTONIAN                          27
+#define TT_MAC_LANGID_LETTISH                           28
+#define TT_MAC_LANGID_SAAMISK                           29
+#define TT_MAC_LANGID_FAEROESE                          30
+#define TT_MAC_LANGID_FARSI                             31
+#define TT_MAC_LANGID_RUSSIAN                           32
+#define TT_MAC_LANGID_CHINESE_SIMPLIFIED                33
+#define TT_MAC_LANGID_FLEMISH                           34
+#define TT_MAC_LANGID_IRISH                             35
+#define TT_MAC_LANGID_ALBANIAN                          36
+#define TT_MAC_LANGID_ROMANIAN                          37
+#define TT_MAC_LANGID_CZECH                             38
+#define TT_MAC_LANGID_SLOVAK                            39
+#define TT_MAC_LANGID_SLOVENIAN                         40
+#define TT_MAC_LANGID_YIDDISH                           41
+#define TT_MAC_LANGID_SERBIAN                           42
+#define TT_MAC_LANGID_MACEDONIAN                        43
+#define TT_MAC_LANGID_BULGARIAN                         44
+#define TT_MAC_LANGID_UKRAINIAN                         45
+#define TT_MAC_LANGID_BYELORUSSIAN                      46
+#define TT_MAC_LANGID_UZBEK                             47
+#define TT_MAC_LANGID_KAZAKH                            48
+#define TT_MAC_LANGID_AZERBAIJANI                       49
+#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT         50
+#define TT_MAC_LANGID_ARMENIAN                          51
+#define TT_MAC_LANGID_GEORGIAN                          52
+#define TT_MAC_LANGID_MOLDAVIAN                         53
+#define TT_MAC_LANGID_KIRGHIZ                           54
+#define TT_MAC_LANGID_TAJIKI                            55
+#define TT_MAC_LANGID_TURKMEN                           56
+#define TT_MAC_LANGID_MONGOLIAN                         57
+#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT         58
+#define TT_MAC_LANGID_PASHTO                            59
+#define TT_MAC_LANGID_KURDISH                           60
+#define TT_MAC_LANGID_KASHMIRI                          61
+#define TT_MAC_LANGID_SINDHI                            62
+#define TT_MAC_LANGID_TIBETAN                           63
+#define TT_MAC_LANGID_NEPALI                            64
+#define TT_MAC_LANGID_SANSKRIT                          65
+#define TT_MAC_LANGID_MARATHI                           66
+#define TT_MAC_LANGID_BENGALI                           67
+#define TT_MAC_LANGID_ASSAMESE                          68
+#define TT_MAC_LANGID_GUJARATI                          69
+#define TT_MAC_LANGID_PUNJABI                           70
+#define TT_MAC_LANGID_ORIYA                             71
+#define TT_MAC_LANGID_MALAYALAM                         72
+#define TT_MAC_LANGID_KANNADA                           73
+#define TT_MAC_LANGID_TAMIL                             74
+#define TT_MAC_LANGID_TELUGU                            75
+#define TT_MAC_LANGID_SINHALESE                         76
+#define TT_MAC_LANGID_BURMESE                           77
+#define TT_MAC_LANGID_KHMER                             78
+#define TT_MAC_LANGID_LAO                               79
+#define TT_MAC_LANGID_VIETNAMESE                        80
+#define TT_MAC_LANGID_INDONESIAN                        81
+#define TT_MAC_LANGID_TAGALOG                           82
+#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT                83
+#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT               84
+#define TT_MAC_LANGID_AMHARIC                           85
+#define TT_MAC_LANGID_TIGRINYA                          86
+#define TT_MAC_LANGID_GALLA                             87
+#define TT_MAC_LANGID_SOMALI                            88
+#define TT_MAC_LANGID_SWAHILI                           89
+#define TT_MAC_LANGID_RUANDA                            90
+#define TT_MAC_LANGID_RUNDI                             91
+#define TT_MAC_LANGID_CHEWA                             92
+#define TT_MAC_LANGID_MALAGASY                          93
+#define TT_MAC_LANGID_ESPERANTO                         94
+#define TT_MAC_LANGID_WELSH                             128
+#define TT_MAC_LANGID_BASQUE                            129
+#define TT_MAC_LANGID_CATALAN                           130
+#define TT_MAC_LANGID_LATIN                             131
+#define TT_MAC_LANGID_QUECHUA                           132
+#define TT_MAC_LANGID_GUARANI                           133
+#define TT_MAC_LANGID_AYMARA                            134
+#define TT_MAC_LANGID_TATAR                             135
+#define TT_MAC_LANGID_UIGHUR                            136
+#define TT_MAC_LANGID_DZONGKHA                          137
+#define TT_MAC_LANGID_JAVANESE                          138
+#define TT_MAC_LANGID_SUNDANESE                         139
+#define TT_MAC_LANGID_SCOTTISH_GAELIC                   140
+#define TT_MAC_LANGID_IRISH_GAELIC                      141
+#define TT_MAC_LANGID_BRETON                            142
+#define TT_MAC_LANGID_INUKTITUT                         143
+
+
+/*
+ * possible values of the language identifier field in the name records of
+ * the TTF "name" table when the 'Platform' identifier code is
+ * TT_PLATFORM_MICROSOFT
+ *
+ * the canonical source for the MS assigned LCID's is at
+ * http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt
+ */
+
+#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA                0x0401
+#define TT_MS_LANGID_ARABIC_IRAQ                        0x0801
+#define TT_MS_LANGID_ARABIC_EGYPT                       0x0c01
+#define TT_MS_LANGID_ARABIC_LIBYA                       0x1001
+#define TT_MS_LANGID_ARABIC_ALGERIA                     0x1401
+#define TT_MS_LANGID_ARABIC_MOROCCO                     0x1801
+#define TT_MS_LANGID_ARABIC_TUNISIA                     0x1c01
+#define TT_MS_LANGID_ARABIC_OMAN                        0x2001
+#define TT_MS_LANGID_ARABIC_YEMEN                       0x2401
+#define TT_MS_LANGID_ARABIC_SYRIA                       0x2801
+#define TT_MS_LANGID_ARABIC_JORDAN                      0x2c01
+#define TT_MS_LANGID_ARABIC_LEBANON                     0x3001
+#define TT_MS_LANGID_ARABIC_KUWAIT                      0x3401
+#define TT_MS_LANGID_ARABIC_UAE                         0x3801
+#define TT_MS_LANGID_ARABIC_BAHRAIN                     0x3c01
+#define TT_MS_LANGID_ARABIC_QATAR                       0x4001
+#define TT_MS_LANGID_BULGARIAN_BULGARIA                 0x0402
+#define TT_MS_LANGID_CATALAN_SPAIN                      0x0403
+#define TT_MS_LANGID_CHINESE_TAIWAN                     0x0404
+#define TT_MS_LANGID_CHINESE_PRC                        0x0804
+#define TT_MS_LANGID_CHINESE_HONG_KONG                  0x0c04
+#define TT_MS_LANGID_CHINESE_SINGAPORE                  0x1004
+#define TT_MS_LANGID_CHINESE_MACAU                      0x1404
+#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC               0x0405
+#define TT_MS_LANGID_DANISH_DENMARK                     0x0406
+#define TT_MS_LANGID_GERMAN_GERMANY                     0x0407
+#define TT_MS_LANGID_GERMAN_SWITZERLAND                 0x0807
+#define TT_MS_LANGID_GERMAN_AUSTRIA                     0x0c07
+#define TT_MS_LANGID_GERMAN_LUXEMBOURG                  0x1007
+#define TT_MS_LANGID_GERMAN_LIECHTENSTEI                0x1407
+#define TT_MS_LANGID_GREEK_GREECE                       0x0408
+#define TT_MS_LANGID_ENGLISH_UNITED_STATES              0x0409
+#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM             0x0809
+#define TT_MS_LANGID_ENGLISH_AUSTRALIA                  0x0c09
+#define TT_MS_LANGID_ENGLISH_CANADA                     0x1009
+#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND                0x1409
+#define TT_MS_LANGID_ENGLISH_IRELAND                    0x1809
+#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA               0x1c09
+#define TT_MS_LANGID_ENGLISH_JAMAICA                    0x2009
+#define TT_MS_LANGID_ENGLISH_CARIBBEAN                  0x2409
+#define TT_MS_LANGID_ENGLISH_BELIZE                     0x2809
+#define TT_MS_LANGID_ENGLISH_TRINIDAD                   0x2c09
+#define TT_MS_LANGID_ENGLISH_ZIMBABWE                   0x3009
+#define TT_MS_LANGID_ENGLISH_PHILIPPINES                0x3409
+#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT     0x040a
+#define TT_MS_LANGID_SPANISH_MEXICO                     0x080a
+#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT   0x0c0a
+#define TT_MS_LANGID_SPANISH_GUATEMALA                  0x100a
+#define TT_MS_LANGID_SPANISH_COSTA_RICA                 0x140a
+#define TT_MS_LANGID_SPANISH_PANAMA                     0x180a
+#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC         0x1c0a
+#define TT_MS_LANGID_SPANISH_VENEZUELA                  0x200a
+#define TT_MS_LANGID_SPANISH_COLOMBIA                   0x240a
+#define TT_MS_LANGID_SPANISH_PERU                       0x280a
+#define TT_MS_LANGID_SPANISH_ARGENTINA                  0x2c0a
+#define TT_MS_LANGID_SPANISH_ECUADOR                    0x300a
+#define TT_MS_LANGID_SPANISH_CHILE                      0x340a
+#define TT_MS_LANGID_SPANISH_URUGUAY                    0x380a
+#define TT_MS_LANGID_SPANISH_PARAGUAY                   0x3c0a
+#define TT_MS_LANGID_SPANISH_BOLIVIA                    0x400a
+#define TT_MS_LANGID_SPANISH_EL_SALVADOR                0x440a
+#define TT_MS_LANGID_SPANISH_HONDURAS                   0x480a
+#define TT_MS_LANGID_SPANISH_NICARAGUA                  0x4c0a
+#define TT_MS_LANGID_SPANISH_PUERTO_RICO                0x500a
+#define TT_MS_LANGID_FINNISH_FINLAND                    0x040b
+#define TT_MS_LANGID_FRENCH_FRANCE                      0x040c
+#define TT_MS_LANGID_FRENCH_BELGIUM                     0x080c
+#define TT_MS_LANGID_FRENCH_CANADA                      0x0c0c
+#define TT_MS_LANGID_FRENCH_SWITZERLAND                 0x100c
+#define TT_MS_LANGID_FRENCH_LUXEMBOURG                  0x140c
+#define TT_MS_LANGID_FRENCH_MONACO                      0x180c
+#define TT_MS_LANGID_HEBREW_ISRAEL                      0x040d
+#define TT_MS_LANGID_HUNGARIAN_HUNGARY                  0x040e
+#define TT_MS_LANGID_ICELANDIC_ICELAND                  0x040f
+#define TT_MS_LANGID_ITALIAN_ITALY                      0x0410
+#define TT_MS_LANGID_ITALIAN_SWITZERLAND                0x0810
+#define TT_MS_LANGID_JAPANESE_JAPAN                     0x0411
+#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA      0x0412
+#define TT_MS_LANGID_KOREAN_JOHAB_KOREA                 0x0812
+#define TT_MS_LANGID_DUTCH_NETHERLANDS                  0x0413
+#define TT_MS_LANGID_DUTCH_BELGIUM                      0x0813
+#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL            0x0414
+#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK           0x0814
+#define TT_MS_LANGID_POLISH_POLAND                      0x0415
+#define TT_MS_LANGID_PORTUGUESE_BRAZIL                  0x0416
+#define TT_MS_LANGID_PORTUGUESE_PORTUGAL                0x0816
+#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND         0x0417
+#define TT_MS_LANGID_ROMANIAN_ROMANIA                   0x0418
+#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA                 0x0818
+#define TT_MS_LANGID_RUSSIAN_RUSSIA                     0x0419
+#define TT_MS_LANGID_RUSSIAN_MOLDAVIA                   0x0819
+#define TT_MS_LANGID_CROATIAN_CROATIA                   0x041a
+#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN               0x081a
+#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC            0x0c1a
+#define TT_MS_LANGID_SLOVAK_SLOVAKIA                    0x041b
+#define TT_MS_LANGID_ALBANIAN_ALBANIA                   0x041c
+#define TT_MS_LANGID_SWEDISH_SWEDEN                     0x041d
+#define TT_MS_LANGID_SWEDISH_FINLAND                    0x081d
+#define TT_MS_LANGID_THAI_THAILAND                      0x041e
+#define TT_MS_LANGID_TURKISH_TURKEY                     0x041f
+#define TT_MS_LANGID_URDU_PAKISTAN                      0x0420
+#define TT_MS_LANGID_INDONESIAN_INDONESIA               0x0421
+#define TT_MS_LANGID_UKRAINIAN_UKRAINE                  0x0422
+#define TT_MS_LANGID_BELARUSIAN_BELARUS                 0x0423
+#define TT_MS_LANGID_SLOVENE_SLOVENIA                   0x0424
+#define TT_MS_LANGID_ESTONIAN_ESTONIA                   0x0425
+#define TT_MS_LANGID_LATVIAN_LATVIA                     0x0426
+#define TT_MS_LANGID_LITHUANIAN_LITHUANIA               0x0427
+#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA       0x0827
+#define TT_MS_LANGID_MAORI_NEW_ZEALAND                  0x0428
+#define TT_MS_LANGID_FARSI_IRAN                         0x0429
+#define TT_MS_LANGID_VIETNAMESE_VIET_NAM                0x042a
+#define TT_MS_LANGID_ARMENIAN_ARMENIA                   0x042b
+#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN             0x042c
+#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC          0x082c
+#define TT_MS_LANGID_BASQUE_SPAIN                       0x042d
+#define TT_MS_LANGID_SORBIAN_GERMANY                    0x042e
+#define TT_MS_LANGID_MACEDONIAN_MACEDONIA               0x042f
+#define TT_MS_LANGID_SUTU_SOUTH_AFRICA                  0x0430
+#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA                0x0431
+#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA                0x0432
+#define TT_MS_LANGID_VENDA_SOUTH_AFRICA                 0x0433
+#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA                 0x0434
+#define TT_MS_LANGID_ZULU_SOUTH_AFRICA                  0x0435
+#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA             0x0436
+#define TT_MS_LANGID_GEORGIAN_GEORGIA                   0x0437
+#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS            0x0438
+#define TT_MS_LANGID_HINDI_INDIA                        0x0439
+#define TT_MS_LANGID_MALTESE_MALTA                      0x043a
+#define TT_MS_LANGID_SAAMI_LAPONIA                      0x043b
+#define TT_MS_LANGID_IRISH_GAELIC_IRELAND               0x043c
+#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM     0x083c
+#define TT_MS_LANGID_MALAY_MALAYSIA                     0x043e
+#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM            0x083e
+#define TT_MS_LANGID_KAZAK_KAZAKSTAN                    0x043f
+#define TT_MS_LANGID_SWAHILI_KENYA                      0x0441
+#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN             0x0443
+#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC          0x0843
+#define TT_MS_LANGID_TATAR_TATARSTAN                    0x0444
+#define TT_MS_LANGID_BENGALI_INDIA                      0x0445
+#define TT_MS_LANGID_PUNJABI_INDIA                      0x0446
+#define TT_MS_LANGID_GUJARATI_INDIA                     0x0447
+#define TT_MS_LANGID_ORIYA_INDIA                        0x0448
+#define TT_MS_LANGID_TAMIL_INDIA                        0x0449
+#define TT_MS_LANGID_TELUGU_INDIA                       0x044a
+#define TT_MS_LANGID_KANNADA_INDIA                      0x044b
+#define TT_MS_LANGID_MALAYALAM_INDIA                    0x044c
+#define TT_MS_LANGID_ASSAMESE_INDIA                     0x044d
+#define TT_MS_LANGID_MARATHI_INDIA                      0x044e
+#define TT_MS_LANGID_SANSKRIT_INDIA                     0x044f
+#define TT_MS_LANGID_KONKANI_INDIA                      0x0457
+
+
+/*
+ * possible values of the 'Name' identifier field in the name records of
+ * the TTF "name" table.  These values are platform independent.
+ */
+
+#define TT_NAME_ID_COPYRIGHT            0
+#define TT_NAME_ID_FONT_FAMILY          1
+#define TT_NAME_ID_FONT_SUBFAMILY       2
+#define TT_NAME_ID_UNIQUE_ID            3
+#define TT_NAME_ID_FULL_NAME            4
+#define TT_NAME_ID_VERSION_STRING       5
+#define TT_NAME_ID_PS_NAME              6
+#define TT_NAME_ID_TRADEMARK            7
+/* the following values are from the OpenType spec */
+#define TT_NAME_ID_MANUFACTURER         8
+#define TT_NAME_ID_DESIGNER             9
+#define TT_NAME_ID_DESCRIPTION          10
+#define TT_NAME_ID_VENDOR_URL           11
+#define TT_NAME_ID_DESIGNER_URL         12
+#define TT_NAME_ID_LICENSE              13
+#define TT_NAME_ID_LICENSE_URL          14
+/* number 15 is reserved */
+#define TT_NAME_ID_PREFERRED_FAMILY     16
+#define TT_NAME_ID_PREFERRED_SUBFAMILY  17
+#define TT_NAME_ID_MAC_FULL_NAME        18
+
+
+/*
+ * Bit Mask values for the Unicode Ranges from the TTF "OS2 " table.
+ */
+
+/* General Scripts Area */
+
+/* Bit  0   C0 Controls and Basic Latin */
+#define TT_UCR_BASIC_LATIN                     (1L <<  0) /* U+0000-U+007F */
+/* Bit  1   C1 Controls and Latin-1 Supplement */
+#define TT_UCR_LATIN1_SUPPLEMENT               (1L <<  1) /* U+0080-U+00FF */
+/* Bit  2   Latin Extended-A */
+#define TT_UCR_LATIN_EXTENDED_A                (1L <<  2) /* U+0100-U+017F */
+/* Bit  3   Latin Extended-B */
+#define TT_UCR_LATIN_EXTENDED_B                (1L <<  3) /* U+0180-U+024F */
+/* Bit  4   IPA Extensions */
+#define TT_UCR_IPA_EXTENSIONS                  (1L <<  4) /* U+0250-U+02AF */
+/* Bit  5   Spacing Modifier Letters */
+#define TT_UCR_SPACING_MODIFIER                (1L <<  5) /* U+02B0-U+02FF */
+/* Bit  6   Combining Diacritical Marks */
+#define TT_UCR_COMBINING_DIACRITICS            (1L <<  6) /* U+0300-U+036F */
+/* Bit  7   Greek */
+#define TT_UCR_GREEK                           (1L <<  7) /* U+0370-U+03FF */
+/* Bit 8 is reserved (was: Greek Symbols and Coptic) */
+/* Bit  9   Cyrillic */
+#define TT_UCR_CYRILLIC                        (1L <<  9) /* U+0400-U+04FF */
+/* Bit 10   Armenian */
+#define TT_UCR_ARMENIAN                        (1L << 10) /* U+0530-U+058F */
+/* Bit 11   Hebrew */
+#define TT_UCR_HEBREW                          (1L << 11) /* U+0590-U+05FF */
+/* Bit 12 is reserved (was: Hebrew Extended) */
+/* Bit 13   Arabic */
+#define TT_UCR_ARABIC                          (1L << 13) /* U+0600-U+06FF */
+/* Bit 14 is reserved (was: Arabic Extended) */
+/* Bit 15   Devanagari */
+#define TT_UCR_DEVANAGARI                      (1L << 15) /* U+0900-U+097F */
+/* Bit 16   Bengali */
+#define TT_UCR_BENGALI                         (1L << 16) /* U+0980-U+09FF */
+/* Bit 17   Gurmukhi */
+#define TT_UCR_GURMUKHI                        (1L << 17) /* U+0A00-U+0A7F */
+/* Bit 18   Gujarati */
+#define TT_UCR_GUJARATI                        (1L << 18) /* U+0A80-U+0AFF */
+/* Bit 19   Oriya */
+#define TT_UCR_ORIYA                           (1L << 19) /* U+0B00-U+0B7F */
+/* Bit 20   Tamil */
+#define TT_UCR_TAMIL                           (1L << 20) /* U+0B80-U+0BFF */
+/* Bit 21   Telugu */
+#define TT_UCR_TELUGU                          (1L << 21) /* U+0C00-U+0C7F */
+/* Bit 22   Kannada */
+#define TT_UCR_KANNADA                         (1L << 22) /* U+0C80-U+0CFF */
+/* Bit 23   Malayalam */
+#define TT_UCR_MALAYALAM                       (1L << 23) /* U+0D00-U+0D7F */
+/* Bit 24   Thai */
+#define TT_UCR_THAI                            (1L << 24) /* U+0E00-U+0E7F */
+/* Bit 25   Lao */
+#define TT_UCR_LAO                             (1L << 25) /* U+0E80-U+0EFF */
+/* Bit 26   Georgian */
+#define TT_UCR_GEORGIAN                        (1L << 26) /* U+10A0-U+10FF */
+/* Bit 27 is reserved (was Georgian Extended) */
+/* Bit 28   Hangul Jamo */
+#define TT_UCR_HANGUL_JAMO                     (1L << 28) /* U+1100-U+11FF */
+/* Bit 29   Latin Extended Additional */
+#define TT_UCR_LATIN_EXTENDED_ADDITIONAL       (1L << 29) /* U+1E00-U+1EFF */
+/* Bit 30   Greek Extended */
+#define TT_UCR_GREEK_EXTENDED                  (1L << 30) /* U+1F00-U+1FFF */
+
+/* Symbols Area */
+
+/* Bit 31   General Punctuation */
+#define TT_UCR_GENERAL_PUNCTUATION             (1L << 31) /* U+2000-U+206F */
+/* Bit 32   Superscripts And Subscripts */
+#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS         (1L <<  0) /* U+2070-U+209F */
+/* Bit 33   Currency Symbols */
+#define TT_UCR_CURRENCY_SYMBOLS                (1L <<  1) /* U+20A0-U+20CF */
+/* Bit 34   Combining Diacritical Marks For Symbols */
+#define TT_UCR_COMBINING_DIACRITICS_SYMB       (1L <<  2) /* U+20D0-U+20FF */
+/* Bit 35   Letterlike Symbols */
+#define TT_UCR_LETTERLIKE_SYMBOLS              (1L <<  3) /* U+2100-U+214F */
+/* Bit 36   Number Forms */
+#define TT_UCR_NUMBER_FORMS                    (1L <<  4) /* U+2150-U+218F */
+/* Bit 37   Arrows */
+#define TT_UCR_ARROWS                          (1L <<  5) /* U+2190-U+21FF */
+/* Bit 38   Mathematical Operators */
+#define TT_UCR_MATHEMATICAL_OPERATORS          (1L <<  6) /* U+2200-U+22FF */
+/* Bit 39 Miscellaneous Technical */
+#define TT_UCR_MISCELLANEOUS_TECHNICAL         (1L <<  7) /* U+2300-U+23FF */
+/* Bit 40   Control Pictures */
+#define TT_UCR_CONTROL_PICTURES                (1L <<  8) /* U+2400-U+243F */
+/* Bit 41   Optical Character Recognition */
+#define TT_UCR_OCR                             (1L <<  9) /* U+2440-U+245F */
+/* Bit 42   Enclosed Alphanumerics */
+#define TT_UCR_ENCLOSED_ALPHANUMERICS          (1L << 10) /* U+2460-U+24FF */
+/* Bit 43   Box Drawing */
+#define TT_UCR_BOX_DRAWING                     (1L << 11) /* U+2500-U+257F */
+/* Bit 44   Block Elements */
+#define TT_UCR_BLOCK_ELEMENTS                  (1L << 12) /* U+2580-U+259F */
+/* Bit 45   Geometric Shapes */
+#define TT_UCR_GEOMETRIC_SHAPES                (1L << 13) /* U+25A0-U+25FF */
+/* Bit 46   Miscellaneous Symbols */
+#define TT_UCR_MISCELLANEOUS_SYMBOLS           (1L << 14) /* U+2600-U+26FF */
+/* Bit 47   Dingbats */
+#define TT_UCR_DINGBATS                        (1L << 15) /* U+2700-U+27BF */
+
+/* CJK Phonetics and Symbols Area */
+
+/* Bit 48   CJK Symbols And Punctuation */
+#define TT_UCR_CJK_SYMBOLS                     (1L << 16) /* U+3000-U+303F */
+/* Bit 49   Hiragana */
+#define TT_UCR_HIRAGANA                        (1L << 17) /* U+3040-U+309F */
+/* Bit 50   Katakana */
+#define TT_UCR_KATAKANA                        (1L << 18) /* U+30A0-U+30FF */
+/* Bit 51   Bopomofo */
+#define TT_UCR_BOPOMOFO                        (1L << 19) /* U+3100-U+312F */
+/* Bit 52   Hangul Compatibility Jamo */
+#define TT_UCR_HANGUL_COMPATIBILITY_JAMO       (1L << 20) /* U+3130-U+318F */
+/* Bit 53   CJK Miscellaneous */
+#define TT_UCR_CJK_MISC                        (1L << 21) /* U+3190-U+319F */
+/* Bit 54   Enclosed CJK Letters And Months */
+#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS     (1L << 22) /* U+3200-U+32FF */
+/* Bit 55   CJK Compatibility */
+#define TT_UCR_CJK_COMPATIBILITY               (1L << 23) /* U+3300-U+33FF */
+
+/* Hangul Syllables Area */
+
+/* Bit 56   Hangul */
+#define TT_UCR_HANGUL                          (1L << 24) /* U+AC00-U+D7A3 */
+
+/* Surrogates Area */
+
+/* Bit 57   Surrogates */
+#define TT_UCR_SURROGATES                      (1L << 25) /* U+D800-U+DFFF */
+/* Bit 58 is reserved for Unicode SubRanges */
+
+/* CJK Ideographs Area */
+
+/* Bit 59   CJK Unified Ideographs */
+#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS          (1L << 27) /* U+4E00-U+9FFF */
+
+/* Private Use Area */
+
+/* Bit 60   Private Use */
+#define TT_UCR_PRIVATE_USE                     (1L << 28) /* U+E000-U+F8FF */
+
+/* Compatibility Area and Specials */
+
+/* Bit 61   CJK Compatibility Ideographs */
+#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS    (1L << 29) /* U+F900-U+FAFF */
+/* Bit 62   Alphabetic Presentation Forms */
+#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS   (1L << 30) /* U+FB00-U+FB4F */
+/* Bit 63   Arabic Presentation Forms-A */
+#define TT_UCR_ARABIC_PRESENTATIONS_A          (1L << 31) /* U+FB50-U+FSFF */
+/* Bit 64   Combining Half Marks */
+#define TT_UCR_COMBINING_HALF_MARKS            (1L <<  0) /* U+FE20-U+FE2F */
+/* Bit 65   CJK Compatibility Forms */
+#define TT_UCR_CJK_COMPATIBILITY_FORMS         (1L <<  1) /* U+FE30-U+FE4F */
+/* Bit 66   Small Form Variants */
+#define TT_UCR_SMALL_FORM_VARIANTS             (1L <<  2) /* U+FE50-U+FE6F */
+/* Bit 67   Arabic Presentation Forms-B */
+#define TT_UCR_ARABIC_PRESENTATIONS_B          (1L <<  3) /* U+FE70-U+FEFF */
+/* Bit 68   Halfwidth And Fullwidth Forms */
+#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS       (1L <<  4) /* U+FF00-U+FFEF */
+/* Bit 69   Specials */
+#define TT_UCR_SPECIALS                        (1L <<  5) /* U+FEFF,
+                                                             U+FFF0-U+FFFF */
+/* Bit 70   Tibetan */
+#define TT_UCR_TIBETAN                         (1L <<  6) /* U+0F00-U+0FBF */
+
+
+/* Some compilers have a very limited length of identifiers. */
+#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ )
+#define HAVE_LIMIT_ON_IDENTS
+#endif
+
+#ifndef HAVE_LIMIT_ON_IDENTS
+
+/*
+ *  Here some alias #defines in order to be clearer.
+ *
+ *  These are not always #defined to stay within the 31 character limit
+ *  which some compilers have.
+ *
+ *  Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern
+ *  Borland compilers (read: from BC++ 3.1 on) can increase this limit.
+ *  If you get a warning with such a compiler, use the -i40 switch.
+ */
+ 
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_A      \
+         TT_UCR_ARABIC_PRESENTATIONS_A
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_B      \
+         TT_UCR_ARABIC_PRESENTATIONS_B           
+
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS      \
+         TT_UCR_COMBINING_DIACRITICS
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \
+         TT_UCR_COMBINING_DIACRITICS_SYMB
+
+#endif /* ndef HAVE_LIMIT_ON_IDENTS */
+
+#endif /* TTNAMEID_H */
+
+
+/* END */
diff --git a/obj/README b/obj/README
new file mode 100644
index 0000000..91fdcbd
--- /dev/null
+++ b/obj/README
@@ -0,0 +1 @@
+This directory contains all the object files created when building the library
diff --git a/src/base/ftbase.c b/src/base/ftbase.c
new file mode 100644
index 0000000..0a00e62
--- /dev/null
+++ b/src/base/ftbase.c
@@ -0,0 +1,6 @@
+#include <ftcalc.c>
+#include <ftobjs.c>
+#include <ftstream.c>
+#include <ftlist.c>
+
+#include <ftextend.c>
diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c
new file mode 100644
index 0000000..71d4430
--- /dev/null
+++ b/src/base/ftbbox.c
@@ -0,0 +1,447 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftbbox.c                                                               */
+/*                                                                         */
+/*    FreeType bbox computation (body).                                    */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This component has a _single_ role: to compute exact outline bounding */
+  /* boxes.                                                                */
+  /*                                                                       */
+  /* It is separated from the rest of the engine for various technical     */
+  /* reasons.  It may well be integrated in `ftoutln' later.               */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include <ftbbox.h>
+#include <ftimage.h>
+#include <ftobjs.h>
+
+  typedef struct  TBBox_Rec_
+  {
+    FT_Vector  last;
+    FT_BBox    bbox;
+
+  } TBBox_Rec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    BBox_Move_To                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used as a `move_to' and `line_to' emitter during  */
+  /*    FT_Raster_Decompose().  It simply records the destination point in */
+  /*    user->last.                                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    to   :: The destination vector.                                    */
+  /*    user :: The current walk context.                                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  static
+  int  BBox_Move_To( FT_Vector*  to,
+                     TBBox_Rec*  user )
+  {
+    user->last = *to;
+
+    return 0;
+  }
+
+
+#define CHECK_X( p, bbox )  \
+          ( p->x < bbox.xMin || p->x > bbox.xMax )
+
+#define CHECK_Y( p, bbox )  \
+          ( p->y < bbox.yMin || p->y > bbox.yMax )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    BBox_Conic_Check                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finds the extrema of a 1-dimensional conic Bezier curve and update */
+  /*    a bounding range.  This version uses direct computation, as it     */
+  /*    doesn't need square roots.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y1  :: The start coordinate.                                       */
+  /*    y2  :: The coordinate of the control point.                        */
+  /*    y3  :: The end coordinate.                                         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    min :: The address of the current minimum.                         */
+  /*    max :: The address of the current maximum.                         */
+  /*                                                                       */
+  static
+  void  BBox_Conic_Check( FT_Pos   y1,
+                          FT_Pos   y2,
+                          FT_Pos   y3,
+                          FT_Pos*  min,
+                          FT_Pos*  max )
+  {
+    if( y1 == y3 )
+    {
+      if ( y2 == y1 )               /* Flat arc */
+      {
+        y3 = y1;
+        goto Suite;
+      }
+    }
+    else if ( y1 < y3 )
+    {
+      if ( y2 >= y1 && y2 <= y3 )   /* Ascending arc */
+        goto Suite;
+    }
+    else
+    {
+      if ( y2 >= y3 && y2 <= y1 )   /* Descending arc */
+      {
+        y2 = y1;
+        y1 = y3;
+        y3 = y2;
+        goto Suite;
+      }
+    }
+
+    y1 = y3 = FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 );
+
+  Suite:
+    if ( y1 < *min ) *min = y1;
+    if ( y3 > *max ) *max = y3;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    BBox_Conic_To                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used as a `conic_to' emitter during               */
+  /*    FT_Raster_Decompose().  It checks a conic Bezier curve with the    */
+  /*    current bounding box, and computes its extrema if necessary to     */
+  /*    update it.                                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    control :: A control point.                                        */
+  /*    to      :: The destination vector.                                 */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    user    :: The current walk context.                               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    In the case of a non-monotonous arc, we compute directly the       */
+  /*    extremum coordinates, as it is sufficiently fast.                  */
+  /*                                                                       */
+  static
+  int  BBox_Conic_To( FT_Vector*  control,
+                      FT_Vector*  to,
+                      TBBox_Rec*  user )
+  {
+    if ( CHECK_X( control, user->bbox ) ||
+         CHECK_X( to,      user->bbox ) )
+
+      BBox_Conic_Check( user->last.x,
+                        control->x,
+                        to->x,
+                        &user->bbox.xMin,
+                        &user->bbox.xMax );
+
+    if ( CHECK_Y( control, user->bbox ) ||
+         CHECK_Y( to,      user->bbox ) )
+
+      BBox_Conic_Check( user->last.y,
+                        control->y,
+                        to->y,
+                        &user->bbox.yMin,
+                        &user->bbox.yMax );
+
+    return 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    BBox_Cubic_Check                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finds the extrema of a 1-dimensional cubic Bezier curve and        */
+  /*    updates a bounding range.  This version uses splitting because we  */
+  /*    don't want to use square roots and extra accuracies.               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    p1  :: The start coordinate.                                       */
+  /*    p2  :: The coordinate of the first control point.                  */
+  /*    p3  :: The coordinate of the second control point.                 */
+  /*    p4  :: The end coordinate.                                         */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    min :: The address of the current minimum.                         */
+  /*    max :: The address of the current maximum.                         */
+  /*                                                                       */
+  static
+  void  BBox_Cubic_Check( FT_Pos   p1,
+                          FT_Pos   p2,
+                          FT_Pos   p3,
+                          FT_Pos   p4,
+                          FT_Pos*  min,
+                          FT_Pos*  max )
+  {
+    FT_Pos  stack[33], *arc;
+
+
+    arc = stack;
+
+    arc[0] = p1;
+    arc[1] = p2;
+    arc[2] = p3;
+    arc[3] = p4;
+
+    do
+    {
+      FT_Pos  y1 = arc[0];
+      FT_Pos  y2 = arc[1];
+      FT_Pos  y3 = arc[2];
+      FT_Pos  y4 = arc[3];
+
+
+      if ( y1 == y4 )
+      {
+        if ( y1 == y2 && y1 == y3 )                         /* Flat */
+        {
+          y4 = y1;
+          goto Test;
+        }
+      }
+      else if ( y1 < y4 )
+      {
+        if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) /* Ascending */
+          goto Test;
+      }
+      else
+      {
+        if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) /* Descending */
+        {
+          y2 = y1;
+          y1 = y4;
+          y4 = y2;
+          goto Test;
+        }
+      }
+
+      /* Unknown direction, split the arc in two */
+      arc[6] = y4;
+      arc[1] = y1 = ( y1 + y2 ) / 2;
+      arc[5] = y4 = ( y4 + y3 ) / 2;
+      y2 = ( y2 + y3 ) / 2;
+      arc[2] = y1 = ( y1 + y2 ) / 2;
+      arc[4] = y4 = ( y4 + y2 ) / 2;
+      arc[3] = ( y1 + y4 ) / 2;
+
+      arc += 3;
+      goto Suite;
+
+   Test:
+      if ( y1 < *min ) *min = y1;
+      if ( y4 > *max ) *max = y4;
+      arc -= 3;
+
+    Suite:
+      ;
+    } while (arc >= stack);
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    BBox_Cubic_To                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used as a `cubic_to' emitter during               */
+  /*    FT_Raster_Decompose().  It checks a cubic Bezier curve with the    */
+  /*    current bounding box, and computes its extrema if necessary to     */
+  /*    update it.                                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    control1 :: The first control point.                               */
+  /*    control2 :: The second control point.                              */
+  /*    to       :: The destination vector.                                */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    user     :: The current walk context.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    In the case of a non-monotonous arc, we don't compute directly     */
+  /*    extremum coordinates, we subdivise instead.                        */
+  /*                                                                       */
+  static
+  int  BBox_Cubic_To( FT_Vector*  control1,
+                      FT_Vector*  control2,
+                      FT_Vector*  to,
+                      TBBox_Rec*  user )
+  {
+    if ( CHECK_X( control1, user->bbox ) ||
+         CHECK_X( control2, user->bbox ) ||
+         CHECK_X( to,       user->bbox ) )
+
+        BBox_Cubic_Check( user->last.x,
+                          control1->x,
+                          control2->x,
+                          to->x,
+                          &user->bbox.xMin,
+                          &user->bbox.xMax );
+
+    if ( CHECK_Y( control1, user->bbox ) ||
+         CHECK_Y( control2, user->bbox ) ||
+         CHECK_Y( to,       user->bbox ) )
+
+        BBox_Cubic_Check( user->last.y,
+                          control1->y,
+                          control2->y,
+                          to->y,
+                          &user->bbox.yMin,
+                          &user->bbox.yMax );
+
+    return 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Raster_GetBBox                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the exact bounding box of an outline.  This is slower     */
+  /*    than computing the control box.  However, it uses an advanced      */
+  /*    algorithm which returns _very_ quickly when the two boxes          */
+  /*    coincide. Otherwise, the outline Bezier arcs are walked over to    */
+  /*    extract their extrema.                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline :: A pointer to the source outline.                        */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    bbox    :: The outline's exact bounding box.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Raster_GetBBox( FT_Outline*  outline,
+                               FT_BBox*     abbox )
+  {
+    FT_BBox    cbox;
+    FT_BBox    bbox;
+    FT_Vector* vec;
+    FT_UShort  n;
+
+
+    /* if outline is empty, return (0,0,0,0) */
+    if ( !outline )
+      return FT_Err_Invalid_Outline;
+
+    if ( outline->n_points == 0 || outline->n_contours <= 0 )
+    {
+      abbox->xMin = abbox->xMax = 0;
+      abbox->yMin = abbox->yMax = 0;
+      return 0;
+    }
+
+    /* We compute the control box, as well as the bounding box    */
+    /* of all `on' points in the outline.  Then, if the two boxes */
+    /* coincide, we exit immediately.                             */
+
+    vec = outline->points;
+    bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x;
+    bbox.yMin = bbox.yMin = cbox.yMin = cbox.yMax = vec->y;
+
+    for ( n = 1; n < outline->n_points; n++ )
+    {
+      FT_Pos  x = vec->x;
+      FT_Pos  y = vec->y;
+
+
+      /* update control box */
+      if ( x < cbox.xMin ) cbox.xMin = x;
+      if ( x > cbox.xMax ) cbox.xMax = x;
+
+      if ( y < cbox.yMin ) cbox.yMin = y;
+      if ( y > cbox.yMax ) cbox.yMax = y;
+
+      if ( FT_CURVE_TAG( outline->flags[n] ) == FT_Curve_Tag_On )
+      {
+        /* update bbox for `on' points only */
+        if ( x < bbox.xMin ) bbox.xMin = x;
+        if ( x > bbox.xMax ) bbox.xMax = x;
+
+        if ( y < bbox.yMin ) bbox.yMin = y;
+        if ( y > bbox.yMax ) bbox.yMax = y;
+      }
+
+      vec++;
+    }
+
+    /* test two boxes for equality */
+    if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax ||
+         cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax )
+    {
+      /* the two boxes are different, now walk over the outline to */
+      /* get the Bezier arc extrema.                               */
+
+      static FT_Outline_Funcs  interface =
+      {
+        (FT_Outline_MoveTo_Func)  BBox_Move_To,
+        (FT_Outline_LineTo_Func)  BBox_Move_To,
+        (FT_Outline_ConicTo_Func) BBox_Conic_To,
+        (FT_Outline_CubicTo_Func) BBox_Cubic_To
+      };
+
+      FT_Error   error;
+      TBBox_Rec  user;
+
+
+      user.bbox = bbox;
+
+      error = FT_Decompose_Outline( outline, &interface, &user );
+      if ( error )
+        return error;
+
+      *abbox = user.bbox;
+    }
+    else
+      *abbox = bbox;
+
+    return FT_Err_Ok;
+  }
+
+
+/* END */
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
new file mode 100644
index 0000000..9acc58e
--- /dev/null
+++ b/src/base/ftcalc.c
@@ -0,0 +1,505 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftcalc.c                                                               */
+/*                                                                         */
+/*    Arithmetic computations (body).                                      */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Support for 1-complement arithmetic has been totally dropped in this  */
+  /* release.  You can still write your own code if you need it.           */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  Implementing basic computation routines.                             */
+  /*                                                                       */
+  /* FT_MulDiv() and FT_MulFix() are declared in freetype.h.               */
+  /*                                                                       */
+  /*************************************************************************/
+
+#include <ftcalc.h>
+#include <ftdebug.h>
+#include <ftobjs.h>  /* for ABS() */
+
+
+  BASE_FUNC
+  FT_Int32  FT_Sqrt32( FT_Int32 x )
+  {
+    FT_ULong  val, root, newroot, mask;
+    
+    root = 0;
+    mask = 0x40000000;
+    val  = (FT_ULong)x;
+    do
+    {
+      newroot = root+mask;
+      if (newroot <= val)
+      {
+        val -= newroot;
+        root = newroot+mask;
+      }
+      root >>= 1;
+      mask >>= 2;
+    }
+    while (mask != 0);
+    
+    return root;
+  }
+
+  
+#ifdef LONG64
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_MulDiv                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very simple function used to perform the computation `(A*B)/C'   */
+  /*    with maximum accuracy (it uses a 64-bit intermediate integer       */
+  /*    whenever necessary).                                               */
+  /*                                                                       */
+  /*    This function isn't necessarily as fast as some processor specific */
+  /*    operations, but is at least completely portable.                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: The first multiplier.                                         */
+  /*    b :: The second multiplier.                                        */
+  /*    c :: The divisor.                                                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `(a*b)/c'.  This function never traps when trying to */
+  /*    divide by zero, it simply returns `MaxInt' or `MinInt' depending   */
+  /*    on the signs of `a' and `b'.                                       */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Long  FT_MulDiv( FT_Long  a,
+                      FT_Long  b,
+                      FT_Long  c )
+  {
+    FT_Int s;
+
+    s = 1;
+    if ( a < 0 ) { a = -a; s = -s; }
+    if ( b < 0 ) { b = -b; s = -s; }
+    if ( c < 0 ) { c = -c; s = -s; }
+
+    return s*( ((FT_Int64)a * b + (c >> 1) )/c);
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_MulFix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very simple function used to perform the computation             */
+  /*    `(A*B)/0x10000' with maximum accuracy.  Most of the time, this is  */
+  /*    used to multiply a given value by a 16.16 fixed float factor.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: The first multiplier.                                         */
+  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */
+  /*         possible (see note below).                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `(a*b)/0x10000'.                                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function has been optimized for the case where the absolute   */
+  /*    value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */
+  /*    As this happens mainly when scaling from notional units to         */
+  /*    fractional pixels in FreeType, it resulted in noticeable speed     */
+  /*    improvements between versions 2.0 and 1.x.                         */
+  /*                                                                       */
+  /*    As a conclusion, always try to place a 16.16 factor as the         */
+  /*    _second_ argument of this function; this can make a great          */
+  /*    difference.                                                        */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Long  FT_MulFix( FT_Long  a,
+                      FT_Long  b )
+  {
+    FT_Int s;
+
+    s = 1;
+    if ( a < 0 ) { a = -a; s = -s; }
+    if ( b < 0 ) { b = -b; s = -s; }
+
+    return s*(FT_Long)((FT_Int64)a * b + 0x8000) >> 16);
+  }
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_DivFix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very simple function used to perform the computation             */
+  /*    `(A*0x10000)/B' with maximum accuracy.  Most of the time, this is  */
+  /*    used to divide  a given value by a 16.16 fixed float factor.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: The first multiplier.                                         */
+  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */
+  /*         possible (see note below).                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `(a*0x10000)/b'.                                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The optimisation for FT_DivFix() is simple : if (a << 16) fits     */
+  /*    in 32 bits, then the division is computed directly. Otherwise,     */
+  /*    we use a specialised version of the old FT_MulDiv64                */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Int32  FT_DivFix( FT_Long  a,
+                       FT_Long  b )
+  {
+    FT_Int32   s;
+    FT_Word32  q;
+
+    s  = a; a = ABS(a);
+    s ^= b; b = ABS(b);
+
+    if ( b == 0 )
+      /* check for divide by 0 */
+      q = 0x7FFFFFFF;
+
+    else 
+      /* compute result directly */
+      q = ((FT_Int64)a << 16) / b;
+
+    return (FT_Int32)( s < 0 ? -q : q );
+  }
+
+
+#else /* LONG64 */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_MulDiv                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very simple function used to perform the computation `(A*B)/C'   */
+  /*    with maximum accuracy (it uses a 64-bit intermediate integer       */
+  /*    whenever necessary).                                               */
+  /*                                                                       */
+  /*    This function isn't necessarily as fast as some processor specific */
+  /*    operations, but is at least completely portable.                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: The first multiplier.                                         */
+  /*    b :: The second multiplier.                                        */
+  /*    c :: The divisor.                                                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `(a*b)/c'.  This function never traps when trying to */
+  /*    divide by zero, it simply returns `MaxInt' or `MinInt' depending   */
+  /*    on the signs of `a' and `b'.                                       */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The FT_MulDiv() function has been optimized thanks to ideas from   */
+  /*    Graham Asher.  The trick is to optimize computation if everything  */
+  /*    fits within 32 bits (a rather common case).                        */
+  /*                                                                       */
+  /*    We compute `a*b+c/2', then divide it by `c'. (positive values)     */
+  /*                                                                       */
+  /*      46340 is FLOOR(SQRT(2^31-1)).                                    */
+  /*                                                                       */
+  /*      if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 )       */
+  /*                                                                       */
+  /*      0x7FFFFFFF - 0x7FFEA810 = 0x157F0                                */
+  /*                                                                       */
+  /*      if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF )              */
+  /*                                                                       */
+  /*      and 2*0x157F0 = 176096                                           */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Long  FT_MulDiv( FT_Long  a,
+                      FT_Long  b,
+                      FT_Long  c )
+  {
+    long   s;
+
+
+    if ( a == 0 || b == c )
+      return a;
+
+    s  = a; a = ABS( a );
+    s ^= b; b = ABS( b );
+    s ^= c; c = ABS( c );
+
+    if ( a <= 46340 && b <= 46340 && c <= 176095L )
+    {
+      a = ( a*b + (c >> 1) ) / c;
+    }
+    else
+    {
+      FT_Int64  temp, temp2;
+
+      FT_MulTo64( a, b, &temp );
+      temp2.hi = (FT_Int32)(c >> 31);
+      temp2.lo = (FT_Word32)(c / 2);
+      FT_Add64( &temp, &temp2, &temp );
+      a = FT_Div64by32( &temp, c );
+    }
+
+    return ( s < 0 ) ? -a : a;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_MulFix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very simple function used to perform the computation             */
+  /*    `(A*B)/0x10000' with maximum accuracy.  Most of the time, this is  */
+  /*    used to multiply a given value by a 16.16 fixed float factor.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: The first multiplier.                                         */
+  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */
+  /*         possible (see note below).                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `(a*b)/0x10000'.                                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The optimisation for FT_MulFix() is different.  We could simply be */
+  /*    happy by applying the same principles as with FT_MulDiv(), because */
+  /*                                                                       */
+  /*    c = 0x10000 < 176096                                               */
+  /*                                                                       */
+  /*    However, in most cases, we have a `b' with a value around 0x10000  */
+  /*    which is greater than 46340.                                       */
+  /*                                                                       */
+  /*    According to some testing, most cases have `a' < 2048, so a good   */
+  /*    idea is to use bounds like 2048 and 1048576 (=floor((2^31-1)/2048) */
+  /*    for `a' and `b' respectively.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Long  FT_MulFix( FT_Long  a,
+                      FT_Long  b )
+  {
+    FT_Long   s;
+
+    if ( a == 0 || b == 0x10000L )
+      return a;
+
+    s  = a; a = ABS(a);
+    s ^= b; b = ABS(b);
+
+    if ( a <= 2048 && b <= 1048576L )
+    {
+      a = ( a*b + 0x8000 ) >> 16;
+    }
+    else
+    {
+      FT_Long  al = a & 0xFFFF;
+
+      a = (a >> 16)*b + al*(b >> 16) + ( al*(b & 0xFFFF) >> 16 );
+    }
+
+    return ( s < 0 ? -a : a );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_DivFix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very simple function used to perform the computation             */
+  /*    `(A*0x10000)/B' with maximum accuracy.  Most of the time, this is  */
+  /*    used to divide  a given value by a 16.16 fixed float factor.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: The first multiplier.                                         */
+  /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */
+  /*         possible (see note below).                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of `(a*0x10000)/b'.                                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The optimisation for FT_DivFix() is simple : if (a << 16) fits     */
+  /*    in 32 bits, then the division is computed directly. Otherwise,     */
+  /*    we use a specialised version of the old FT_MulDiv64                */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Long  FT_DivFix( FT_Long  a,
+                      FT_Long  b )
+  {
+    FT_Int32   s;
+    FT_Word32  q;
+
+    s  = a; a = ABS(a);
+    s ^= b; b = ABS(b);
+
+    if ( b == 0 )
+      /* check for divide by 0 */
+      q = 0x7FFFFFFF;
+
+    else if ( (a >> 16) == 0 )
+    {
+      /* compute result directly */
+      q = (FT_Word32)(a << 16) / (FT_Word32)b;
+    }
+    else
+    {
+      /* we need more bits, we'll have to do it by hand */
+      FT_Word32  c;
+
+      q  = (a/b) << 16;
+      c  = a%b;
+
+      /* we must compute C*0x10000/B, we simply shift C and B so */
+      /* C becomes smaller than 16 bits                          */
+      while (c >> 16)
+      {
+        c >>= 1;
+        b <<= 1;
+      }
+
+      q += (c << 16)/b;
+    }
+
+    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
+  }
+
+
+  BASE_FUNC
+  void  FT_Add64( FT_Int64*  x,
+                  FT_Int64*  y,
+                  FT_Int64*  z )
+  {
+    register FT_Word32  lo, hi;
+
+    lo = x->lo + y->lo;
+    hi = x->hi + y->hi + ( lo < x->lo );
+
+    z->lo = lo;
+    z->hi = hi;
+  }
+
+
+  BASE_FUNC
+  void  FT_MulTo64( FT_Int32   x,
+                    FT_Int32   y,
+                    FT_Int64*  z )
+  {
+    FT_Int32   s;
+
+
+    s  = x; x = ABS( x );
+    s ^= y; y = ABS( y );
+
+    {
+      FT_Word32  lo1, hi1, lo2, hi2, lo, hi, i1, i2;
+    
+      lo1 = x & 0x0000FFFF;  hi1 = x >> 16;
+      lo2 = y & 0x0000FFFF;  hi2 = y >> 16;
+
+      lo = lo1 * lo2;
+      i1 = lo1 * hi2;
+      i2 = lo2 * hi1;
+      hi = hi1 * hi2;
+
+      /* Check carry overflow of i1 + i2 */
+      i1 += i2;
+      if ( i1 < i2 )
+        hi += 1L << 16;
+
+      hi += (i1 >> 16);
+      i1  = i1 << 16;
+
+      /* Check carry overflow of i1 + lo */
+      lo += i1;
+      hi += (lo < i1);
+
+      z->lo = lo;
+      z->hi = hi;
+    }
+
+    if ( s < 0 )
+    {
+      z->lo = (FT_Word32)-(FT_Int32)z->lo;
+      z->hi = ~z->hi + !(z->lo);
+    }
+  }
+
+
+  BASE_FUNC
+  FT_Int32  FT_Div64by32( FT_Int64*  x,
+                          FT_Int32   y )
+  {
+    FT_Int32   s;
+    FT_Word32  q, r, i, lo;
+
+
+    s  = x->hi;
+    if ( s < 0 )
+    {
+      x->lo = (FT_Word32)-(FT_Int32)x->lo;
+      x->hi = ~x->hi + !(x->lo);
+    }
+    s ^= y;  y = ABS( y );
+
+    /* Shortcut */
+    if ( x->hi == 0 )
+    {
+      q = x->lo / y;
+      return ( s < 0 ) ? -(FT_Int32)q : (FT_Int32)q;
+    }
+
+    r  = x->hi;
+    lo = x->lo;
+
+    if ( r >= (FT_Word32)y ) /* we know y is to be treated as unsigned here */
+      return ( s < 0 ) ? 0x80000001L : 0x7FFFFFFFL;
+                            /* Return Max/Min Int32 if divide overflow. */
+                            /* This includes division by zero!          */
+    q = 0;
+    for ( i = 0; i < 32; i++ )
+    {
+      r <<= 1;
+      q <<= 1;
+      r  |= lo >> 31;
+
+      if ( r >= (FT_Word32)y )
+      {
+        r -= y;
+        q |= 1;
+      }
+      lo <<= 1;
+    }
+
+    return ( s < 0 ) ? -(FT_Int32)q : (FT_Int32)q;
+  }
+
+
+#endif /* LONG64 */
+
+
+/* END */
diff --git a/src/base/ftcalc.h b/src/base/ftcalc.h
new file mode 100644
index 0000000..1bbe178
--- /dev/null
+++ b/src/base/ftcalc.h
@@ -0,0 +1,85 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftcalc.h                                                               */
+/*                                                                         */
+/*    Arithmetic computations (specification).                             */
+/*                                                                         */
+/*  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 FTCALC_H
+#define FTCALC_H
+
+#include <freetype.h>
+#include <ftconfig.h>   /* for LONG64 */
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+#ifdef LONG64
+
+  typedef INT64  FT_Int64;
+
+#define ADD_64( x, y, z )  z = (x) + (y)
+#define MUL_64( x, y, z )  z = (FT_Int64)(x) * (y)
+
+#define DIV_64( x, y )     ( (x) / (y) )
+
+#else /* LONG64 */
+
+  typedef struct  FT_Int64_
+  {
+    FT_Word32  lo;
+    FT_Word32  hi;
+
+  } FT_Int64;
+
+#define ADD_64( x, y, z )  FT_Add64( &x, &y, &z )
+#define MUL_64( x, y, z )  FT_MulTo64( x, y, &z )
+#define DIV_64( x, y )     FT_Div64by32( &x, y )
+
+  BASE_DEF void      FT_Add64    ( FT_Int64* x, FT_Int64* y, FT_Int64*  z );
+  BASE_DEF void      FT_MulTo64  ( FT_Int32  x, FT_Int32  y, FT_Int64*  z );
+  BASE_DEF FT_Int32  FT_Div64by32( FT_Int64* x, FT_Int32  y );
+
+#endif /* LONG64 */
+
+#define SQRT_32( x )       FT_Sqrt32( x )
+
+  BASE_DEF FT_Int32  FT_Sqrt32( FT_Int32  l );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_MulDiv() and FT_MulFix() are declared in freetype.h.               */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#define INT_TO_F26DOT6( x )    ( (FT_Long)(x) << 6  )
+#define INT_TO_F2DOT14( x )    ( (FT_Long)(x) << 14 )
+#define INT_TO_FIXED( x )      ( (FT_Long)(x) << 16 )
+#define F2DOT14_TO_FIXED( x )  ( (FT_Long)(x) << 2  )
+#define FLOAT_TO_FIXED( x )    ( (FT_Long)(x * 65536.0) )
+
+#define ROUND_F26DOT6( x )     ( x >= 0 ? (   ((x) + 32) & -64) \
+                                     : ( -((32 - (x)) & -64) ) )
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* FTCALC_H */
+
+
+/* END */
diff --git a/src/base/ftdebug.c b/src/base/ftdebug.c
new file mode 100644
index 0000000..168f9b7
--- /dev/null
+++ b/src/base/ftdebug.c
@@ -0,0 +1,93 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftdebug.c                                                              */
+/*                                                                         */
+/*    Debugging and logging component (body).                              */
+/*                                                                         */
+/*  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 <ftdebug.h>
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+  char  ft_trace_levels[trace_max];
+#endif
+
+
+#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE )
+
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The Print() function is defined in ftconfig.h.  It defaults to        */
+  /* vprintf() on systems which have it.                                   */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  void  FT_Message( const char*  fmt, ... )
+  {
+    va_list  ap;
+
+
+    va_start( ap, fmt );
+    vprintf( fmt, ap );
+    va_end( ap );
+  }
+
+
+  void  FT_Panic( const char*  fmt, ... )
+  {
+    va_list  ap;
+
+
+    va_start( ap, fmt );
+    vprintf( fmt, ap );
+    va_end( ap );
+
+    exit( EXIT_FAILURE );
+  }
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+  EXPORT_FUNC
+  void  FT_SetTraceLevel( FT_Trace  component,
+                          char      level )
+  {
+    if ( component >= trace_max )
+      return;
+
+    /* if component is `trace_any', then change _all_ levels at once */
+    if ( component == trace_any )
+    {
+      int  n;
+
+
+      for ( n = trace_any; n < trace_max; n++ )
+        ft_trace_levels[n] = level;
+    }
+    else        /* otherwise, only change individual component */
+      ft_trace_levels[component] = level;
+  }
+
+#endif /* FT_DEBUG_LEVEL_TRACE */
+
+#endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */
+
+
+/* END */
diff --git a/src/base/ftdebug.h b/src/base/ftdebug.h
new file mode 100644
index 0000000..c619f35
--- /dev/null
+++ b/src/base/ftdebug.h
@@ -0,0 +1,191 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftdebug.h                                                              */
+/*                                                                         */
+/*    Debugging and logging component (specification).                     */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This component contains various macros and functions used to ease the */
+  /* debugging of the FreeType engine.  Its main purpose is in assertion   */
+  /* checking, tracing, and error detection.                               */
+  /*                                                                       */
+  /* There are now three debugging modes:                                  */
+  /*                                                                       */
+  /* - trace mode                                                          */
+  /*                                                                       */
+  /*   Error and trace messages are sent to the log file (which can be the */
+  /*   standard error output).                                             */
+  /*                                                                       */
+  /* - error mode                                                          */
+  /*                                                                       */
+  /*   Only error messages are generated.                                  */
+  /*                                                                       */
+  /* - release mode:                                                       */
+  /*                                                                       */
+  /*   No error message is sent nor generated.  The code is free from any  */
+  /*   debugging parts.                                                    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef FTDEBUG_H
+#define FTDEBUG_H
+
+#include <ftconfig.h>   /* for FT_DEBUG_LEVEL_TRACE, FT_DEBUG_LEVEL_ERROR */
+
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+
+
+  typedef enum  FT_Trace_
+  {
+    trace_any = 0,
+
+    /* first, define an enum for each common component */
+    trace_io,        /* in ftsys */
+    trace_memory,    /* in ftsys */
+    trace_sync,      /* in ftsys */
+    trace_stream,    /* stream manager - see ftstream.c */
+    trace_calc,      /* computations   - see ftcalc.c   */
+    trace_raster,    /* raster         - see ftraster.c */
+    trace_list,      /* list manager   - see ftlist.c   */
+    trace_objs,      /* base objects   - see ftobjs.c   */
+
+    /* then define an enum for each TrueType driver component */
+    trace_ttobjs,
+    trace_ttload,
+    trace_ttgload,
+    trace_ttinterp,
+    trace_ttcmap,
+    trace_ttextend,
+    trace_ttdriver,
+
+    /* define an enum for each TrueDoc driver component */
+    trace_tdobjs,
+    trace_tdload,
+    trace_tdgload,
+    trace_tdhint,
+    trace_tddriver,
+
+    /* define an enum for each Type1 driver component */
+    trace_t1objs,
+    trace_t1load,
+    trace_t1gload,
+    trace_t1hint,
+    trace_t1driver,
+
+    /* other trace levels */
+	trace_init,
+
+    /* the last level must always be `trace_max' */
+    trace_max
+
+  } FT_Trace;
+
+  extern char  ft_trace_levels[trace_max];
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* IMPORTANT!                                                            */
+  /*                                                                       */
+  /* Each component must define the macro FT_COMPONENT to a valid          */
+  /* Trace_Component value before using any TRACE macro.                   */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#define FT_TRACE( level, varformat )                       \
+          if ( ft_trace_levels[FT_COMPONENT] >= level )  \
+            FT_Message##varformat
+
+
+  EXPORT_DEF
+  void  FT_SetTraceLevel( FT_Trace  component,
+                          char      level );
+
+
+#elif defined( FT_DEBUG_LEVEL_ERROR )
+
+
+#define FT_TRACE( level, varformat )  /* nothing */
+
+
+#else  /* release mode */
+
+
+#define FT_Assert( condition )  /* nothing */
+
+#define FT_TRACE( level, varformat )      /* nothing */
+#define FT_ERROR( varformat )             /* nothing */
+
+
+#endif /* FT_DEBUG_LEVEL_TRACE, FT_DEBUG_LEVEL_ERROR */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define macros and functions that are common to the debug and trace    */
+  /* modes.                                                                */
+  /*                                                                       */
+  /* You need vprintf() to be able to compile ttdebug.c.                   */
+  /*                                                                       */
+  /*************************************************************************/
+
+#if defined( FT_DEBUG_LEVEL_TRACE ) || defined( FT_DEBUG_LEVEL_ERROR )
+
+
+#include "stdio.h"  /* for vprintf() */
+
+#define FT_Assert( condition )  \
+       if ( !(condition) )      \
+         FT_Panic( "assertion failed on line %d of file %s\n", __LINE__, __FILE__ );
+
+  extern void  FT_Message( const char*  fmt, ... );
+
+  /* print a message and exit */
+  extern void  FT_Panic  ( const char*  fmt, ... );
+
+#define FT_ERROR( varformat )  FT_Message##varformat
+
+
+#endif /* FT_DEBUG_LEVEL_TRACE || FT_DEBUG_LEVEL_ERROR */
+
+
+#define FT_TRACE0( varformat )  FT_TRACE( 0, varformat )
+#define FT_TRACE1( varformat )  FT_TRACE( 1, varformat )
+#define FT_TRACE2( varformat )  FT_TRACE( 2, varformat )
+#define FT_TRACE3( varformat )  FT_TRACE( 3, varformat )
+#define FT_TRACE4( varformat )  FT_TRACE( 4, varformat )
+#define FT_TRACE5( varformat )  FT_TRACE( 5, varformat )
+#define FT_TRACE6( varformat )  FT_TRACE( 6, varformat )
+#define FT_TRACE7( varformat )  FT_TRACE( 7, varformat )
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif /* FTDEBUG_H */
+
+
+/* END */
diff --git a/src/base/ftdriver.h b/src/base/ftdriver.h
new file mode 100644
index 0000000..04cf748
--- /dev/null
+++ b/src/base/ftdriver.h
@@ -0,0 +1,641 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftdriver.h                                                             */
+/*                                                                         */
+/*  FreeType driver interface (specification).                             */
+/*                                                                         */
+/*  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 FTDRIVER_H
+#define FTDRIVER_H
+
+#include <freetype.h>
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                         D R I V E R S                           ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_initDriver                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to create a new driver object for a given     */
+  /*    format.                                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver :: A handle to the `new' driver object.  The fields         */
+  /*              `library', `system', and `lock' are already set when the */
+  /*              base layer calls this method.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef FT_Error  (*FTDriver_initDriver)( FT_Driver  driver );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_doneEngine                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to finalize a given driver object.  Note that */
+  /*    all faces and resources for this driver have been released before  */
+  /*    this call, and that this function should NOT destroy the driver    */
+  /*    object.                                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver :: A handle to target driver object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef FT_Error  (*FTDriver_doneDriver)( FT_Driver  driver );
+
+
+  
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_getInterface                                              */
+  /*                                                                       */
+  /* <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).                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver    :: A handle to a driver object.                          */
+  /*    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 when the requested extension  */
+  /*    isn't available (i.e., wasn't compiled in the driver at build      */
+  /*    time).                                                             */
+  /*                                                                       */
+  typedef void*  (*FTDriver_getInterface)( FT_Driver         driver,
+                                           const FT_String*  interface );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FTDriver_formatInterface                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver interface field whose value is a driver-specific          */
+  /*    interface method tables.  This table contains entry points to      */
+  /*    various functions that are strictly related to the driver's        */
+  /*    format.                                                            */
+  /*                                                                       */
+  typedef void*  FT_FormatInterface;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                           F A C E S                             ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_initFace                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to initialize a new face object.  The object  */
+  /*    must be created by the caller.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver         :: A handle to the source driver object.            */
+  /*    resource       :: A handle to the source resource.                 */
+  /*    typeface_index :: The index of face in the font resource.  Used to */
+  /*                      access individual faces in collections.          */
+  /*                                                                       */
+  /*    face           :: A handle to the new target face.                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The `typeface_index' parameter field will be set to -1 when the    */
+  /*    engine only wants to test the format of the resource.  This means  */
+  /*    that font drivers should simply check the font format, then return */
+  /*    immediately with an error code of 0 (meaning success).  The field  */
+  /*    `num_faces' should be set.                                         */
+  /*                                                                       */
+  /*    done_face() will be called subsequently, whatever the result was.  */
+  /*                                                                       */
+  typedef FT_Error  (*FTDriver_initFace)( FT_Stream    stream,
+                                          FT_Long      typeface_index,
+                                          FT_Face      face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_doneFace                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to finalize a given face object.  This        */
+  /*    function does NOT destroy the object, that is the responsibility   */
+  /*    of the caller.                                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target face object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef void  (*FTDriver_doneFace)( FT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_getKerning                                                */
+  /*                                                                       */
+  /* <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 method.  Other layouts, or more sophisticated    */
+  /*    kernings are out of the scope of this method (the basic driver     */
+  /*    interface is meant to be simple).                                  */
+  /*                                                                       */
+  /*    They can be implemented through format-specific interfaces.        */
+  /*                                                                       */
+  typedef FT_Error  (*FTDriver_getKerning)( FT_Face      face,
+                                            FT_UInt      left_glyph,
+                                            FT_UInt      right_glyph,
+                                            FT_Vector*   kerning );
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                            S I Z E S                            ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_initSize                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to initialize a new size object.  The object  */
+  /*    must be created by the caller.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the parent face object.                        */
+  /*    size :: A handle to the new size object.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function should return an error if the face's format isn't    */
+  /*    scalable.                                                          */
+  /*                                                                       */
+  typedef FT_Error  (*FTDriver_initSize)( FT_Size  size );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_setCharSizes                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to reset a size's character sizes (horizontal */
+  /*    and vertical) expressed in fractional points.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size        :: A handle to the target size object.                 */
+  /*    char_width  :: The character width expressed in 26.6 fractional    */
+  /*                   points.                                             */
+  /*    char_height :: The character height expressed in 26.6 fractional   */
+  /*                   points.                                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function should always FAIL if the face format isn't          */
+  /*    scalable!                                                          */
+  /*                                                                       */
+  typedef FT_Error  (*FTDriver_setCharSizes)( FT_Size     size,
+                                              FT_F26Dot6  char_width,
+                                              FT_F26Dot6  char_height,
+                                              FT_UInt     horz_resolution,
+                                              FT_UInt     vert_resolution );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_setPixelSizes                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to reset a size's character sizes (horizontal */
+  /*    and vertical) expressed in integer pixels.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size         :: A handle to the target size object.                */
+  /*                                                                       */
+  /*    pixel_width  :: The character width expressed in 26.6 fractional   */
+  /*                    pixels.                                            */
+  /*                                                                       */
+  /*    pixel_height :: The character height expressed in 26.6 fractional  */
+  /*                    pixels.                                            */
+  /*                                                                       */
+  /*    point_size   :: The corresponding character size in points.  This  */
+  /*                    value is only sent to the TrueType bytecode        */
+  /*                    interpreter, even though 99% of glyph programs     */
+  /*                    will simply ignore it.  A safe value there is the  */
+  /*                    maximum of the pixel width and height (multiplied  */
+  /*                    by 64 to make it a 26.6 fixed float).              */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function should work with all kinds of `Size' objects, either */
+  /*    fixed or scalable ones.  The `point_size' parameter will simply be */
+  /*    ignored in case of fixed formats.                                  */
+  /*                                                                       */
+  typedef FT_Error  (*FTDriver_setPixelSizes)( FT_Size  size,
+                                               FT_UInt  pixel_width,
+                                               FT_UInt  pixel_height );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_doneSize                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to finalize a given size object.  This method */
+  /*    does NOT destroy the object; this is the responsibility of the     */
+  /*    caller.                                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size :: A handle to the target size object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef void  (*FTDriver_doneSize)( FT_Size  size );
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                       G L Y P H   S L O T S                     ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_initGlyphSlot                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to initialize a new glyph slot object.  The   */
+  /*    object must be created by the caller.  The glyph slot is a         */
+  /*    container where a single glyph can be loaded, either in outline or */
+  /*    bitmap format.                                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the parent face object.                        */
+  /*    slot :: A handle to the new glyph slot object.                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef FT_Error  (*FTDriver_initGlyphSlot)( FT_GlyphSlot  slot );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_doneGlyphSlot                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to finalize a given glyph slot.  The object   */
+  /*    is not destroyed by this function.                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the parent face object.                        */
+  /*    slot :: A handle to the new glyph slot object.                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef void  (*FTDriver_doneGlyphSlot)( FT_GlyphSlot  slot );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_loadGlyph                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to load a glyph within a given glyph slot.    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    slot        :: A handle to target slot object where the glyph will */
+  /*                   be loaded.                                          */
+  /*                                                                       */
+  /*    size        :: A handle to the source face size at which the glyph */
+  /*                   must be scaled/loaded.                              */
+  /*                                                                       */
+  /*    glyph_index :: The index of the glyph in the font file.            */
+  /*                                                                       */
+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
+  /*                   FTLOAD_??? constants can be used to control the     */
+  /*                   glyph loading process (e.g., whether the outline    */
+  /*                   should be scaled, whether to load bitmaps or not,   */
+  /*                   whether to hint the outline, etc).                  */
+  /* <Output>                                                              */
+  /*    result      :: A set of bit flags indicating the type of data that */
+  /*                   was loaded in the glyph slot (outline, bitmap,      */
+  /*                   pixmap, etc).                                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef FT_Error  (*FTDriver_loadGlyph)( FT_GlyphSlot  slot,
+                                           FT_Size       size,
+                                           FT_UInt       glyph_index,
+                                           FT_Int        load_flags );
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                  C H A R A C T E R   M A P S                    ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FTDriver_getCharIndex                                              */
+  /*                                                                       */
+  /* <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>                                                              */
+  /*    The glyph index.  0 means `undefined character code'.              */
+  /*                                                                       */
+  typedef FT_UInt  (*FTDriver_getCharIndex)( FT_CharMap  charmap,
+                                             FT_Long     charcode );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_DriverInterface                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure which holds a font driver's basic interface used by    */
+  /*    the high-level parts of FreeType (or other applications).          */
+  /*                                                                       */
+  /*    Most scalable drivers provide a specialized interface to access    */
+  /*    format specific features.  It can be retrieved with a call to      */
+  /*    `get_format_interface()', and should be defined in each font       */
+  /*    driver header (e.g., ttdriver.h, t1driver.h, etc).                 */
+  /*                                                                       */
+  /*    All fields are function pointers.                                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    driver_object_size   :: The size in bytes of a single driver       */
+  /*                            object.                                    */
+  /*                                                                       */
+  /*    face_object_size     :: The size in bytes of a single face object. */
+  /*                                                                       */
+  /*    size_object_size     :: The size in bytes of a single size object. */
+  /*                                                                       */
+  /*    slot_object_size     :: The size in bytes of a single glyph slot   */
+  /*                            object.                                    */
+  /*                                                                       */
+  /*    driver_name          :: a string to describe the driver to the     */
+  /*                            system. It doesn't necessarily describe    */
+  /*                            in detail all the font formats the driver  */
+  /*                            may support.                               */
+  /*                                                                       */
+  /*    driver_version       :: driver version number. starts at 1         */
+  /*                                                                       */
+  /*    driver_requires      :: the FreeType major version this driver is  */
+  /*                            written for. This number should be equal   */
+  /*                            to or greater than 2 !                     */
+  /*                                                                       */
+  /*    format_interface     :: A pointer to the driver's format-specific  */
+  /*                            interface.                                 */
+  /*                                                                       */
+  /*    init_driver          :: Used to initialize a given driver object.  */
+  /*                                                                       */
+  /*    done_driver          :: Used to finalize and destroy a given       */
+  /*                            driver object.                             */
+  /*                                                                       */
+  /*    get_extension        :: Returns an interface for a given driver    */
+  /*                            extension.                                 */
+  /*                                                                       */
+  /*    init_face            :: Initializes a given face object.           */
+  /*                                                                       */
+  /*    done_face            :: Discards a face object, as well as all     */
+  /*                            child objects (sizes, charmaps, glyph      */
+  /*                            slots).                                    */
+  /*                                                                       */
+  /*    get_kerning          :: Returns the kerning vector corresponding   */
+  /*                            to a pair of glyphs, expressed in unscaled */
+  /*                            font units.                                */
+  /*                                                                       */
+  /*    init_size            :: Initializes a given size object.           */
+  /*                                                                       */
+  /*    done_size            :: Finalizes a given size object.             */
+  /*                                                                       */
+  /*    set_size_char_sizes  :: Resets a scalable size object's character  */
+  /*                            size.                                      */
+  /*                                                                       */
+  /*    set_pixel_sizes      :: Resets a face size object's pixel          */
+  /*                            dimensions.  Applies to both scalable and  */
+  /*                            fixed faces.                               */
+  /*                                                                       */
+  /*    init_glyph_slot      :: Initializes a given glyph slot object.     */
+  /*                                                                       */
+  /*    done_glyph_slot      :: Finalizes a given glyph slot.              */
+  /*                                                                       */
+  /*    load_glyph           :: Loads a given glyph into a given slot.     */
+  /*                                                                       */
+  typedef struct  FT_DriverInterface_
+  {
+    FT_Int                       driver_object_size;
+    FT_Int                       face_object_size;
+    FT_Int                       size_object_size;
+    FT_Int                       slot_object_size;
+
+    FT_String*                   driver_name;
+    FT_Int                       driver_version;
+    FT_Int                       driver_requires;
+
+    void*                        format_interface;
+
+    FTDriver_initDriver          init_driver;
+    FTDriver_doneDriver          done_driver;
+    FTDriver_getInterface        get_interface;
+
+    FTDriver_initFace            init_face;
+    FTDriver_doneFace            done_face;
+    FTDriver_getKerning          get_kerning;
+
+    FTDriver_initSize            init_size;
+    FTDriver_doneSize            done_size;
+    FTDriver_setCharSizes        set_char_sizes;
+    FTDriver_setPixelSizes       set_pixel_sizes;
+
+    FTDriver_initGlyphSlot       init_glyph_slot;
+    FTDriver_doneGlyphSlot       done_glyph_slot;
+    FTDriver_loadGlyph           load_glyph;
+
+    FTDriver_getCharIndex        get_char_index;
+
+  } FT_DriverInterface;
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_DriverChain                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A very structure used exclusively by "ftinit.c" in the function    */
+  /*    FT_Add_Default_Drivers. This function is in charge of loading the  */
+  /*    set of "default" font drivers into each new library object.        */
+  /*                                                                       */
+  /*    The set itself is determined at _compile_ time through various     */
+  /*    macro definitions.                                                 */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    next      :: pointer to next element in driver list chain          */
+  /*    interface :: pointer to the driver's interface                     */
+  /*                                                                       */
+  typedef struct FT_DriverChain_  FT_DriverChain;
+
+  struct FT_DriverChain_
+  {
+    const FT_DriverChain*      next;
+    const FT_DriverInterface*  interface;
+  };
+
+
+/*************************************************************************
+ *
+ *  Here is a template of the code that should appear in each
+ *  font driver's _interface_ file (the one included by "ftinit.c").
+ *
+ *  It is used to build, at compile time, a simple linked list of
+ *  the interfaces of the drivers which have been #included in 
+ *  "ftinit.c". See the source code of the latter file for details
+ *
+ *  (Note that this is only required when you want your driver included
+ *   in the set of default drivers loaded by FT_Init_FreeType. Other
+ *   drivers can still be added manually at runtime with FT_Add_Driver.
+ *
+ * {
+ *   #ifdef FTINIT_DRIVER_CHAIN
+ *
+ *   static
+ *   const FT_DriverChain  ftinit_<FORMAT>_driver_chain =
+ *   {
+ *     FT_INIT_LAST_DRIVER_CHAIN,
+ *     &<FORMAT>_driver_interface
+ *   };
+ * 
+ *   #undef  FT_INIT_LAST_DRIVER_CHAIN
+ *   #define FT_INIT_LAST_DRIVER_CHAIN   &ftinit_<FORMAT>_driver_chain
+ *
+ *   #endif 
+ * }
+ *
+ *  replace <FORMAT> with your driver's prefix
+ *
+ *************************************************************************/
+
+
+#endif /* FTDRIVER_H */
+
+
+/* END */
diff --git a/src/base/ftextend.c b/src/base/ftextend.c
new file mode 100644
index 0000000..415d38b
--- /dev/null
+++ b/src/base/ftextend.c
@@ -0,0 +1,199 @@
+/*******************************************************************
+ *
+ *  ftextend.h                                                   2.0
+ *
+ *    Extensions Implementation
+ *
+ *  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.
+ *
+ *  This is an updated version of the extension component, now
+ *  located in the main library's source directory.  It allows
+ *  the dynamic registration/use of various face object extensions
+ *  through a simple API.
+ *
+ ******************************************************************/
+
+#include "ftextend.h"
+#include "ftobjs.h"
+
+/* required by the tracing mode */
+#undef  FT_COMPONENT
+#define FT_COMPONENT      trace_extend
+
+
+  typedef struct FT_Extension_Registry_
+  {
+    FT_Int              num_extensions;
+    FT_Long             cur_offset;
+    FT_Extension_Class  classes[FT_MAX_EXTENSIONS];
+    
+  } FT_Extension_Registry;
+
+
+  /* Initialize the extension component */
+
+  LOCAL_FUNC
+  FT_Error  FT_Init_Extensions( FT_Driver  driver )
+  {
+  FT_Error                error;
+    FT_Memory               memory;
+    FT_Extension_Registry*  registry;
+
+    memory = driver->library->memory;
+    if ( ALLOC( registry, sizeof (*registry) ) )
+      return error;
+
+    registry->num_extensions = 0;
+    registry->cur_offset     = 0;
+    driver->extensions       = registry;
+
+    return FT_Err_Ok;
+  }
+
+
+  /* Finalize the extension component */
+
+  LOCAL_FUNC
+  FT_Error  FT_Done_Extensions( FT_Driver  driver )
+  {
+    FT_Memory  memory = driver->memory;
+    
+    FREE( driver->extensions );
+    return FT_Err_Ok;
+  }
+
+
+  /* Register a new extension */
+
+  EXPORT_FUNC
+  FT_Error  FT_Register_Extension( FT_Driver            driver,
+                                   FT_Extension_Class*  clazz )
+  {
+    FT_Extension_Registry*  registry;
+
+    registry = (FT_Extension_Registry*)driver->extensions;
+    if (registry)
+    {
+      FT_Int               n   = registry->num_extensions;
+      FT_Extension_Class*  cur = registry->classes + n;
+      
+      if ( n >= FT_MAX_EXTENSIONS )
+        return FT_Err_Too_Many_Extensions;
+
+      *cur = *clazz;    
+
+      cur->offset  = registry->cur_offset;
+
+      registry->num_extensions++;
+      registry->cur_offset += ( cur->size + FT_ALIGNMENT-1 ) & -FT_ALIGNMENT;
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+  /* Query an extension block by extension_ID */
+
+  EXPORT_FUNC
+  void*  FT_Get_Extension( FT_Face      face,
+                           const char*  extension_id,
+                           void*       *extension_interface ) 
+  {
+    FT_Extension_Registry*  registry;
+    
+    registry = (FT_Extension_Registry*)face->driver->extensions;
+    if (registry && face->extensions)
+    {
+      FT_Extension_Class*  cur   = registry->classes;
+      FT_Extension_Class*  limit = cur + registry->num_extensions;
+      
+      for ( ; cur < limit; cur++ )
+        if ( strcmp( cur->id, extension_id ) == 0 )
+        {
+          *extension_interface = cur->interface;
+          return (void*)((char*)face->extensions + cur->offset);
+        }
+    }
+    
+    /* could not find the extension id */
+    *extension_interface = 0;
+    return 0;
+  }
+
+  /* Destroy all extensions within a face object.  Called by the */
+  /* face object destructor.                                     */
+
+  LOCAL_FUNC
+  FT_Error  FT_Destroy_Extensions( FT_Face  face )
+  {
+    FT_Extension_Registry*  registry;
+    FT_Memory               memory;
+    
+    registry = (FT_Extension_Registry*)face->driver->extensions;
+    if (registry && face->extensions)
+    {
+      FT_Extension_Class*  cur   = registry->classes;
+      FT_Extension_Class*  limit = cur + registry->num_extensions;
+      
+      for ( ; cur < limit; cur++ )
+      {
+        char*  ext = (char*)face->extensions + cur->offset;
+        
+        if (cur->finalize)
+          cur->finalize( ext, face );
+      }
+      
+      memory = face->driver->memory;
+      FREE( face->extensions );
+    }
+    return FT_Err_Ok;
+  }
+
+
+  /* Create an extension within a face object.  Called by the */
+  /* face object constructor.                                 */
+
+  LOCAL_FUNC
+  FT_Error  FT_Create_Extensions( FT_Face  face )
+  {
+    FT_Extension_Registry*  registry;
+    FT_Memory               memory;
+    FT_Error                error;
+    
+    face->extensions = 0;
+    
+    /* load extensions registry, exit succesfully if none is there */
+    registry = (FT_Extension_Registry*)face->driver->extensions;
+    if (!registry) return FT_Err_Ok;
+    
+    memory = face->driver->memory;
+    if ( ALLOC( face->extensions, registry->cur_offset ) )
+      return error;
+      
+    {
+      FT_Extension_Class*  cur   = registry->classes;
+      FT_Extension_Class*  limit = cur + registry->num_extensions;
+      
+      for ( ; cur < limit; cur++ )
+      {
+        char*  ext = (char*)face->extensions + cur->offset;
+        
+        if (cur->init)
+        {
+          error = cur->init( ext, face );
+          if (error) break;
+        }
+      }
+    }
+    return error;
+  }
+
+
+/* END */
diff --git a/src/base/ftextend.h b/src/base/ftextend.h
new file mode 100644
index 0000000..4433a3b
--- /dev/null
+++ b/src/base/ftextend.h
@@ -0,0 +1,166 @@
+/*******************************************************************
+ *
+ *  ftextend.h                                                   2.0
+ *
+ *    Extensions Interface.
+ *
+ *  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 FTEXTEND_H
+#define FTEXTEND_H
+
+#include "ftconfig.h"
+#include "ftobjs.h"
+
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+  /* The extensions don't need to be integrated at compile time into */
+  /* the engine, only at link time.                                  */
+
+
+ /*****************************************************************
+  *
+  * <FuncType>
+  *   FT_Extension_Initializer
+  *
+  * <Description>
+  *   Each new face object can have several extensions associated
+  *   to it at creation time. This function is used to initialize
+  *   a given extension data for a given face.
+  *
+  * <Input>
+  *   ext   :: a typeless pointer to the extension data.
+  *   face  :: handle to the source face object the extension is
+  *            associated with
+  *
+  * <Return>
+  *   Error condition. 0 means success
+  *
+  * <Note>
+  *   In case of error, the initializer should not destroy the
+  *   extension data, as the finalizer will get called later
+  *   by the function's caller..
+  *
+  *****************************************************************/
+
+  typedef FT_Error (*FT_Extension_Initializer)( void*    ext, 
+                                                FT_Face  face );
+
+ /*****************************************************************
+  *
+  * <FuncType>
+  *   FT_Extension_Finalizer
+  *
+  * <Description>
+  *   Each new face object can have several extensions associated
+  *   to it at creation time. This function is used to finalize
+  *   a given extension data for a given face. This occurs before
+  *   the face object itself is finalized.
+  *
+  * <Input>
+  *   ext   :: a typeless pointer to the extension data.
+  *   face  :: handle to the source face object the extension is
+  *            associated with
+  *
+  *****************************************************************/
+
+  typedef void  (*FT_Extension_Finalizer)( void*  ext, FT_Face  face );
+
+
+ /*****************************************************************
+  *
+  * <Struct>
+  *   FT_Extension_Class
+  *
+  * <Description>
+  *   A simple structure used to describe a given extension to
+  *   the FreeType base layer. An FT_Extension_Class is used as
+  *   a parameter for FT_Register_Extension.
+  *
+  * <Fields>
+  *   id        :: the extension's id. This is a normal C string
+  *                that is used to uniquely reference the extension's
+  *                interface.
+  *
+  *   size      :: the size in bytes of the extension data that must
+  *                be associated with each face object.
+  *
+  *   init      :: a pointer to the extension data's initializer
+  *   finalize  :: a pointer to the extension data's finalizer
+  *
+  *   inteface  :: this pointer can be anything, but should usually
+  *                point to a table of function pointers which implement
+  *                the extension's interface.
+  *
+  *   offset    :: this field is set and used within the base layer
+  *                and should be set to 0 when registering an
+  *                extension through FT_Register_Extension. It contains
+  *                an offset within the face's extension block for the
+  *                current extension's data.
+  *
+  *****************************************************************/
+
+  typedef struct FT_Extension_Class_
+  {
+    const char*               id;
+    FT_ULong                  size;
+    FT_Extension_Initializer  init;
+    FT_Extension_Finalizer    finalize;
+    void*                     interface;
+    
+    FT_ULong                  offset;
+    
+  } FT_Extension_Class;
+  
+
+  EXPORT_DEF
+  FT_Error  FT_Register_Extension( FT_Driver            driver,
+                                   FT_Extension_Class*  clazz );
+
+
+#ifdef FT_CONFIG_OPTION_EXTEND_ENGINE
+  /* Initialize the extension component */
+  LOCAL_DEF
+  FT_Error  FT_Init_Extensions( FT_Library  library );
+
+  /* Finalize the extension component */
+  LOCAL_DEF
+  FT_Error  FT_Done_Extensions( FT_Library  library );
+
+  /* Create an extension within a face object.  Called by the */
+  /* face object constructor.                                 */
+  LOCAL_DEF
+  FT_Error  FT_Create_Extensions( FT_Face  face );
+
+  /* Destroy all extensions within a face object.  Called by the */
+  /* face object destructor.                                     */
+  LOCAL_DEF
+  FT_Error  FT_Destroy_Extensions( FT_Face  face );
+#endif
+
+  /* Returns an extension's data & inteface according to its ID */
+  EXPORT_DEF
+  void*     FT_Get_Extension( FT_Face      face,
+                              const char*  extension_id,
+                              void*       *extension_interface );
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif /* FTEXTEND_H */
+
+
+/* END */
diff --git a/src/base/ftinit.c b/src/base/ftinit.c
new file mode 100644
index 0000000..ca754ae
--- /dev/null
+++ b/src/base/ftinit.c
@@ -0,0 +1,169 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftinit.c                                                               */
+/*                                                                         */
+/*    FreeType initialisation layer (body).                                */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+ /**************************************************************************
+  *
+  *  The purpose of this file is to implement the three following
+  *  functions:
+  *
+  *	 FT_Default_Drivers:
+  *		This function is used to add the set of default drivers
+  *		to a fresh new library object. The set is computed at compile
+  *		time from the Makefiles inclusions in Makefile.lib. See the
+  *		document "FreeType Internals" for more info.
+  *
+  *
+  *	 FT_Init_FreeType:
+  *		This function creates a system object for the current platform,
+  *		builds a library out of it, then calls FT_Default_Drivers
+  *
+  *
+  *	 FT_Done_FreeType:
+  *		This function simply finalise the library and the corresponding
+  *		system object.
+  *
+  *
+  *	 Note that even if FT_Init_FreeType uses the implementation of the
+  *	 system object defined at build time, client applications are still
+  *	 able to provide their own "ftsystem.c"
+  *
+  *
+  *
+  *
+  *
+  ************************************************************************/
+
+#include <ftobjs.h>
+#include <ftdriver.h>
+#include <ftconfig.h>
+#include <ftdebug.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_init
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macros FT_SUPPORT_xxxx are defined by Makefile.lib when this file */
+  /* is compiled.  They come from a make variable called FTINIT_MACROS     */
+  /* which is updated by each driver Makefile.                             */
+  /*                                                                       */
+  /* This means that when a driver isn't part of the build, ftinit.o       */
+  /* won't try to reference it.                                            */
+  /*                                                                       */
+  /*************************************************************************/
+
+#define  FTINIT_DRIVER_CHAIN
+#define  FT_INIT_LAST_DRIVER_CHAIN    ((FT_DriverChain*) 0)
+
+  /* Include the SFNT driver interface if needed */
+
+#ifdef FT_SUPPORT_SFNT
+#include "sfdriver.h"
+#endif
+
+  /* Include the TrueType driver interface if needed */
+
+#ifdef FT_SUPPORT_TRUETYPE
+#include "ttdriver.h"
+#endif
+
+
+  /* Include the Type1 driver interface if needed */
+
+#ifdef FT_SUPPORT_TYPE1
+#include "t1driver.h"
+#endif
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Default_Drivers                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Adds the set of default drivers to a given library object.         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to a new library object.                       */
+  /*                                                                       */
+  EXPORT_FUNC
+  void  FT_Default_Drivers( FT_Library  library )
+  {
+    FT_Error               error;
+    const FT_DriverChain*  chain = FT_INIT_LAST_DRIVER_CHAIN;
+
+    while (chain)
+    {
+      error = FT_Add_Driver( library, chain->interface );
+
+      /* notify errors, but don't stop */
+      if (error)
+      {
+        FT_ERROR(( "FT.Default_Drivers: cannot install `%s', error = %x\n",
+                   chain->interface->driver_name,
+                   error ));
+      }
+
+      chain = chain->next;
+      error = 0;  /* clear error */
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Init_FreeType                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a new FreeType library object.  The set of drivers     */
+  /*    that are registered by this function is determined at build time.  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    library :: A handle to a new library object.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Init_FreeType( FT_Library*  library )
+  {
+    FT_Error   error;
+    FT_Memory  memory;
+
+    /* First of all, allocate a new system object -this function is part */
+    /* of the system-specific component, i.e. ftsystem.c                 */
+    memory = FT_New_Memory();
+    if (!memory)
+    {
+      FT_ERROR(( "FT_Init_FreeType:" ));
+      FT_ERROR(( " cannot find memory manager" ));
+      return FT_Err_Unimplemented_Feature;
+    }
+    
+    /* builds a library out of it, then fill it with the set of */
+    /* default drivers..										*/
+    error = FT_New_Library( memory, library );
+    if ( !error )
+      FT_Default_Drivers(*library);
+    
+    return error;
+  }
+
+
+/* END */
diff --git a/src/base/ftlist.c b/src/base/ftlist.c
new file mode 100644
index 0000000..fd2241f
--- /dev/null
+++ b/src/base/ftlist.c
@@ -0,0 +1,300 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftlist.c                                                               */
+/*                                                                         */
+/*    Generic list support for FreeType (body).                            */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  This file implements functions relative to list processing.  Its     */
+  /*  data structures are defined in freetype.h.                           */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include <ftlist.h>
+#include <ftdebug.h>
+#include <ftobjs.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Find                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finds the list node for a given listed object.                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list :: A pointer to the parent list.                              */
+  /*    data :: The address of the listed object.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    List node.  NULL if it wasn't found.                               */
+  /*                                                                       */
+  BASE_FUNC
+  FT_ListNode  FT_List_Find( FT_List  list,
+                             void*    data )
+  {
+    FT_ListNode  cur;
+
+
+    cur = list->head;
+    while ( cur )
+    {
+      if (cur->data == data)
+        return cur;
+
+      cur = cur->next;
+    }
+
+    return (FT_ListNode)0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Add                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Appends an element at the end of a list.                           */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    list :: A pointer to the parent list.                              */
+  /*    node :: The node to append.                                        */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_List_Add( FT_List      list,
+                     FT_ListNode  node )
+  {
+    FT_ListNode  before = list->tail;
+
+
+    node->next = 0;
+    node->prev = before;
+
+    if ( before )
+      before->next = node;
+    else
+      list->head = node;
+
+    list->tail = node;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Insert                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Inserts an element at the head of a list.                          */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    list :: A pointer to parent list.                                  */
+  /*    node :: The node to insert.                                        */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_List_Insert( FT_List      list,
+                        FT_ListNode  node )
+  {
+    FT_ListNode  after = list->head;
+
+
+    node->next = after;
+    node->prev = 0;
+
+    if ( !after )
+      list->tail = node;
+    else
+      after->prev = node;
+
+    list->head = node;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Remove                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Removes a node from a list.  This function doesn't check whether   */
+  /*    the node is in the list!                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    node :: The node to remove.                                        */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    list :: A pointer to the parent list.                              */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_List_Remove( FT_List      list,
+                        FT_ListNode  node )
+  {
+    FT_ListNode  before, after;
+
+
+    before = node->prev;
+    after  = node->next;
+
+    if ( before )
+      before->next = after;
+    else
+      list->head = after;
+
+    if ( after )
+      after->prev = before;
+    else
+      list->tail = before;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Up                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Moves a node to the head/top of a list.  Used to maintain LRU      */
+  /*    lists.                                                             */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    list :: A pointer to the parent list.                              */
+  /*    node :: The node to move.                                          */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_List_Up( FT_List      list,
+                    FT_ListNode  node )
+  {
+    FT_ListNode  before, after;
+
+
+    before = node->prev;
+    after  = node->next;
+
+    /* check wether we're already on top of the list */
+    if ( !before )
+      return;
+
+    before->next = after;
+
+    if ( after )
+      after->prev = before;
+    else
+      list->tail = before;
+
+    node->prev       = 0;
+    node->next       = list->head;
+    list->head->prev = node;
+    list->head       = node;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Iterate                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Parses a list and calls a given iterator function on each element. */
+  /*    Note that parsing is stopped as soon as one of the iterator calls  */
+  /*    returns a non-zero value.                                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list     :: A handle to the list.                                  */
+  /*    iterator :: An interator function, called on each node of the      */
+  /*                list.                                                  */
+  /*    user     :: A user-supplied field which is passed as the second    */
+  /*                argument to the iterator.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of the last iterator call.                              */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_List_Iterate( FT_List            list,
+                             FT_List_Iterator   iterator,
+                             void*              user )
+  {
+    FT_ListNode  cur   = list->head;
+    FT_Error     error = FT_Err_Ok;
+
+
+    while ( cur )
+    {
+      FT_ListNode  next = cur->next;
+
+
+      error = iterator( cur, user );
+      if ( error )
+        break;
+
+      cur = next;
+    }
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Finalize                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys all elements in the list as well as the list itself.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list    :: A handle to the list.                                   */
+  /*                                                                       */
+  /*    destroy :: A list destructor that will be applied to each element  */
+  /*               of the list.                                            */
+  /*                                                                       */
+  /*    memory  :: The current memory object where destructions take       */
+  /*               place.                                                  */
+  /*                                                                       */
+  /*    user    :: A user-supplied field which is passed as the last       */
+  /*               argument to the destructor.                             */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_List_Finalize( FT_List            list,
+                          FT_List_Destructor destroy,
+                          FT_Memory          memory,
+                          void*              user )
+  {
+    FT_ListNode  cur;
+
+
+    cur = list->head;
+    while ( cur )
+    {
+      FT_ListNode  next = cur->next;
+      void*        data = cur->data;
+
+
+      if ( destroy )
+        destroy( memory, data, user );
+
+      FREE( cur );
+      cur = next;
+    }
+
+    list->head = 0;
+    list->tail = 0;
+  }
+
+
+/* END */
diff --git a/src/base/ftlist.h b/src/base/ftlist.h
new file mode 100644
index 0000000..2319326
--- /dev/null
+++ b/src/base/ftlist.h
@@ -0,0 +1,228 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftlist.c                                                               */
+/*                                                                         */
+/*    Generic list support for FreeType (specification).                   */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  This file implements functions relative to list processing.  Its     */
+  /*  data structures are defined in freetype.h.                           */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef FTLIST_H
+#define FTLIST_H
+
+#include <freetype.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Find                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finds the list node for a given listed object.                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list :: A pointer to the parent list.                              */
+  /*    data :: The address of the listed object.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    List node.  NULL if it wasn't found.                               */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_ListNode  FT_List_Find( FT_List  list,
+                             void*    data );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Add                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Appends an element at the end of a list.                           */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    list :: A pointer to the parent list.                              */
+  /*    node :: The node to append.                                        */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_List_Add( FT_List      list,
+                     FT_ListNode  node );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Insert                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Inserts an element at the head of a list.                          */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    list :: A pointer to parent list.                                  */
+  /*    node :: The node to insert.                                        */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_List_Insert( FT_List      list,
+                        FT_ListNode  node );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Remove                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Removes a node from a list.  This function doesn't check whether   */
+  /*    the node is in the list!                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    node :: The node to remove.                                        */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    list :: A pointer to the parent list.                              */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_List_Remove( FT_List      list,
+                        FT_ListNode  node );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Up                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Moves a node to the head/top of a list.  Used to maintain LRU      */
+  /*    lists.                                                             */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    list :: A pointer to the parent list.                              */
+  /*    node :: The node to move.                                          */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_List_Up( FT_List      list,
+                    FT_ListNode  node );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_List_Iterator                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An FT_List iterator function which is called during a list parse   */
+  /*    by FT_List_Iterate().                                              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    node :: The current iteration list node.                           */
+  /*    user :: A typeless pointer passed to FT_List_Iterate().            */
+  /*            Can be used to point to the iteration's state.             */
+  /*                                                                       */
+  typedef FT_Error  (*FT_List_Iterator)( FT_ListNode  node,
+                                         void*        user );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Iterate                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Parses a list and calls a given iterator function on each element. */
+  /*    Note that parsing is stopped as soon as one of the iterator calls  */
+  /*    returns a non-zero value.                                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list     :: A handle to the list.                                  */
+  /*    iterator :: An interator function, called on each node of the      */
+  /*                list.                                                  */
+  /*    user     :: A user-supplied field which is passed as the second    */
+  /*                argument to the iterator.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The result of the last iterator call.                              */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_List_Iterate( FT_List           list,
+                             FT_List_Iterator  iterator,
+                             void*             user );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_List_Destructor                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An FT_List iterator function which is called during a list         */
+  /*    finalisation by FT_List_Finalize() to destroy all elements in a    */
+  /*    given list.                                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    system :: The current system object.                               */
+  /*    data   :: The current object to destroy.                           */
+  /*    user   :: A typeless pointer passed to FT_List_Iterate().  It can  */
+  /*              used to point to the iteration's state.                  */
+  /*                                                                       */
+  typedef void  (*FT_List_Destructor)( FT_Memory  memory,
+                                       void*      data,
+                                       void*      user );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_List_Finalize                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys all elements in the list as well as the list itself.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list    :: A handle to the list.                                   */
+  /*                                                                       */
+  /*    destroy :: A list destructor that will be applied to each element  */
+  /*               of the list.                                            */
+  /*                                                                       */
+  /*    system  :: The current system object where destructions take       */
+  /*               place.                                                  */
+  /*                                                                       */
+  /*    user    :: A user-supplied field which is passed as the last       */
+  /*               argument to the destructor.                             */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_List_Finalize( FT_List             list,
+                          FT_List_Destructor  destroy,
+                          FT_Memory           memory,
+                          void*               user );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* FTLIST_H */
+
+
+/* END */
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
new file mode 100644
index 0000000..9e8e933
--- /dev/null
+++ b/src/base/ftobjs.c
@@ -0,0 +1,2123 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftobjs.c                                                               */
+/*                                                                         */
+/*  The FreeType private base classes (base).                              */
+/*                                                                         */
+/*  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 <ftobjs.h>
+#include <ftlist.h>
+#include <ftdebug.h>
+#include <ftstream.h>
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                           M E M O R Y                           ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the PTRACE() and PERROR() macros, used to print/log      */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_memory
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Alloc                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Allocates a new block of memory.  The returned area is always      */
+  /*    zero-filled, this is a strong convention in many FreeType parts.   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to a given `memory object' where allocation     */
+  /*              occurs.                                                  */
+  /*                                                                       */
+  /*    size   :: The size in bytes of the block to allocate.              */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+  /*              NULL if `size' is 0, or in case of error.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Alloc( FT_Memory  memory,
+                      FT_Long    size,
+                      void**     P )
+  {
+    FT_Assert( P != 0 );
+
+    if (size > 0)
+    {
+      *P = memory->alloc( memory, size );
+      if (!*P)
+      {
+        FT_ERROR(( "FT.Alloc:" ));
+        FT_ERROR(( " out of memory ? (%ld requested)\n",
+                   size ));
+
+        return FT_Err_Out_Of_Memory;
+      }
+      MEM_Set( *P, 0, size );
+    }
+    else
+      *P = NULL;
+
+    FT_TRACE2(( "FT_Alloc:" ));
+    FT_TRACE2(( " size = %ld, block = 0x%08lx, ref = 0x%08lx\n",
+                size, (long)*P, (long)P ));
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Realloc                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Reallocates a block of memory pointed to by `*P' to `Size' bytes   */
+  /*    from the heap, possibly changing `*P'.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to a given `memory object' where allocation     */
+  /*              occurs.                                                  */
+  /*                                                                       */
+  /*    current :: current block size in bytes                             */
+  /*    size    :: the new block size in bytes                              */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+  /*              NULL if `size' is 0, or in case of error.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    All callers of FT_Realloc _must_ provide the current block size    */
+  /*    as well as the new one.                                            */
+  /*                                                                       */
+  /*    When the memory object's flag FT_SYSTEM_FLAG_NO_REALLOC is         */
+  /*    set, this function will try to emulate a realloc through uses      */
+  /*    of FT_Alloc and FT_Free. Otherwise, it will call the system-       */
+  /*    specific "realloc" implementation.                                 */
+  /*                                                                       */
+  /*    (Some embedded systems do not have a working realloc).             */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Realloc( FT_Memory  memory,
+                        FT_Long    current,
+                        FT_Long    size,
+                        void*     *P )
+  {
+    void*  Q;
+
+    FT_Assert( P != 0 );
+
+    /* if the original pointer is NULL, call FT_Alloc() */
+    if ( !*P )
+      return FT_Alloc( memory, size, P );
+
+    /* if the new block if zero-sized, clear the current one */
+    if ( size <= 0 )
+    {
+      FT_Free( memory, P );
+      return FT_Err_Ok;
+    }
+
+    Q = memory->realloc( memory, current, size, *P );
+    if ( !Q ) goto Fail;
+
+    *P = Q;
+    return FT_Err_Ok;
+
+  Fail:
+    FT_ERROR(( "FT.Realloc:" ));
+    FT_ERROR(( " failed (current %ld, requested %ld)\n",
+               current, size ));
+    return FT_Err_Out_Of_Memory;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Free                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given block of memory allocated through FT_Alloc().     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to a given `memory object' where allocation     */
+  /*              occured.                                                 */
+  /*                                                                       */
+  /*    P      :: This is the _address_ of a _pointer_ which points to the */
+  /*              allocated block.  It is always set to NULL on exit.      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    If P or *P are NULL, this function should return successfully.     */
+  /*    This is a strong convention within all of FreeType and its         */
+  /*    drivers.                                                           */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_Free( FT_Memory  memory,
+                     void*     *P )
+  {
+    FT_TRACE2(( "FT_Free:" ));
+    FT_TRACE2(( " Freeing block 0x%08lx, ref 0x%08lx\n",
+                (long)P, (P ? (long)*P : -1) ));
+
+    FT_Assert( P != 0 );
+    
+    if ( *P )
+    {
+      memory->free( memory, *P );
+      *P = 0;
+    }
+  }
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                   O B J E C T   M A N A G E M E N T             ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+      /* destructor for sizes list */
+      static
+      void  destroy_size( FT_Memory  memory,
+                          FT_Size    size,
+                          FT_Driver  driver )
+      {
+        /* finalize format-specific stuff */
+        driver->interface.done_size( size );
+        FREE( size );
+      }
+
+
+      /* destructor for faces list */
+      static
+      void  destroy_face( FT_Memory  memory,
+                          FT_Face    face,
+                          FT_Driver  driver )
+      {
+        /* Discard glyph slots for this face                                */
+        /* XXX: Beware!  FT_Done_GlyphSlot() changes the field `face->slot' */
+        while ( face->glyph )
+          FT_Done_GlyphSlot( face->glyph );
+    
+        /* Discard all sizes for this face */
+        FT_List_Finalize( &face->sizes_list,
+                         (FT_List_Destructor)destroy_size,
+                         memory,
+                         driver );
+        face->size = 0;
+    
+        /* finalize format-specific stuff */
+        driver->interface.done_face( face );
+    
+        /* Now discard client data */
+        if ( face->generic.finalizer )
+          face->generic.finalizer( face );
+    
+        /* get rid of it */
+        FREE( face );
+      }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*   Destroy_Driver                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given driver object.  This also destroys all child      */
+  /*    faces.                                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver :: A handle to the target driver object.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The driver _must_ be LOCKED!                                      */
+  /*                                                                       */
+  static
+  void   Destroy_Driver( FT_Driver  driver )
+  {
+    FT_Memory  memory  = driver->memory;
+
+    /* now, finalize all faces in the driver list */
+    FT_List_Finalize( &driver->faces_list,
+                      (FT_List_Destructor)destroy_face,
+                      memory,
+                      driver );
+
+    /* finalize the driver object */
+    if (driver->interface.done_driver)
+      driver->interface.done_driver(driver);
+
+    /* finalize client-data */
+    if (driver->generic.finalizer)
+      driver->generic.finalizer(driver);
+
+    /* discard it */
+    FREE( driver );
+  }
+
+
+
+
+
+  BASE_FUNC
+  FT_Glyph_Format*  FT_Get_Glyph_Format( FT_Library    library,
+                                         FT_Glyph_Tag  format_tag )
+  {
+    FT_Glyph_Format*  cur   = library->glyph_formats;
+    FT_Glyph_Format*  limit = cur + FT_MAX_GLYPH_FORMATS;
+    
+    for ( ; cur < limit; cur ++ )
+    {
+      if ( cur->format_tag == format_tag )
+        return cur;
+    }
+    
+    return 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Raster                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used to change the raster module used to convert  */
+  /*    from a given memory object.  It is thus possible to use libraries  */
+  /*    with distinct memory allocators within the same program.           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory  :: A handle to the original memory object.                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    library :: A handle to a new library object.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Set_Raster( FT_Library            library,
+                           FT_Raster_Interface*  interface,
+                           FT_Raster             raster )
+  {
+    FT_Memory         memory = library->memory;
+    FT_Error          error  = FT_Err_Ok;
+    FT_Glyph_Format*  format;
+
+    /* allocate the render pool if necessary */
+    if ( !library->raster_pool &&
+         ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
+      goto Exit;
+
+    /* find the glyph formatter for the raster's format */
+    format = FT_Get_Glyph_Format( library, interface->format_tag );
+    if (!format)
+    {
+      error = FT_Err_Invalid_Argument;
+      goto Exit;
+    }
+    
+    /* free previous raster object if necessary */
+    if (format->raster_allocated)
+    {
+      FREE( format->raster );
+      format->raster_allocated = 0;
+    }
+    
+    /* allocate new raster object is necessary */
+    if (!raster)
+    {
+      if ( ALLOC( raster, interface->size ) )
+        goto Exit;
+        
+      format->raster_allocated = 1;
+    }
+    format->raster           = raster;
+    format->raster_interface = interface;
+    
+    /* initialize the raster object */
+    error = interface->init( raster,
+                             (char*)library->raster_pool,
+                             FT_RENDER_POOL_SIZE );
+    if (error)
+    {
+      if (format->raster_allocated)
+      {
+        FREE( format->raster );
+        format->raster_allocated = 0;
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+  EXPORT_FUNC
+  void  FT_Set_Debug_Hook( FT_Library         library,
+                           FT_UInt            hook_index,
+                           FT_DebugHook_Func  debug_hook )
+  {
+    if (hook_index < (sizeof(library->debug_hooks)/sizeof(void*)))
+    {
+      library->debug_hooks[hook_index] = debug_hook;
+    }
+  }
+                           
+  
+  
+  BASE_FUNC
+  FT_Error  FT_Add_Glyph_Format( FT_Library        library,
+                                 FT_Glyph_Format*  format )
+  {
+    FT_Glyph_Format*  new = 0;
+    
+    {
+      FT_Glyph_Format*  cur = library->glyph_formats;
+      FT_Glyph_Format*  limit = cur + FT_MAX_GLYPH_FORMATS;
+      
+      for ( ; cur < limit; cur++ )
+      {
+        /* return an error if the format is already registered */
+        if ( cur->format_tag == format->format_tag )
+          return FT_Err_Invalid_Glyph_Format;
+          
+        if ( cur->format_tag == 0 && new == 0 )
+          new = cur;
+      }
+    }
+      
+    /* if there is no place to hold the new format, return an error */
+    if (!new)
+      return FT_Err_Too_Many_Glyph_Formats;
+        
+    *new = *format;
+    
+    /* now, create a raster object if we need to */
+    return FT_Set_Raster( library,
+                          format->raster_interface,
+                          format->raster );
+  }
+  
+
+
+  BASE_FUNC
+  FT_Error  FT_Remove_Glyph_Format( FT_Library    library,
+                                    FT_Glyph_Tag  format_tag )
+  {
+    FT_Memory         memory;
+    FT_Glyph_Format*  cur   = library->glyph_formats;
+    FT_Glyph_Format*  limit = cur + FT_MAX_GLYPH_FORMATS;
+    
+    memory = library->memory;
+    
+    for ( ; cur < limit; cur++ )
+    {
+      if (cur->format_tag == format_tag)
+      {
+        if (cur->raster_allocated)
+        {
+          FREE( cur->raster );
+          cur->raster_allocated = 0;
+        }
+        cur->format_tag = 0;
+        return FT_Err_Ok;
+      }
+    }
+    
+    return FT_Err_Invalid_Argument;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Library                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used to create a new FreeType library instance    */
+  /*    from a given memory object.  It is thus possible to use libraries  */
+  /*    with distinct memory allocators within the same program.           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory  :: A handle to the original memory object.                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    library :: A handle to a new library object.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_New_Library( FT_Memory    memory,
+                            FT_Library*  alibrary )
+  {
+    FT_Library library      = 0;
+    FT_Error   error;
+
+    /* First of all, allocate the library object */
+    if ( ALLOC( library, sizeof ( *library ) ) )
+      return error;
+
+    library->memory = memory;
+
+    /* now register the default raster for the `outline' glyph image format */
+    {
+      FT_Glyph_Format  outline_format =
+      {
+        ft_glyph_format_outline,
+        &ft_default_raster,
+        0,
+        0
+      };
+      
+      error = FT_Add_Glyph_Format( library, &outline_format );
+    }
+
+    /* That's ok now */
+    *alibrary = library;
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_Library                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards a given library object.  This closes all drivers and      */
+  /*    discards all resource objects.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to the target library                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Done_Library( FT_Library  library )
+  {
+    FT_Memory  memory;
+    FT_Int     n;
+
+
+    if ( !library )
+      return FT_Err_Invalid_Library_Handle;
+
+    memory = library->memory;
+
+    /* Discard client-data */
+    if( library->generic.finalizer )
+      library->generic.finalizer( library );
+
+    /* Close all drivers in the library */
+    for ( n = 0; n < library->num_drivers; n++ )
+    {
+      FT_Driver  driver = library->drivers[n];
+
+      if ( driver )
+      {
+        Destroy_Driver( driver );
+        library->drivers[n] = 0;
+      }
+    }
+
+    /* Destroy raster object */
+    FREE( library->raster_pool   );
+    
+    {
+      FT_Glyph_Format*  cur = library->glyph_formats;
+      FT_Glyph_Format*  limit = cur + FT_MAX_GLYPH_FORMATS;
+      
+      for ( ; cur < limit; cur++ )
+      {
+        if ( cur->raster_allocated )
+        {
+          FREE( cur->raster );
+          cur->raster_allocated = 0;
+        }
+      }
+    }
+
+    FREE( library );
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Raster_Mode                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Set a raster-specific mode.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to a target library object.                    */
+  /*    format  :: the glyph format used to select the raster              */
+  /*    mode    :: the raster-specific mode descriptor                     */
+  /*    args    :: the mode arguments                                      */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Set_Raster_Mode( FT_Library    library,
+                                FT_Glyph_Tag  format_tag,
+                                const char*   mode,
+                                const char*   args )
+  {
+    FT_Memory         memory;
+    FT_Error          error;
+    FT_Glyph_Format*  format = 0;
+
+    {
+      FT_Glyph_Format*  cur   = library->glyph_formats;
+      FT_Glyph_Format*  limit = cur + FT_MAX_GLYPH_FORMATS;
+      
+      for (; cur < limit; cur++)
+      {
+        if (cur->format_tag == format_tag)
+        {
+          format = cur;
+          break;
+        }
+      }
+    }
+
+    if (!format)
+      return FT_Err_Invalid_Argument;
+
+    memory = library->memory;
+
+    error = FT_Err_Ok;
+    if (format->raster)
+      error = format->raster_interface->set_mode( format->raster, mode, args );
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Add_Driver                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Registers a new driver in a given library object.  This function   */
+  /*    takes only a pointer to a driver interface.  It uses it to create  */
+  /*    the new driver, then sets up some important fields.                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library          :: A handle to the target library object.         */
+  /*                                                                       */
+  /*    driver_interface :: A pointer to a driver interface table.         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function doesn't check whether the driver is already          */
+  /*    installed!                                                         */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Add_Driver( FT_Library                 library,
+                           const FT_DriverInterface*  driver_interface )
+  {
+    FT_Error   error;
+    FT_Driver  driver;
+    FT_Memory  memory;
+
+    if ( !library || !driver_interface )
+      return FT_Err_Invalid_Library_Handle;
+
+    memory = library->memory;
+    error  = FT_Err_Ok;
+
+    if ( library->num_drivers >= FT_MAX_DRIVERS )
+      error = FT_Err_Too_Many_Drivers;
+    else
+    {
+      if ( ALLOC( driver, driver_interface->driver_object_size ) )
+        goto Exit;
+
+      driver->library   = library;
+      driver->memory    = memory;
+      driver->interface = *driver_interface;
+
+      if (driver_interface->init_driver)
+      {
+        error = driver_interface->init_driver( driver );
+        if ( error ) goto Fail;
+      }
+
+      library->drivers[library->num_drivers++] = driver;
+      goto Exit;
+
+    Fail:
+      FREE( driver );
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Remove_Driver                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Unregister a given driver.  This closes the driver, which in turn  */
+  /*    destroys all faces, sizes, slots, etc. associated with it.         */
+  /*                                                                       */
+  /*    This function also DESTROYS the driver object.                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver :: A handle to target driver object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Remove_Driver( FT_Driver  driver )
+  {
+    FT_Library  library;
+    FT_Memory   memory;
+    FT_Driver   *cur, *last;
+    FT_Error    error;
+
+
+    if ( !driver )
+      return FT_Err_Invalid_Driver_Handle;
+
+    library = driver->library;
+    memory  = driver->memory;
+
+    if ( !library || !memory )
+      return FT_Err_Invalid_Driver_Handle;
+
+    /* look-up driver entry in library table */
+    error = FT_Err_Invalid_Driver_Handle;
+    cur   = library->drivers;
+    last  = cur + library->num_drivers - 1;
+
+    for ( ; cur <= last; cur++ )
+    {
+      if ( *cur == driver )
+      {
+        /* Destroy the driver object */
+        Destroy_Driver( driver );
+
+        /* now move the last driver in the table to the vacant slot */
+        if (cur < last)
+        {
+          *cur  = *last;
+          *last = 0;
+        }
+        library->num_drivers--;
+
+        /* exit loop */
+        error = FT_Err_Ok;
+        break;
+      }
+    }
+
+    return error;
+  }
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Driver                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    returns the handle of the driver responsible for a given format    */
+  /*    (or service) according to its `name'.                              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library     :: handle to library object.                           */
+  /*    driver_name :: name of driver to look-up.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    handle to driver object. 0 otherwise                               */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Driver  FT_Get_Driver( FT_Library  library,
+                            char*       driver_name )
+  {
+    FT_Driver  *cur, *limit;
+    
+    if (!library || !driver_name)
+      return 0;
+      
+    cur   = library->drivers;
+    limit = cur + library->num_drivers;
+    for ( ; cur < limit; cur++ )
+    {
+      if ( strcmp( (*cur)->interface.driver_name, driver_name ) == 0 )
+        return *cur;
+    }
+    return 0;
+  }
+
+
+
+  static
+  FT_Error  open_face( FT_Driver  driver,
+                       FT_Stream  stream,
+                       FT_Long    face_index,
+                       FT_Face*   aface )
+  {
+    FT_Memory            memory;
+    FT_DriverInterface*  interface;
+    FT_Face              face = 0;
+    FT_Error             error;
+
+
+    interface = &driver->interface;
+    memory    = driver->memory;
+
+    /* allocate the face object, and performs basic initialisation */
+    if ( ALLOC( face, interface->face_object_size ) )
+      goto Fail;
+
+    face->driver = driver;
+    face->memory = memory;
+    face->stream = stream;
+
+    error = interface->init_face( stream, face_index, face );
+    if ( error )
+      goto Fail;
+
+    *aface = face;
+
+  Fail:
+    if ( error )
+    {
+      interface->done_face( face );
+      FREE( face );
+      *aface = 0;
+    }
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Face                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new face object from a given resource and typeface       */
+  /*    index.                                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    resource   :: A handle to a source resource.                       */
+  /*                                                                       */
+  /*    face_index :: The index of the face within the resource.  The      */
+  /*                  first face has index 0.                              */
+  /* <Output>                                                              */
+  /*    face       :: A handle to a new face object.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Unlike FreeType 1.1, this function automatically creates a glyph   */
+  /*    slot for the face object which can be accessed directly through    */
+  /*    `face->glyph'.                                                     */
+  /*                                                                       */
+  /*    Note that additional slots can be added to each face through the   */
+  /*    FT_New_GlyphSlot() API function.  Slots are linked in a single     */
+  /*    list through their `next' field.                                   */
+  /*                                                                       */
+  /*    FT_New_Face() can be used to determine and/or check the font       */
+  /*    format of a given font resource.  If the `face_index' field is     */
+  /*    negative, the function will _not_ return any face handle in        */
+  /*    `*face'.  Its return value should be 0 if the resource is          */
+  /*    recognized, or non-zero if not.                                    */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_New_Face( FT_Library   library,
+                         const char*  pathname,
+                         FT_Long      face_index,
+                         FT_Face     *aface )
+  {
+    FT_Stream  stream;
+    FT_Memory  memory;
+    FT_Error   error;
+    
+    memory = library->memory;
+    if ( ALLOC( stream, sizeof(*stream) ) )
+      goto Fail;
+      
+    stream->memory = memory;
+    
+    error = FT_New_Stream( pathname, stream );
+    if (error) goto Fail_Stream;
+    
+    error = FT_Open_Face( library, stream, face_index, aface );
+    if (!error)
+      return error;
+
+    /* close stream in case of error */
+    stream->close( stream );
+    
+  Fail_Stream:
+    FREE(stream);
+  Fail:
+    return error;
+  }
+
+  EXPORT_FUNC
+  FT_Error  FT_New_Memory_Face( FT_Library   library,
+                                void*        file_base,
+                                FT_Long      file_size,
+                                FT_Long      face_index,
+                                FT_Face*     face )
+  {
+    FT_Stream  stream;
+    FT_Memory  memory;
+    FT_Error   error;
+    
+    memory = library->memory;
+    if ( ALLOC( stream, sizeof(*stream) ) )
+      goto Fail;
+      
+    stream->memory = memory;
+    
+    FT_New_Memory_Stream( library, (void*)file_base, file_size, stream );
+    
+    error = FT_Open_Face( library, stream, face_index, face );
+    if (!error)
+      return error;
+
+    FREE(stream);
+  Fail:
+    return error;
+  }
+
+  
+  EXPORT_FUNC
+  FT_Error  FT_Open_Face( FT_Library library,
+                          FT_Stream  stream,
+                          FT_Long    face_index,
+                          FT_Face*   aface )
+  {
+    FT_Error     error;
+    FT_Driver    driver;
+    FT_Memory    memory;
+    FT_Face      face = 0;
+    FT_ListNode  node = 0;
+
+    *aface = 0;
+
+    if ( !library || !stream )
+      return FT_Err_Invalid_Handle;
+
+    memory = library->memory;
+
+    {
+      /* check each font driver for an appropriate format */
+	  FT_Driver*  cur   = library->drivers;
+	  FT_Driver*  limit = cur + library->num_drivers;
+
+      for ( ; cur < limit; cur++ )
+      {
+        driver = *cur;
+        if (driver->interface.face_object_size)
+        {
+          error = open_face( driver, stream, face_index, &face );
+          if ( !error )
+            goto Success;
+
+          if ( error != FT_Err_Unknown_File_Format )
+            goto Bad_Resource;
+        }
+      }
+
+      /* no driver is able to handle this format */
+      error = FT_Err_Unknown_File_Format;
+      goto Bad_Resource;
+    }
+
+  Success:
+    /****************************************************************/
+    /* if we were simply checking the font format, discard the face */
+    /* object, then return successfully.                            */
+    if ( face_index < 0 )
+    {
+      driver->interface.done_face( face );
+      FREE( face );
+      goto Exit;
+    }
+
+    FT_TRACE4(( "FT_New_Face: New face object, adding to list\n" ));
+
+    /****************************************************************/
+    /* Otherwise add the face object to its driver's list           */
+    if ( ALLOC( node, sizeof ( *node ) ) )
+      goto Fail;
+
+    node->data = face;
+    FT_List_Add( &driver->faces_list, node );
+
+    /****************************************************************/
+    /* now allocate a glyph slot object for the face                */
+    {
+      FT_GlyphSlot  slot;
+
+      FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
+      error = FT_New_GlyphSlot( face, &slot );
+      if ( error ) goto Fail;
+    }
+    
+    /****************************************************************/
+    /* finally allocate a size object for the face                  */
+    {
+      FT_Size  size;
+
+      FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
+      error = FT_New_Size( face, &size );
+      if ( error ) goto Fail;
+    }
+    
+    *aface = face;
+    goto Exit;
+
+  Fail:
+    FT_Done_Face( face );
+
+  Bad_Resource:
+    
+  Exit:
+    FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_Face                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards a given face object, as well as all of its child slots    */
+  /*    and sizes.                                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to a target face object.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Done_Face( FT_Face  face )
+  {
+    FT_Error             error;
+    FT_Driver            driver;
+    FT_Memory            memory;
+    FT_DriverInterface*  interface;
+    FT_ListNode          node;
+
+
+    if (!face || !face->driver )
+      return FT_Err_Invalid_Face_Handle;
+
+    driver    = face->driver;
+    interface = &driver->interface;
+    memory    = driver->memory;
+
+    /* find face in driver's list */
+    node = FT_List_Find( &driver->faces_list, face );
+    if ( node )
+    {
+      /* remove face object from the driver's list */
+      FT_List_Remove( &driver->faces_list, node );
+      FREE( node );
+
+      /* now destroy the object proper */
+      destroy_face( memory, face, driver );
+      error = FT_Err_Ok;
+    }
+    else
+      error = FT_Err_Invalid_Face_Handle;
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Size                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new size object from a given face object.                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to a parent face object.                          */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    size :: A handle to a new size object.                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_New_Size( FT_Face   face,
+                         FT_Size*  asize )
+  {
+    FT_Error             error;
+    FT_Memory            memory;
+    FT_Driver            driver;
+    FT_DriverInterface*  interface;
+
+    FT_Size              size = 0;
+    FT_ListNode          node = 0;
+
+
+    if ( !face || !face->driver )
+      return FT_Err_Invalid_Face_Handle;
+
+    *asize    = 0;
+    driver    = face->driver;
+    interface = &driver->interface;
+    memory    = face->memory;
+
+    /* Allocate new size object and perform basic initialisation */
+    if ( ALLOC( size, interface->size_object_size ) ||
+         ALLOC( node, sizeof ( FT_ListNodeRec )   ) )
+      goto Exit;
+
+    size->face = face;
+
+    error = interface->init_size( size );
+
+    /* in case of success, add to the face's list */
+    if ( !error )
+    {
+      *asize     = size;
+      node->data = size;
+      FT_List_Add( &face->sizes_list, node );
+      
+      /* record as current size for the face */
+      face->size = size;
+    }
+
+  Exit:
+    if ( error )
+    {
+      FREE( node );
+      FREE( size );
+    }
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_Size                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards a given size object.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size :: A handle to a target size object                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Done_Size( FT_Size  size )
+  {
+    FT_Error     error;
+    FT_Driver    driver;
+    FT_Memory    memory;
+    FT_Face      face;
+    FT_ListNode  node;
+
+
+    if ( !size || !size->face )
+      return FT_Err_Invalid_Size_Handle;
+
+    driver = size->face->driver;
+    if ( !driver )
+      return FT_Err_Invalid_Driver_Handle;
+
+    memory = driver->memory;
+
+    error = FT_Err_Ok;
+    face  = size->face;
+    node  = FT_List_Find( &face->sizes_list, size );
+    if ( node )
+    {
+      FT_List_Remove( &face->sizes_list, node );
+      FREE( node );
+
+      if (face->size == size)
+      {
+        face->size = 0;
+        if (face->sizes_list.head)
+          face->size = (FT_Size)(face->sizes_list.head->data);
+      }
+
+      destroy_size( memory, size, driver );
+    }
+    else
+      error = FT_Err_Invalid_Size_Handle;
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Char_Size                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets the character dimensions of a given size object.  The         */
+  /*    `char_size' value is used for the width and height, expressed in   */
+  /*    26.6 fractional points.  1 point = 1/72 inch.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size      :: A handle to a target size object.                     */
+  /*    char_size :: The character size, in 26.6 fractional points.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    When dealing with fixed-size faces (i.e., non-scalable formats),   */
+  /*    use the function FT_Set_Pixel_Sizes().                             */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Set_Char_Size( FT_Face     face,
+                              FT_F26Dot6  char_width,
+                              FT_F26Dot6  char_height,
+                              FT_UInt     horz_resolution,
+                              FT_UInt     vert_resolution )
+  {
+    FT_Error             error;
+    FT_Driver            driver;
+    FT_Memory            memory;
+    FT_DriverInterface*  interface;
+
+    if ( !face || !face->size || !face->driver)
+      return FT_Err_Invalid_Face_Handle;
+
+    if (!char_width)
+      char_width = char_height;
+      
+    else if (!char_height)
+      char_height = char_width;
+      
+    if (!horz_resolution)
+      horz_resolution = 72;
+      
+    if (!vert_resolution)
+      vert_resolution = 72;
+
+    driver    = face->driver;
+    interface = &driver->interface;
+    memory    = driver->memory;
+
+    error = interface->set_char_sizes( face->size,
+                                       char_width,
+                                       char_height,
+                                       horz_resolution,
+                                       vert_resolution );
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Pixel_Sizes                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets the character dimensions of a given size object.  The width   */
+  /*    and height are expressed in integer pixels.                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size         :: A handle to a target size object.                  */
+  /*    pixel_width  :: The character width, in integer pixels.            */
+  /*    pixel_height :: The character height, in integer pixels.           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Set_Pixel_Sizes( FT_Face  face,
+                                FT_UInt  pixel_width,
+                                FT_UInt  pixel_height )
+  {
+    FT_Error             error;
+    FT_Driver            driver;
+    FT_Memory            memory;
+    FT_DriverInterface*  interface;
+
+    if ( !face || !face->size || !face->driver )
+      return FT_Err_Invalid_Face_Handle;
+
+    driver    = face->driver;
+    interface = &driver->interface;
+    memory    = driver->memory;
+
+    error = interface->set_pixel_sizes( face->size, pixel_width, pixel_height );
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_GlyphSlot                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    It is sometimes useful to have more than one glyph slot for a      */
+  /*    given face object.  This function is used to create additional     */
+  /*    slots.  All of them are automatically discarded when the face is   */
+  /*    destroyed.                                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face  :: A handle to a parent face object.                         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    aslot :: A handle to a new glyph slot object.                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_New_GlyphSlot( FT_Face        face,
+                              FT_GlyphSlot*  aslot )
+  {
+    FT_Error             error;
+    FT_Driver            driver;
+    FT_DriverInterface*  interface;
+    FT_Memory            memory;
+    FT_GlyphSlot         slot;
+
+
+    *aslot = 0;
+
+    if ( !face || !face->driver )
+      return FT_Err_Invalid_Face_Handle;
+
+    driver    = face->driver;
+    interface = &driver->interface;
+    memory    = driver->memory;
+
+    FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
+    if ( ALLOC( slot, interface->slot_object_size ) )
+      goto Exit;
+
+    slot->face = face;
+    
+    slot->max_subglyphs = 0;
+    slot->num_subglyphs = 0;
+    slot->subglyphs     = 0;
+
+    error = interface->init_glyph_slot( slot );
+    if ( !error )
+    {
+      /* in case of success, add slot to the face's list */
+      slot->next  = face->glyph;
+      face->glyph = slot;
+      *aslot      = slot;
+    }
+
+    if ( error )
+      FREE( slot );
+
+  Exit:
+    FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_GlyphSlot                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given glyph slot.  Remember however that all slots are  */
+  /*    automatically destroyed with its parent.  Using this function is   */
+  /*    not always mandatory.                                              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    slot :: A handle to a target glyph slot.                           */
+  /*                                                                       */
+  EXPORT_FUNC
+  void  FT_Done_GlyphSlot( FT_GlyphSlot  slot )
+  {
+    if (slot)
+    {
+      FT_Driver      driver = slot->face->driver;
+      FT_Memory      memory = driver->memory;
+      FT_GlyphSlot*  parent;
+      FT_GlyphSlot   cur;
+
+
+      /* Remove slot from its parent face's list */
+      parent = &slot->face->glyph;
+      cur    = *parent;
+      while ( cur )
+      {
+        if ( cur == slot )
+        {
+          *parent = cur->next;
+          break;
+        }
+        cur = cur->next;
+      }
+
+      driver->interface.done_glyph_slot( slot );
+      FREE( slot );
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Load_Glyph                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function used to load a single glyph within a given glyph slot,  */
+  /*    for a given size.                                                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    slot        :: A handle to a target slot object where the glyph    */
+  /*                   will be loaded.                                     */
+  /*                                                                       */
+  /*    size        :: A handle to the source face size at which the glyph */
+  /*                   must be scaled/loaded.                              */
+  /*                                                                       */
+  /*    glyph_index :: The index of the glyph in the font file.            */
+  /*                                                                       */
+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
+  /*                   FT_LOAD_XXX constants can be used to control the    */
+  /*                   glyph loading process (e.g., whether the outline    */
+  /*                   should be scaled, whether to load bitmaps or not,   */
+  /*                   whether to hint the outline, etc).                  */
+  /* <Output>                                                              */
+  /*    result      :: A set of bit flags indicating the type of data that */
+  /*                   was loaded in the glyph slot (outline or bitmap,    */
+  /*                   etc).                                               */
+  /*                                                                       */
+  /*                   You can set this field to 0 if you don't want this  */
+  /*                   information.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Load_Glyph( FT_Face  face,
+                           FT_UInt  glyph_index,
+                           FT_Int   load_flags )
+  {
+    FT_Error   error;
+    FT_Driver  driver;
+
+    if ( !face || !face->size || !face->glyph )
+      return FT_Err_Invalid_Face_Handle;
+
+    driver = face->driver;
+
+    error = driver->interface.load_glyph( face->glyph,
+                                          face->size,
+                                          glyph_index,
+                                          load_flags );
+
+    return error;
+  }
+
+
+  EXPORT_FUNC
+  FT_Error  FT_Load_Char( FT_Face   face,
+                          FT_ULong  char_code,
+                          FT_Int    load_flags )
+  {
+    FT_Error   error;
+    FT_Driver  driver;
+    FT_UInt    glyph_index;
+    
+    if (!face || !face->size || !face->glyph || !face->charmap )
+      return FT_Err_Invalid_Face_Handle;
+      
+    driver      = face->driver;
+    glyph_index = FT_Get_Char_Index( face, char_code );
+    
+    if (glyph_index == 0)
+      error = FT_Err_Invalid_Character_Code;
+    else
+      error = driver->interface.load_glyph( face->glyph,
+                                            face->size,
+                                            glyph_index,
+                                            load_flags );
+    return error;
+  }
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Kerning                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the kerning vector between two glyphs of a same face.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: A handle to a 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 method.  Other layouts, or more sophisticated    */
+  /*    kernings, are out of the scope of this API function -- they can be */
+  /*    implemented through format-specific interfaces.                    */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Get_Kerning( FT_Face     face,
+                            FT_UInt     left_glyph,
+                            FT_UInt     right_glyph,
+                            FT_Vector*  kerning )
+  {
+    FT_Error   error;
+    FT_Driver  driver;
+    FT_Memory  memory;
+
+
+    if ( !face )
+    {
+      error = FT_Err_Invalid_Face_Handle;
+      goto Exit;
+    }
+
+    driver = face->driver;
+    memory = driver->memory;
+
+    if ( driver->interface.get_kerning )
+    {
+      error = driver->interface.get_kerning( face, left_glyph,
+                                             right_glyph, kerning );
+    }
+    else
+    {
+      kerning->x = 0;
+      kerning->y = 0;
+      error      = FT_Err_Ok;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Char_Index                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the glyph index of a given character code.  This function  */
+  /*    uses a charmap object to do the translation.                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    charmap  :: A handle to a filter charmap object.                   */
+  /*    charcode :: The character code.                                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The glyph index.  0 means `undefined character code'.              */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_UInt  FT_Get_Char_Index( FT_Face  face,
+                              FT_ULong charcode )
+  {
+    FT_UInt    result;
+    FT_Driver  driver;
+
+    result = 0;
+    if ( face && face->charmap )
+    {
+      driver = face->driver;
+      result = driver->interface.get_char_index( face->charmap, charcode );
+    }
+    return result;
+  }
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Decompose_Outline                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Walks over an outline's structure to decompose it into individual  */
+  /*    segments and Bezier arcs.  This function is also able to emit      */
+  /*    `move to' and `close to' operations to indicate the start and end  */
+  /*    of new contours in the outline.                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline   :: A pointer to the source target.                       */
+  /*                                                                       */
+  /*    interface :: A table of `emitters', i.e,. function pointers called */
+  /*                 during decomposition to indicate path operations.     */
+  /*                                                                       */
+  /*    user      :: A typeless pointer which is passed to each emitter    */
+  /*                 during the decomposition.  It can be used to store    */
+  /*                 the state during the decomposition.                   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means sucess.                                       */
+  /*                                                                       */
+  EXPORT_FUNC
+  int  FT_Decompose_Outline( FT_Outline*        outline,
+                             FT_Outline_Funcs*  interface,
+                             void*              user )
+  {
+    typedef enum _phases
+    {
+      phase_point,
+      phase_conic,
+      phase_cubic,
+      phase_cubic2
+
+    } TPhase;
+
+    FT_Vector  v_first;
+    FT_Vector  v_last;
+    FT_Vector  v_control;
+    FT_Vector  v_control2;
+    FT_Vector  v_start;
+
+    FT_Vector* point;
+    char*      flags;
+
+    int    n;         /* index of contour in outline     */
+    int    first;     /* index of first point in contour */
+    int    index;     /* current point's index           */
+
+    int    error;
+
+    char   tag;       /* current point's state           */
+    TPhase phase;
+
+
+    first = 0;
+
+    for ( n = 0; n < outline->n_contours; n++ )
+    {
+      int  last;  /* index of last point in contour */
+
+
+      last = outline->contours[n];
+
+      v_first = outline->points[first];
+      v_last  = outline->points[last];
+
+      v_start = v_control = v_first;
+
+      tag   = FT_CURVE_TAG( outline->flags[first] );
+      index = first;
+
+      /* A contour cannot start with a cubic control point! */
+
+      if ( tag == FT_Curve_Tag_Cubic )
+        return FT_Err_Invalid_Outline;
+
+
+      /* check first point to determine origin */
+
+      if ( tag == FT_Curve_Tag_Conic )
+      {
+        /* first point is conic control.  Yes, this happens. */
+        if ( FT_CURVE_TAG( outline->flags[last] ) == FT_Curve_Tag_On )
+        {
+          /* start at last point if it is on the curve */
+          v_start = v_last;
+        }
+        else
+        {
+          /* if both first and last points are conic,         */
+          /* start at their middle and record its position    */
+          /* for closure                                      */
+          v_start.x = ( v_start.x + v_last.x ) / 2;
+          v_start.y = ( v_start.y + v_last.y ) / 2;
+
+          v_last = v_start;
+        }
+        phase = phase_conic;
+      }
+      else
+        phase = phase_point;
+
+
+      /* Begin a new contour with MOVE_TO */
+
+      error = interface->move_to( &v_start, user );
+      if ( error )
+        return error;
+
+      point = outline->points + first;
+      flags = outline->flags  + first;
+
+      /* now process each contour point individually */
+
+      while ( index < last )
+      {
+        index++;
+        point++;
+        flags++;
+
+        tag = FT_CURVE_TAG( flags[0] );
+
+        switch ( phase )
+        {
+        case phase_point:     /* the previous point was on the curve */
+
+          switch ( tag )
+          {
+            /* two succesive on points -> emit segment */
+          case FT_Curve_Tag_On:
+            error = interface->line_to( point, user );
+            break;
+
+            /* on point + conic control -> remember control point */
+          case FT_Curve_Tag_Conic:
+            v_control = point[0];
+            phase     = phase_conic;
+            break;
+
+            /* on point + cubic control -> remember first control */
+          default:
+            v_control = point[0];
+            phase     = phase_cubic;
+            break;
+          }
+          break;
+
+        case phase_conic:   /* the previous point was a conic control */
+
+          switch ( tag )
+          {
+            /* conic control + on point -> emit conic arc */
+          case  FT_Curve_Tag_On:
+            error = interface->conic_to( &v_control, point, user );
+            phase = phase_point;
+            break;
+
+            /* two successive conics -> emit conic arc `in between' */
+          case FT_Curve_Tag_Conic:
+            {
+              FT_Vector  v_middle;
+
+
+              v_middle.x = (v_control.x + point->x)/2;
+              v_middle.y = (v_control.y + point->y)/2;
+
+              error = interface->conic_to( &v_control,
+                                           &v_middle, user );
+              v_control = point[0];
+            }
+             break;
+
+          default:
+            error = FT_Err_Invalid_Outline;
+          }
+          break;
+
+        case phase_cubic:  /* the previous point was a cubic control */
+
+          /* this point _must_ be a cubic control too */
+          if ( tag != FT_Curve_Tag_Cubic )
+            return FT_Err_Invalid_Outline;
+
+          v_control2 = point[0];
+          phase      = phase_cubic2;
+          break;
+
+
+        case phase_cubic2:  /* the two previous points were cubics */
+
+          /* this point _must_ be an on point */
+          if ( tag != FT_Curve_Tag_On )
+            error = FT_Err_Invalid_Outline;
+          else
+            error = interface->cubic_to( &v_control, &v_control2,
+                                         point, user );
+          phase = phase_point;
+          break;
+        }
+
+        /* lazy error testing */
+        if ( error )
+          return error;
+      }
+
+      /* end of contour, close curve cleanly */
+      error = 0;
+
+      tag = FT_CURVE_TAG( outline->flags[first] );
+
+      switch ( phase )
+      {
+      case phase_point:
+        if ( tag == FT_Curve_Tag_On )
+          error = interface->line_to( &v_first, user );
+        break;
+
+      case phase_conic:
+        error = interface->conic_to( &v_control, &v_start, user );
+        break;
+
+      case phase_cubic2:
+        if ( tag == FT_Curve_Tag_On )
+          error = interface->cubic_to( &v_control, &v_control2,
+                                       &v_first,   user );
+        else
+          error = FT_Err_Invalid_Outline;
+        break;
+
+      default:
+        error = FT_Err_Invalid_Outline;
+        break;
+      }
+
+      if ( error )
+        return error;
+
+      first = last + 1;
+    }
+
+    return 0;
+  }
+
+
+  static
+  const FT_Outline  null_outline = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Outline                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new outline of a given size.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library     :: A handle to the library object from where the       */
+  /*                   outline is allocated.  Note however that the new    */
+  /*                   outline will NOT necessarily be FREED when          */
+  /*                   destroying the library, by FT_Done_FreeType().      */
+  /*                                                                       */
+  /*    numPoints   :: The maximum number of points within the outline.    */
+  /*                                                                       */
+  /*    numContours :: The maximum number of contours within the outline.  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    outline     :: A handle to the new outline.  NULL in case of       */
+  /*                   error.                                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    No.                                                                */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The reason why this function takes a `library' parameter is simply */
+  /*    to use the library's memory allocator.  You can copy the source    */
+  /*    code of this function, replacing allocations with `malloc()' if    */
+  /*    you want to control where the objects go.                          */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_New_Outline( FT_Library   library,
+                            FT_UInt      numPoints,
+                            FT_Int       numContours,
+                            FT_Outline*  outline )
+  {
+    FT_Error   error;
+    FT_Memory  memory;
+
+
+    if ( !outline )
+      return FT_Err_Invalid_Argument;
+
+    *outline = null_outline;
+    memory   = library->memory;
+
+    if ( ALLOC_ARRAY( outline->points,   numPoints * 2L, FT_Pos    ) ||
+         ALLOC_ARRAY( outline->flags,    numPoints,      FT_Byte   ) ||
+         ALLOC_ARRAY( outline->contours, numContours,    FT_UShort ) )
+      goto Fail;
+
+    outline->n_points   = (FT_UShort)numPoints;
+    outline->n_contours = (FT_Short)numContours;
+    outline->owner      = TRUE;
+
+    return FT_Err_Ok;
+
+  Fail:
+    outline->owner = TRUE;
+    FT_Done_Outline( library, outline );
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_Outline                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys an outline created with FT_New_Outline().                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle of the library object used to allocate the     */
+  /*               outline.                                                */
+  /*                                                                       */
+  /*    outline :: A pointer to the outline object to be discarded.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    No.                                                                */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    If the outline's `owner' field is not set, only the outline        */
+  /*    descriptor will be released.                                       */
+  /*                                                                       */
+  /*    The reason why this function takes an `outline' parameter is       */
+  /*    simply to use FT_Alloc()/FT_Free().  You can copy the source code  */
+  /*    of this function, replacing allocations with `malloc()' in your    */
+  /*    application if you want something simpler.                         */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Done_Outline( FT_Library   library,
+                             FT_Outline*  outline )
+  {
+    FT_Memory  memory = library->memory;
+
+
+    if ( outline )
+    {
+      if ( outline->owner )
+      {
+        FREE( outline->points   );
+        FREE( outline->flags    );
+        FREE( outline->contours );
+      }
+      *outline = null_outline;
+
+      return FT_Err_Ok;
+    }
+    else
+      return FT_Err_Invalid_Argument;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Outline_CBox                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns an outline's `control box'.  The control box encloses all  */
+  /*    the outline's points, including Bezier control points.  Though it  */
+  /*    coincides with the exact bounding box for most glyphs, it can be   */
+  /*    slightly larger in some situations (like when rotating an outline  */
+  /*    which contains Bezier outside arcs).                               */
+  /*                                                                       */
+  /*    Computing the control box is very fast, while getting the bounding */
+  /*    box can take much more time as it needs to walk over all segments  */
+  /*    and arcs in the outline.  To get the latter, you can use the       */
+  /*    `ftbbox' component which is dedicated to this single task.         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline :: A pointer to the source outline descriptor.             */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    cbox    :: The outline's control box.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Get_Outline_CBox( FT_Outline*  outline,
+                                 FT_BBox*     cbox )
+  {
+    if ( outline && cbox )
+    {
+      if ( outline->n_points == 0 )
+      {
+        cbox->xMin = 0;
+        cbox->yMin = 0;
+        cbox->xMax = 0;
+        cbox->yMax = 0;
+      }
+      else
+      {
+        FT_UShort   k;
+        FT_Vector*  vec = outline->points;
+
+
+        cbox->xMin = cbox->xMax = vec->x;
+        cbox->yMin = cbox->yMax = vec->y;
+        vec++;
+
+        for ( k = 1; k < outline->n_points; k++ )
+        {
+          FT_Pos  x, y;
+
+
+          x = vec->x;
+          if ( x < cbox->xMin ) cbox->xMin = x;
+          if ( x > cbox->xMax ) cbox->xMax = x;
+
+          y = vec->y;
+          if ( y < cbox->yMin ) cbox->yMin = y;
+          if ( y > cbox->yMax ) cbox->yMax = y;
+          vec++;
+        }
+      }
+      return FT_Err_Ok;
+    }
+    else
+      return FT_Err_Invalid_Argument;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Translate_Outline                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Applies a simple translation to the points of an outline.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline :: A pointer to the target outline descriptor.             */
+  /*    xOffset :: The horizontal offset.                                  */
+  /*    yOffset :: The vertical offset.                                    */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_Translate_Outline( FT_Outline*  outline,
+                              FT_Pos       xOffset,
+                              FT_Pos       yOffset )
+  {
+    FT_UShort   n;
+    FT_Vector*  vec = outline->points;
+
+
+    for ( n = 0; n < outline->n_points; n++ )
+    {
+      vec->x += xOffset;
+      vec->y += yOffset;
+      vec++;
+    }
+  }
+
+
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_FreeType                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given FreeType library object and all of its childs,    */
+  /*    including resources, drivers, faces, sizes, etc.                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to the target library object.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Error  FT_Done_FreeType( FT_Library  library )
+  {
+    /* Discard the library object */
+    FT_Done_Library( library );
+
+    return FT_Err_Ok;
+  }
+
+/* END */
diff --git a/src/base/ftobjs.h b/src/base/ftobjs.h
new file mode 100644
index 0000000..8dc90ec
--- /dev/null
+++ b/src/base/ftobjs.h
@@ -0,0 +1,710 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftobjs.h                                                               */
+/*                                                                         */
+/*  The FreeType private base classes (specification).                     */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  This file contains the definition of all internal FreeType classes.  */
+  /*                                                                       */
+  /*************************************************************************/
+
+#ifndef FTOBJS_H
+#define FTOBJS_H
+
+#include <ftconfig.h>
+#include <ftsystem.h>
+#include <ftdriver.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Some generic definitions.                                             */
+  /*                                                                       */
+#ifndef TRUE
+#define TRUE  1
+#endif
+
+#ifndef FALSE
+#define FALSE  0
+#endif
+
+#ifndef NULL
+#define NULL  (void*)0
+#endif
+
+#ifndef UNUSED
+#define UNUSED( arg )  ( (void)(arg) )
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The min and max functions missing in C.  As usual, be careful not to  */
+  /* write things like MIN( a++, b++ ) to avoid side effects.              */
+  /*                                                                       */
+#ifndef MIN
+#define MIN( a, b )  ( (a) < (b) ? (a) : (b) )
+#endif
+
+#ifndef MAX
+#define MAX( a, b )  ( (a) > (b) ? (a) : (b) )
+#endif
+
+#ifndef ABS
+#define ABS( a )     ( (a) < 0 ? -(a) : (a) )
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_SET_ERROR                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This macro is used to set an implicit `error' variable to a given  */
+  /*    expression's value (usually a function call), and convert it to a  */
+  /*    boolean which is set whenever the value is != 0.                   */
+  /*                                                                       */
+#undef  FT_SET_ERROR
+#define FT_SET_ERROR( expression ) \
+          ( (error = (expression)) != 0 )
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                           M E M O R Y                           ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Alloc                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Allocates a new block of memory.  The returned area is always      */
+  /*    zero-filled, this is a strong convention in many FreeType parts.   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to a given `memory object' where allocation     */
+  /*              occurs.                                                  */
+  /*                                                                       */
+  /*    size   :: The size in bytes of the block to allocate.              */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+  /*              NULL if `size' is 0, or in case of error.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  BASE_DEF
+  FT_Error  FT_Alloc( FT_Memory  memory,
+                      FT_Long    size,
+                      void**     P );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Realloc                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Reallocates a block of memory pointed to by `*P' to `Size' bytes   */
+  /*    from the heap, possibly changing `*P'.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to a given `memory object' where allocation     */
+  /*              occurs.                                                  */
+  /*                                                                       */
+  /*    current :: current block size in bytes                             */
+  /*    size    :: the new block size in bytes                              */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    P      :: A pointer to the fresh new block.  It should be set to   */
+  /*              NULL if `size' is 0, or in case of error.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    All callers of FT_Realloc _must_ provide the current block size    */
+  /*    as well as the new one.                                            */
+  /*                                                                       */
+  /*    When the memory object's flag FT_memory_FLAG_NO_REALLOC is         */
+  /*    set, this function will try to emulate a realloc through uses      */
+  /*    of FT_Alloc and FT_Free. Otherwise, it will call the memory-       */
+  /*    specific "realloc" implementation.                                 */
+  /*                                                                       */
+  /*    (Some embedded memorys do not have a working realloc).             */
+  /*                                                                       */
+  BASE_DEF
+  FT_Error  FT_Realloc( FT_Memory  memory,
+                        FT_Long    current,
+                        FT_Long    size,
+                        void**     P );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Free                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given block of memory allocated through FT_Alloc().     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to a given `memory object' where allocation     */
+  /*              occured.                                                 */
+  /*                                                                       */
+  /*    P      :: This is the _address_ of a _pointer_ which points to the */
+  /*              allocated block.  It is always set to NULL on exit.      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    If P or *P are NULL, this function should return successfully.     */
+  /*    This is a strong convention within all of FreeType and its         */
+  /*    drivers.                                                           */
+  /*                                                                       */
+  BASE_DEF
+  void  FT_Free( FT_Memory  memory,
+                 void**     P );
+
+
+
+  /* This include is needed by the MEM_xxx() macros, it should be */
+  /* available on every platform we know !!                       */
+#include <string.h>
+
+#define MEM_Set( dest, byte, count )  memset( dest, byte, count )
+
+#ifdef HAVE_MEMCPY
+#define MEM_Copy( dest, source, count )  memcpy( dest, source, count )
+#else
+#define MEM_Copy( dest, source, count )  bcopy( source, dest, count )
+#endif
+
+#define MEM_Move( dest, source, count )  memmove( dest, source, count )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* We now support closures to produce completely reentrant code.  This   */
+  /* means the allocation functions now takes an additional argument       */
+  /* (`memory').  It is a handle to a given memory object, responsible for */
+  /* all low-level operations, including memory management and             */
+  /* synchronisation.                                                      */
+  /*                                                                       */
+  /* In order to keep our code readable and use the same macros in the     */
+  /* font drivers and the rest of the library, MEM_Alloc(), ALLOC(), and   */
+  /* ALLOC_ARRAY() now use an implicit variable, `memory'.  It must be     */
+  /* defined at all locations where a memory operation is queried.         */
+  /*                                                                       */
+
+  /*                                                                       */
+  /* Note that ALL memory allocation functions need an IMPLICIT argument   */
+  /* called `memory' to point to the current memory object.                */
+  /*                                                                       */
+#define MEM_Alloc( _pointer_, _size_ ) \
+          FT_Alloc( memory, _size_, (void**)&(_pointer_) )
+
+#define MEM_Realloc( _pointer_, _current_, _size_ ) \
+          FT_Realloc( memory, _current_, _size_, (void**)&(_pointer_) )
+
+#define ALLOC( _pointer_, _size_ ) \
+          FT_SET_ERROR( MEM_Alloc( _pointer_, _size_ ) )
+
+#define REALLOC( _pointer_, _current_, _size_ ) \
+          FT_SET_ERROR( MEM_Realloc( _pointer_, _current_, _size_ ) )
+
+#define ALLOC_ARRAY( _pointer_, _count_, _type_ ) \
+          FT_SET_ERROR( MEM_Alloc( _pointer_, (_count_)*sizeof (_type_) ) )
+
+#define REALLOC_ARRAY( _pointer_, _current_, _count_, _type_ ) \
+          FT_SET_ERROR( MEM_Realloc( _pointer_, (_current_)*sizeof(_type_), \
+                         (_count_)*sizeof(_type_) ) )
+
+#define FREE( _pointer_ )  FT_Free( memory, (void**)&(_pointer_) )
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                         D R I V E R S                           ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_DriverRec                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The root font driver class.  A font driver is responsible for      */
+  /*    managing and loading font files of a given format.                 */
+  /*                                                                       */
+  /*  <Fields>                                                             */
+  /*     library     :: A handle to the driver's parent library.           */
+  /*                                                                       */
+  /*     memory      :: A handle to the driver's memory object.  This is a */
+  /*                    duplicate of `library->memory'.                    */
+  /*                                                                       */
+  /*     interface   :: A set of driver methods that implement its         */
+  /*                    behaviour.  These methods are called by the        */
+  /*                    various FreeType functions like FT_New_Face(),     */
+  /*                    FT_Load_Glyph(), etc.                              */
+  /*                                                                       */
+  /*     format      :: A typeless pointer, used to store the address of   */
+  /*                    the driver's format specific interface.  This is a */
+  /*                    table of other driver methods that are specific to */
+  /*                    its format.  Format specific interfaces are        */
+  /*                    defined in the driver's header files (e.g.,        */
+  /*                    `freetype/drivers/ttlib/ttdriver.h').              */
+  /*                                                                       */
+  /*     version     :: The driver's version.  It can be used for          */
+  /*                    versioning and dynamic driver update if needed.    */
+  /*                                                                       */
+  /*     description :: An ASCII string describing the driver's supported  */
+  /*                    format, like `truetype', `type1', etc.             */
+  /*                                                                       */
+  /*     faces_list  :: The list of faces currently opened by this driver. */
+  /*                                                                       */
+  /*     extensions  :: a typeless pointer to the driver's extensions      */
+  /*                    registry, when they are supported through the      */
+  /*                    config macro FT_CONFIG_OPTION_EXTENSIONS           */
+  /*                                                                       */
+  typedef struct  FT_DriverRec_
+  {
+    FT_Library          library;
+    FT_Memory           memory;
+
+    FT_Generic          generic;
+
+    FT_DriverInterface  interface;
+    FT_FormatInterface  format;
+
+    FT_Int              version;      /* driver version     */
+    FT_String*          description;  /* format description */
+
+    FT_ListRec          faces_list;   /* driver's faces list    */
+
+    void*               extensions;
+
+  } FT_DriverRec;
+
+
+#ifdef FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                     G L Y P H   F O R M A T S                   ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+ /*************************************************************************
+  *
+  * <Struct>
+  *   FT_Glyph_Format
+  *
+  * <Description>
+  *   A structure used to model various properties of a non-standard   
+  *   glyph image format.
+  *
+  * <Fields>
+  *   format_tag        :: the glyph format tag
+  *
+  *   raster_interface  :: the default rasters interface for this glyph
+  *                        format.
+  *
+  *   raster            :: the default raster object for this glyph format
+  *                        if set to nil, a new object will be allocated
+  *                        automatically through the raster interface.
+  *
+  *   raster_owned      :: a boolean used internally by the library. If
+  *                        set, if indicates that the current raster object
+  *                        was allocated by the library.
+  *
+  *************************************************************************/
+  
+  typedef struct FT_Glyph_Format_
+  {
+    FT_Glyph_Tag           format_tag;
+    FT_Raster_Interface*   raster_interface;
+    FT_Raster              raster;
+    FT_Bool                raster_allocated;
+  
+  } FT_Glyph_Format;
+
+
+ /*************************************************************************
+  *
+  * <Function>
+  *   FT_Add_Glyph_Format
+  *
+  * <Description>
+  *   Register a new glyph format into the library
+  *
+  * <Input>
+  *   library   :: handle to target library object
+  *   interface :: pointer to glyph format interface
+  *
+  * <Return>
+  *   Error code. 0 means success
+  *
+  * <Note>
+  *   This function should normally be called by those font drivers which
+  *   need to use their own glyph image format.
+  *
+  *************************************************************************/
+  
+  EXPORT_DEF
+  FT_Error  FT_Add_Glyph_Format( FT_Library        library,
+                                 FT_Glyph_Format*  format );
+
+
+ /*************************************************************************
+  *
+  * <Function>
+  *   FT_Remove_Glyph_Format
+  *
+  * <Description>
+  *   Un-Register a given glyph format from the library
+  *
+  * <Input>
+  *   library      :: handle to target library object
+  *   glyph_format :: glyph format tag
+  *
+  * <Return>
+  *   Error code. 0 means success
+  *
+  * <Note>
+  *   This function should normally be called by those font drivers which
+  *   need to use their own glyph image format.
+  *
+  *************************************************************************/
+  
+  EXPORT_DEF
+  FT_Error  FT_Remove_Glyph_Format( FT_Library     library,
+                                    FT_Glyph_Tag   glyph_format );
+
+ /*************************************************************************
+  *
+  * <Function>
+  *   FT_Get_Glyph_Format
+  *
+  * <Description>
+  *   Return a pointer to the glyph format descriptor corresponding to
+  *   a given format tag.
+  *
+  * <Input>
+  *   library    :: handle to source library object
+  *
+  *   format_tag :: glyph format tag
+  *
+  * <Return>
+  *   a pointer to the corresponding glyph format descriptor, if it was
+  *   registered in the library. 0 otherwise.
+  *
+  *************************************************************************/
+  
+  BASE_DEF
+  FT_Glyph_Format*  FT_Get_Glyph_Format( FT_Library    library,
+                                         FT_Glyph_Tag  format_tag );
+
+
+
+#endif /* FT_CONFIG_OPTION_ALTERNATE_GLYPH_FORMATS */
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                       L I B R A R I E S                         ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+#define FT_DEBUG_HOOK_TRUETYPE   0
+#define FT_DEBUG_HOOK_TYPE1      1
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_LibraryRec                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The FreeType library class.  This is the root of all FreeType      */
+  /*    data.  Use FT_New_Library() to create a library object, and        */
+  /*    FT_Done_Library() to discard it and all child objects.             */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    memory         :: The library's memory object.  Manages memory     */
+  /*                      allocation                                       */
+  /*                                                                       */
+  /*    generic        :: Client data variable.  Used to extend the        */
+  /*                      Library class by higher levels and clients.      */
+  /*                                                                       */
+  /*    num_drivers    :: The number of drivers currently registered       */
+  /*                      within this library.  This is set to 0 for new   */
+  /*                      libraries.  New drivers are added through the    */
+  /*                      FT_Add_Driver() API function.                    */
+  /*                                                                       */
+  /*    drivers        :: A table used to store handles to the currently   */
+  /*                      registered font drivers.  Note that each driver  */
+  /*                      contains a list of its opened faces.             */
+  /*                                                                       */
+  /*    glyph_formats  :: A table used to store glyph format descriptors   */
+  /*                      for new image formats that may have been         */
+  /*                      registered within the library                    */
+  /*                                                                       */
+  /*    raster_pool    :: The raster object's render pool.  This can       */
+  /*                      ideally be changed dynamically at run-time.      */
+  /*                                                                       */
+  typedef  void  (*FT_DebugHook_Func)( void* arg );
+  
+  typedef struct  FT_LibraryRec_
+  {
+    FT_Memory           memory;         /* library's memory object          */
+
+    FT_Generic          generic;
+
+    FT_Int              num_drivers;
+    FT_Driver           drivers[ FT_MAX_DRIVERS ];  /* driver objects  */
+
+    FT_Glyph_Format     glyph_formats[FT_MAX_GLYPH_FORMATS];
+
+    void*               raster_pool;    /* scan-line conversion render pool */
+
+    FT_DebugHook_Func   debug_hooks[4];
+
+  } FT_LibraryRec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Library                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used to create a new FreeType library instance    */
+  /*    from a given memory object.  It is thus possible to use libraries  */
+  /*    with distinct memory allocators within the same program.           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory  :: A handle to the original memory object.                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    library :: A handle to a new library object.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function is normally not called by client applications,       */
+  /*    unless they want to create a specific instance of FreeType which   */
+  /*    uses a specific memory allocator.                                  */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_New_Library( FT_Memory    memory,
+                            FT_Library*  library );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Done_Library                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards a given library object.  This closes all drivers and      */
+  /*    discards all face objects.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to the target library.                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Done_Library( FT_Library  library );
+
+
+
+  EXPORT_DEF
+  void  FT_Set_Debug_Hook( FT_Library         library,
+                           FT_UInt            hook_index,
+                           FT_DebugHook_Func  debug_hook );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Add_Driver                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Registers a new driver in a given library object.  This function   */
+  /*    takes only a pointer to a driver interface.  It uses it to create  */
+  /*    the new driver, then sets up some important fields.                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library          :: A handle to the target library object.         */
+  /*                                                                       */
+  /*    driver_interface :: A pointer to a driver interface table.         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function doesn't check whether the driver is already          */
+  /*    installed!                                                         */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Add_Driver( FT_Library                 library,
+                           const FT_DriverInterface*  driver_interface );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Remove_Driver                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Unregister a given driver.  This closes the driver, which in turn  */
+  /*    destroys all faces, sizes, slots, etc. associated with it.         */
+  /*                                                                       */
+  /*    This function also DESTROYS the driver object.                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver :: A handle to target driver object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Remove_Driver( FT_Driver  driver );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Driver                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    returns the handle of the driver responsible for a given format    */
+  /*    (or service) according to its `name'.                              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library     :: handle to library object.                           */
+  /*    driver_name :: name of driver to look-up.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    handle to driver object. 0 otherwise                               */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Driver  FT_Get_Driver( FT_Library  library,
+                            char*       driver_name );
+
+#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
+
+ /**************************************************************************
+  *
+  * <Function>
+  *   FT_New_Stream
+  *
+  * <Description>
+  *   Open a new stream from a given standard ASCII file path name
+  *
+  * <Input>
+  *   filepathname  :: an ASCII string naming the file to be opened
+  * 
+  * <Output>
+  *   astream :: the opened stream descriptor to be used by the library
+  *
+  * <Return>
+  *   Error code. 0 means success
+  *
+  * <Note>
+  *   This function must be implemented by the system-specific part
+  *   of the engine, i.e. `ftsystem.c'.
+  *
+  *   This function should only fill the stream descriptor. Note that
+  *   the stream's `memory' field should be left to the caller.
+  *
+  **************************************************************************/
+  
+  extern
+  FT_Error  FT_New_Stream( const char*  filepathname,
+                           FT_Stream    astream );
+
+
+ /**************************************************************************
+  *
+  * <Function>
+  *   FT_New_Memory
+  *
+  * <Description>
+  *   Returns a handle to a new memory object
+  *
+  * <Return>
+  *   Handle to the memory object. 0 means failure
+  *
+  * <Note>
+  *   This function must be implemented by the system-specific part
+  *   of the engine, i.e. `ftsystem.c'.
+  *
+  *   It is only used by `ftinit' in order to implement the function
+  *   FT_Init_FreeType.
+  *
+  **************************************************************************/
+  
+  extern
+  FT_Memory  FT_New_Memory( void );
+
+#endif
+
+/* Define default raster's interface. The default raster is located in `src/base/ftraster.c' */
+/*                                                                                           */
+/* Client applications can register new rasters through the FT_Set_Raster API..              */
+/*                                                                                           */
+#ifndef FT_NO_DEFAULT_RASTER
+  extern
+  FT_Raster_Interface  ft_default_raster;
+#endif
+
+
+#endif /* FTOBJS_H */
+
+
+/* END */
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
new file mode 100644
index 0000000..f6f9160
--- /dev/null
+++ b/src/base/ftoutln.c
@@ -0,0 +1,286 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftoutln.c                                                              */
+/*                                                                         */
+/*    FreeType outline management (body).                                  */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* All functions are declared in freetype.h.                             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include <freetype.h>
+#include <ftconfig.h>
+#include <ftobjs.h>
+#include <ftimage.h>
+#include <ftoutln.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Copy_Outline                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Copies an outline into another one.  Both objects must have the    */
+  /*    same sizes (number of points & number of contours) when this       */
+  /*    function is called.                                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    source :: A handle to the source outline.                          */
+  /*    target :: A handle to the target outline.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Copy_Outline( FT_Outline*  source,
+                             FT_Outline*  target )
+  {
+    if ( !source            || !target            ||
+         source->n_points   != target->n_points   ||
+         source->n_contours != target->n_contours )
+      return FT_Err_Invalid_Argument;
+
+    MEM_Copy( target->points, source->points,
+              source->n_points * 2 * sizeof ( FT_Pos ) );
+
+    MEM_Copy( target->flags, source->flags,
+              source->n_points * sizeof ( FT_Byte ) );
+
+    MEM_Copy( target->contours, source->contours,
+              source->n_contours * sizeof ( FT_Short ) );
+
+    target->high_precision = source->high_precision;
+    target->second_pass    = target->second_pass;
+    target->dropout_mode   = source->dropout_mode;
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Outline_Bitmap                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Renders an outline within a bitmap.  The outline's image is simply */
+  /*    or-ed to the target bitmap.                                        */
+  /*                                                                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to a FreeType library object.                  */
+  /*    outline :: A pointer to the source outline descriptor.             */
+  /*    map     :: A pointer to the target bitmap descriptor.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    YES.  Rendering is synchronized, so that concurrent calls to the   */
+  /*    scan-line converter will be serialized.                            */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function does NOT CREATE the bitmap, it only renders an       */
+  /*    outline image within the one you pass to it!                       */
+  /*                                                                       */
+  /*    It will use the raster correponding to the default glyph format.   */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Get_Outline_Bitmap( FT_Library   library,
+                                   FT_Outline*  outline,
+                                   FT_Bitmap*   map )
+  {
+    FT_Error          error;
+    FT_Glyph_Format*  format;
+    
+    error  = FT_Err_Invalid_Glyph_Format;
+    format = FT_Get_Glyph_Format( library, ft_glyph_format_outline );
+    if (!format) goto Exit;
+    
+    error = FT_Err_Invalid_Glyph_Format;
+    if (!format->raster) goto Exit;
+
+    error = format->raster_interface->render( format->raster, outline, map );
+  Exit:
+    return error; 
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Transform_Outline                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Applies a simple 2x2 matrix to all of an outline's points.  Useful */
+  /*    for applying rotations, slanting, flipping, etc.                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline :: A pointer to the target outline descriptor.             */
+  /*    matrix  :: A pointer to the transformation matrix.                 */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    You can use FT_Translate_Outline() if you need to translate the    */
+  /*    outline's points.                                                  */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_Transform_Outline( FT_Outline*  outline,
+                              FT_Matrix*   matrix )
+  {
+    FT_UShort   n;
+    FT_Vector*  vec;
+
+
+    vec = outline->points;
+    for ( n = 0; n < outline->n_points; n++ )
+    {
+      FT_Pos  x, y;
+
+
+      x = FT_MulFix( vec->x, matrix->xx ) +
+          FT_MulFix( vec->y, matrix->xy );
+
+      y = FT_MulFix( vec->x, matrix->yx ) +
+          FT_MulFix( vec->y, matrix->yy );
+
+      vec->x = x;
+      vec->y = y;
+      vec++;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Transform_Vector                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Transforms a single vector through a 2x2 matrix.                   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    x      :: The horizontal vector coordinate.                        */
+  /*    y      :: The vertical vector coordinate.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    matrix :: A pointer to the source 2x2 matrix.                      */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_Transform_Vector( FT_Pos*     x,
+                             FT_Pos*     y,
+                             FT_Matrix*  matrix )
+  {
+    FT_Pos xz, yz;
+
+
+    xz = FT_MulFix( *x, matrix->xx ) +
+         FT_MulFix( *y, matrix->xy );
+
+    yz = FT_MulFix( *x, matrix->yx ) +
+         FT_MulFix( *y, matrix->yy );
+
+    *x = xz;
+    *y = yz;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Matrix_Multiply                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Performs the matrix operation `b = a*b'.                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: A pointer to matrix `a'.                                      */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    b :: A pointer to matrix `b'.                                      */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  BASE_FUNC
+  void  FT_Matrix_Multiply( FT_Matrix*  a,
+                            FT_Matrix*  b )
+  {
+    FT_Fixed  xx, xy, yx, yy;
+
+
+    xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );
+    xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );
+    yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );
+    yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );
+
+    b->xx = xx;  b->xy = xy;
+    b->yx = yx;  b->yy = yy;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Matrix_Invert                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Inverts a 2x2 matrix.  Returns an error if it can't be inverted.   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    matrix :: A pointer to the target matrix.  Remains untouched in    */
+  /*              case of error.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  BASE_FUNC
+  FT_Error  FT_Matrix_Invert( FT_Matrix*  matrix )
+  {
+    FT_Pos  delta, xx, yy;
+
+
+    /* compute discriminant */
+    delta = FT_MulFix( matrix->xx, matrix->yy ) -
+            FT_MulFix( matrix->xy, matrix->yx );
+
+    if ( !delta )
+      return FT_Err_Invalid_Argument;  /* matrix can't be inverted */
+
+    matrix->xy = - FT_DivFix( matrix->xy, delta );
+    matrix->yx = - FT_DivFix( matrix->yx, delta );
+
+    xx = matrix->xx;
+    yy = matrix->yy;
+
+    matrix->xx = FT_DivFix( yy, delta );
+    matrix->yy = FT_DivFix( xx, delta );
+
+    return FT_Err_Ok;
+  }
+
+
+/* END */
diff --git a/src/base/ftoutln.h b/src/base/ftoutln.h
new file mode 100644
index 0000000..c8ce7cc
--- /dev/null
+++ b/src/base/ftoutln.h
@@ -0,0 +1,153 @@
+#ifndef FTOUTLN_H
+#define FTOUTLN_H
+
+#include <ftobjs.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Copy_Outline                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Copies an outline into another one.  Both objects must have the    */
+  /*    same sizes (number of points & number of contours) when this       */
+  /*    function is called.                                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    source :: A handle to the source outline.                          */
+  /*    target :: A handle to the target outline.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Copy_Outline( FT_Outline*  source,
+                             FT_Outline*  target );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Outline_Bitmap                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Renders an outline within a bitmap.  The outline's image is simply */
+  /*    or-ed to the target bitmap.                                        */
+  /*                                                                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library :: A handle to a FreeType library object.                  */
+  /*    outline :: A pointer to the source outline descriptor.             */
+  /*    map     :: A pointer to the target bitmap descriptor.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    YES.  Rendering is synchronized, so that concurrent calls to the   */
+  /*    scan-line converter will be serialized.                            */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function does NOT CREATE the bitmap, it only renders an       */
+  /*    outline image within the one you pass to it!                       */
+  /*                                                                       */
+  /*    It will use the raster correponding to the default glyph format.   */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Get_Outline_Bitmap( FT_Library   library,
+                                   FT_Outline*  outline,
+                                   FT_Bitmap*   map );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Transform_Outline                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Applies a simple 2x2 matrix to all of an outline's points.  Useful */
+  /*    for applying rotations, slanting, flipping, etc.                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline :: A pointer to the target outline descriptor.             */
+  /*    matrix  :: A pointer to the transformation matrix.                 */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    You can use FT_Translate_Outline() if you need to translate the    */
+  /*    outline's points.                                                  */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_Transform_Outline( FT_Outline*  outline,
+                              FT_Matrix*   matrix );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Transform_Vector                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Transforms a single vector through a 2x2 matrix.                   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    x      :: The horizontal vector coordinate.                        */
+  /*    y      :: The vertical vector coordinate.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    matrix :: A pointer to the source 2x2 matrix.                      */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_Transform_Vector( FT_Pos*     x,
+                             FT_Pos*     y,
+                             FT_Matrix*  matrix );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Matrix_Multiply                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Performs the matrix operation `b = a*b'.                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    a :: A pointer to matrix `a'.                                      */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    b :: A pointer to matrix `b'.                                      */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  EXPORT_DEF
+  void  FT_Matrix_Multiply( FT_Matrix*  a,
+                            FT_Matrix*  b );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Matrix_Invert                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Inverts a 2x2 matrix.  Returns an error if it can't be inverted.   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    matrix :: A pointer to the target matrix.  Remains untouched in    */
+  /*              case of error.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  EXPORT_DEF
+  FT_Error  FT_Matrix_Invert( FT_Matrix*  matrix );
+
+#endif /* FTOUTLN_H */
diff --git a/src/base/ftraster.c b/src/base/ftraster.c
new file mode 100644
index 0000000..abf78f3
--- /dev/null
+++ b/src/base/ftraster.c
@@ -0,0 +1,4372 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftraster2.c                                                            */
+/*                                                                         */
+/*    The FreeType glyph rasterizer (body).                                */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The `raster' component implements FreeType's scan-line converter, the */
+  /* one used to generate bitmaps and pixmaps from vectorial outline       */
+  /* descriptions.                                                         */
+  /*                                                                       */
+  /* It has been rewritten entirely for FreeType 2.0, in order to become   */
+  /* completely independent of the rest of the library.  It should now be  */
+  /* possible to include it more easily in all kinds of libraries and      */
+  /* applications, which do not necessarily need the font engines and API. */
+  /*                                                                       */
+  /* This version contains the following features:                         */
+  /*                                                                       */
+  /* - Support for third-order Bezier arcs.                                */
+  /*                                                                       */
+  /* - Improved performance of the 5-levels anti-aliasing algorithm.       */
+  /*                                                                       */
+  /* - 17-levels anti-aliasing for smoother curves, though the difference  */
+  /*   isn't always noticeable, depending on your palette.                 */
+  /*                                                                       */
+  /* - An API to decompose a raster outline into a path (i.e., into a      */
+  /*   a series of segments and arcs).                                     */
+  /*                                                                       */
+  /* Planned additions:                                                    */
+  /*                                                                       */
+  /* - Getting rid of the second pass for horizontal drop-out detection.   */
+  /*   I've got a few ideas, but I'll have to experiment in Pascal with    */
+  /*   them.  to avoid damaging of the rendering of glyphs at small sizes. */
+  /*                                                                       */
+  /* - Adding a `composition' callback, which should be invoked during     */
+  /*   anti-aliased rendering.  In short, it will allow line-by-line       */
+  /*   composition (i.e., transparencies, etc.) of the output in a fairly  */
+  /*   portable way.  Of course, a single sweep is required there.         */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include <ftimage.h>
+#ifndef _STANDALONE_
+#include <ftconfig.h>
+#endif
+
+#ifndef EXPORT_FUNC
+#define EXPORT_FUNC  /* nothing */
+#endif
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_raster
+
+#ifdef _STANDALONE_
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The following defines are used when the raster is compiled as a       */
+  /* stand-alone object.  Each of them is commented, and you're free to    */
+  /* toggle them to suit your needs.                                       */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_RASTER_INT_IS_32                                                   */
+  /*                                                                       */
+  /*   Set this configuration macro to the unsigned type which has 32      */
+  /*   bits.                                                               */
+  /*                                                                       */
+#define FT_RASTER_INT_IS_32
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_RASTER_OPTION_ANTI_ALIAS                                           */
+  /*                                                                       */
+  /*   Define this configuration macro if you want to support              */
+  /*   anti-aliasing.                                                      */
+  /*                                                                       */
+#define FT_RASTER_OPTION_ANTI_ALIAS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_RASTER_OPTION_CONIC_BEZIERS                                        */
+  /*                                                                       */
+  /*   Define this configuration macro if your source outlines contain     */
+  /*   second-order Bezier arcs.  Typically, these are TrueType outlines.  */
+  /*                                                                       */
+#define FT_RASTER_CONIC_BEZIERS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_RASTER_OPTION_CUBIC_BEZIERS                                        */
+  /*                                                                       */
+  /*   Define this configuration macro if your source outlines contain     */
+  /*   third-order Bezier arcs.  Typically, these are Type1 outlines.      */
+  /*                                                                       */
+#define FT_RASTER_CUBIC_BEZIERS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_RASTER_ANTI_ALIAS_5                                                */
+  /*                                                                       */
+  /*   Define this configuration macro if you want to enable the 5-grays   */
+  /*   anti-aliasing mode.  Ignored if FT_RASTER_OPTION_ANTI_ALIAS isn't   */
+  /*   defined.                                                            */
+  /*                                                                       */
+#define FT_RASTER_ANTI_ALIAS_5
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_RASTER_ANTI_ALIAS_17                                               */
+  /*                                                                       */
+  /*   Define this configuration macro if you want to enable the 17-grays  */
+  /*   anti-aliasing mode.  Ignored if FT_RASTER_OPTION_ANTI_ALIAS isn't   */
+  /*   defined.                                                            */
+  /*                                                                       */
+/* #define FT_RASTER_ANTI_ALIAS_17 */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_RASTER_LITTLE_ENDIAN                                               */
+  /* FT_RASTER_BIG_ENDIAN                                                  */
+  /*                                                                       */
+  /*   The default anti-alias routines are processor-independent, but      */
+  /*   slow.  Define one of these macros to suit your own system, and      */
+  /*   enjoy greatly improved rendering speed.                             */
+  /*                                                                       */
+
+/* #define FT_RASTER_LITTLE_ENDIAN */
+/* #define FT_RASTER_BIG_ENDIAN    */
+
+
+#else /* _STANDALONE_ */
+
+#include <freetype.h>
+#include <ftconfig.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The following defines are used when the raster is compiled within the */
+  /* FreeType base layer.  Don't change these unless you really know what  */
+  /* you're doing.                                                         */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifdef FT_CONFIG_OPTION_ANTI_ALIAS
+#define FT_RASTER_OPTION_ANTI_ALIAS
+#endif
+
+#define FT_RASTER_CONIC_BEZIERS
+#define FT_RASTER_CUBIC_BEZIERS
+
+#define FT_RASTER_ANTI_ALIAS_5
+/* #define  FT_RASTER_ANTI_ALIAS_17 */
+
+#ifdef FT_CONFIG_OPTION_LITTLE_ENDIAN
+#define FT_RASTER_LITTLE_ENDIAN
+#endif
+
+#ifdef FT_CONFIG_OPTION_BIG_ENDIAN
+#define FT_RASTER_BIG_ENDIAN
+#endif
+
+
+#endif /* _STANDALONE_ */
+
+
+/* to keep the compiler happy */
+#ifndef PTRACE2
+#define PTRACE2(x)  /*void*/
+#endif
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FT_RASTER_ANY_ENDIAN indicates that no endianess was defined by one   */
+  /* of the configuration macros.                                          */
+  /*                                                                       */
+#if !defined( FT_RASTER_LITTLE_ENDIAN ) && !defined( FT_RASTER_BIG_ENDIAN )
+#define FT_RASTER_ANY_ENDIAN
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The rasterizer is a very general purpose component.  Please leave the */
+  /* following redefinitions here (you never know your target              */
+  /* environment).                                                         */
+  /*                                                                       */
+  /*************************************************************************/
+
+#ifndef TRUE
+#define TRUE   1
+#endif
+
+#ifndef FALSE
+#define FALSE  0
+#endif
+
+#ifndef NULL
+#define NULL  (void*)0
+#endif
+
+
+#ifndef UNUSED
+#define UNUSED( arg )  ( (void)(arg) )
+#endif
+
+
+#undef  FAILURE
+#define FAILURE  TRUE
+
+#undef  SUCCESS
+#define SUCCESS  FALSE
+
+#ifndef ABS
+#define ABS(x)  ( (x) < 0 ? -(x) : (x) )
+#endif
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Please don't touch the following macros. Their importance is          */
+  /* historical to FreeType, but they have some nice effects, like getting */
+  /* rid of all `->' symbols when accessing the raster object (replacing   */
+  /* them with a simple `.').                                              */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /* used in function signatures to define the _first_ argument */
+#define RAS_ARG_  FT_Raster  raster,
+#define RAS_ARG   FT_Raster  raster
+
+  /* used to call a function within this component, first parameter */
+#define RAS_VAR_  raster,
+#define RAS_VAR   raster
+
+  /* used to access the current raster object, with a `.' instead of a */
+  /* `->'                                                              */
+#define ras       (*raster)
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* For anti-aliasing modes, we use a 2 or 4 lines intermediate bitmap    */
+  /* which is filtered repeatedly to render each pixmap row.  The          */
+  /* following macro defines this buffer's size in bytes (which is part of */
+  /* raster objects).                                                      */
+  /*                                                                       */
+#define ANTI_ALIAS_BUFFER_SIZE  2048
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Error codes returned by the scan-line converter/raster.               */
+  /*                                                                       */
+#define ErrRaster_Ok                     0
+#define ErrRaster_Uninitialized_Object   1
+#define ErrRaster_Overflow               2
+#define ErrRaster_Negative_Height        3
+#define ErrRaster_Invalid_Outline        4
+#define ErrRaster_Invalid_Map            5
+#define ErrRaster_AntiAlias_Unsupported  6
+#define ErrRaster_Invalid_Pool           7
+#define ErrRaster_Unimplemented          8
+#define ErrRaster_Bad_Palette_Count      9
+
+
+#define Flow_Up     1
+#define Flow_Down  -1
+
+#define SET_High_Precision( p )  Set_High_Precision( RAS_VAR_  p )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Fast MulDiv, as `b' is always < 64.  Don't use intermediate           */
+  /* precision.                                                            */
+  /*                                                                       */
+#define FMulDiv( a, b, c )  ( (a) * (b) / (c) )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define DEBUG_RASTER if you want to generate a debug version of the    */
+  /* rasterizer.  This will progressively draw the glyphs while all the    */
+  /* computation are done directly on the graphics screen (the glyphs will */
+  /* will be shown inverted).                                              */
+  /*                                                                       */
+  /* Note that DEBUG_RASTER should only be used for debugging with b/w     */
+  /* rendering, not with gray levels.                                      */
+  /*                                                                       */
+  /* The definition of DEBUG_RASTER should appear in the file              */
+  /* `ftconfig.h'.                                                         */
+  /*                                                                       */
+#ifdef DEBUG_RASTER
+  extern char*  vio;  /* A pointer to VRAM or display buffer */
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The maximum number of stacked Bezier curves.  Setting this constant   */
+  /* to more than 32 is a pure waste of space.                             */
+  /*                                                                       */
+#define MaxBezier  32
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The number fractional bits of *input* coordinates.  We always use the */
+  /* 26.6 format (i.e, 6 bits for the fractional part), but hackers are    */
+  /* free to experiment with different values.                             */
+  /*                                                                       */
+#define Pixel_Bits  6
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* An unsigned type that is exactly 32 bits on your platform.  This      */
+  /* means `unsigned long' on 16-bit machines, and `unsigned int' on       */
+  /* others.                                                               */
+  /*                                                                       */
+#ifdef _STANDALONE_
+#if defined( FT_RASTER_INT_IS_32 )
+  typedef unsigned int   FT_Word32;
+#elif defined( FT_RASTER_LONG_IS_32 )
+  typedef unsigned long  FT_Word32;
+#else
+#error "no 32bit type found - please check your configuration"
+#endif
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* A pointer to an unsigned char.                                        */
+  /*                                                                       */
+  typedef unsigned char*  PByte;
+
+  typedef char  TResult;
+
+  typedef unsigned char   Byte;
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The type of the pixel coordinates used within the render pool during  */
+  /* scan-line conversion.  We use longs to store either 26.6 or 22.10     */
+  /* fixed float values, depending on the `precision' we want to use       */
+  /* (i.e., low resp. high precision).  These are ideals in order to       */
+  /* subdivise Bezier arcs in halves by simple additions and shifts.       */
+  /*                                                                       */
+  /* Note that this is an 8-bytes integer on 64 bits systems.              */
+  /*                                                                       */
+  typedef long  TPos, *PPos;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The type of a scanline position/coordinate within a map.              */
+  /*                                                                       */
+  typedef int  TScan, *PScan;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* States and directions of each line, arc, and profile.                 */
+  /*                                                                       */
+  typedef enum  _TDirection
+  {
+    Unknown,
+    Ascending,
+    Descending,
+    Flat
+
+  } TDirection;
+
+
+  struct  _TProfile;
+  typedef struct _TProfile  TProfile;
+  typedef TProfile*         PProfile;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The `master' structure used for decomposing outlines.                 */
+  /*                                                                       */
+  struct  _TProfile
+  {
+    TPos      X;           /* current coordinate during sweep          */
+    PProfile  link;        /* link to next profile - various purpose   */
+    PPos      offset;      /* start of profile's data in render pool   */
+    int       flow;        /* Profile orientation: Asc/Descending      */
+    TScan     height;      /* profile's height in scanlines            */
+    TScan     start;       /* profile's starting scanline              */
+
+    TScan     countL;      /* number of lines to step before this      */
+                           /* profile becomes drawable                 */
+
+    PProfile  next;        /* next profile in same contour, used       */
+                           /* during drop-out control                  */
+  };
+
+  typedef PProfile   TProfileList;
+  typedef PProfile*  PProfileList;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* A simple record used to implement a stack of bands, required by the   */
+  /* sub-banding mechanism.                                                */
+  /*                                                                       */
+  typedef struct  _TBand
+  {
+    TScan  y_min;   /* band's minimum */
+    TScan  y_max;   /* band's maximum */
+
+  } TBand;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The size in _TPos_ of a profile record in the render pool.            */
+  /*                                                                       */
+#define AlignProfileSize  \
+          ( (sizeof ( TProfile ) + sizeof ( TPos ) - 1) / sizeof ( TPos ) )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Prototypes used for sweep function dispatch.                          */
+  /*                                                                       */
+  typedef void  (*Function_Sweep_Init)( RAS_ARG_ int*  min,
+                                                 int*  max );
+
+  typedef void  (*Function_Sweep_Span)( RAS_ARG_ TScan  y,
+                                                 TPos   x1,
+                                                 TPos   x2 );
+
+  typedef int   (*Function_Test_Pixel)( RAS_ARG_ TScan  y,
+                                                 int    x );
+
+  typedef void  (*Function_Set_Pixel)( RAS_ARG_  TScan  y,
+                                                 int    x,
+                                                 int    color );
+
+  typedef void  (*Function_Sweep_Step)( RAS_ARG );
+
+  typedef struct Raster_Render_
+  {
+    Function_Sweep_Init  init;
+    Function_Sweep_Span  span;
+    Function_Sweep_Step  step;
+    Function_Test_Pixel  test_pixel;
+    Function_Set_Pixel   set_pixel;
+
+  } Raster_Render;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Compute lowest integer coordinate below a given value.                */
+  /*                                                                       */
+#define FLOOR( x )  ( (x) & ras.precision_mask )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Compute highest integer coordinate above a given value.               */
+  /*                                                                       */
+#define CEILING( x )  ( ((x) + ras.precision - 1) & ras.precision_mask )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Get integer coordinate of a given 26.6 or 22.10 `x' coordinate -- no  */
+  /* rounding.                                                             */
+  /*                                                                       */
+#define TRUNC( x )  ( (signed long)(x) >> ras.precision_bits )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Get the fractional part of a given coordinate.                        */
+  /*                                                                       */
+#define FRAC( x )  ( (x) & (ras.precision - 1) )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Scale an `input coordinate' (as found in FT_Outline structures) into  */
+  /* a `work coordinate' which depends on current resolution and render    */
+  /* mode.                                                                 */
+  /*                                                                       */
+#define SCALED( x )  ( ((x) << ras.scale_shift) - ras.scale_delta )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DEBUG_PSET is used to plot a single pixel in VRam during debug mode.  */
+  /*                                                                       */
+#ifdef DEBUG_RASTER
+#define DEBUG_PSET  Pset()
+#else
+#define DEBUG_PSET
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This structure defines a point in a plane.                            */
+  /*                                                                       */
+  typedef struct  _TPoint
+  {
+    TPos  x, y;
+
+  } TPoint;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The most used variables are at the beginning of the structure.  Thus, */
+  /* their offset can be coded with less opcodes which results in a        */
+  /* smaller executable.                                                   */
+  /*                                                                       */
+  struct  FT_RasterRec_
+  {
+    PPos      cursor;              /* Current cursor in render pool  */
+
+    PPos      pool;                /* The render pool base address   */
+    PPos      pool_size;           /* The render pool's size         */
+    PPos      pool_limit;          /* Limit of profiles zone in pool */
+
+    int       bit_width;           /* target bitmap width  */
+    PByte     bit_buffer;          /* target bitmap buffer */
+    PByte     pix_buffer;          /* target pixmap buffer */
+
+    TPoint    last;
+    long      minY, maxY;
+
+    int       error;
+
+    int       precision_bits;       /* precision related variables */
+    int       precision;
+    int       precision_half;
+    long      precision_mask;
+    int       precision_shift;
+    int       precision_step;
+    int       precision_jitter;
+
+    FT_Outline*  outline;
+
+    int       n_points;             /* number of points in current glyph   */
+    int       n_contours;           /* number of contours in current glyph */
+    int       n_extrema;            /* number of `extrema' scanlines       */
+
+    TPoint*   arc;                  /* current Bezier arc pointer */
+
+    int       num_profs;            /* current number of profiles */
+
+    char      fresh;                /* signals a fresh new profile which */
+                                    /* `start' field must be completed   */
+    char      joint;                /* signals that the last arc ended   */
+                                    /* exactly on a scanline.  Allows    */
+                                    /* removal of doublets               */
+    PProfile  cur_prof;             /* current profile                   */
+    PProfile  start_prof;           /* head of linked list of profiles   */
+    PProfile  first_prof;           /* contour's first profile in case   */
+                                    /* of impact                         */
+    TDirection  state;              /* rendering state */
+
+    FT_Bitmap target;          /* description of target bit/pixmap */
+
+    int       trace_bit;            /* current offset in target bitmap    */
+    int       trace_pix;            /* current offset in target pixmap    */
+    int       trace_incr;           /* sweep's increment in target bitmap */
+
+    int       gray_min_x;           /* current min x during gray rendering */
+    int       gray_max_x;           /* current max x during gray rendering */
+
+    /* dispatch variables */
+
+    Raster_Render     render;
+
+    int       scale_shift;      /* == 0  for bitmaps           */
+                                /* == 1  for 5-levels pixmaps  */
+                                /* == 2  for 17-levels pixmaps */
+
+    int       scale_delta;      /* ras.precision_half for bitmaps */
+                                /* 0 for pixmaps                  */
+
+    char      dropout_mode;     /* current drop_out control method */
+
+    char      second_pass;      /* indicates whether a horizontal pass     */
+                                /* should be performed to control drop-out */
+                                /* accurately when calling Render_Glyph.   */
+                                /* Note that there is no horizontal pass   */
+                                /* during gray rendering.                  */
+
+    char      flipped;          /* this flag is set during the rendering to */
+                                /* indicate the second pass.                */
+
+    TBand     band_stack[16];   /* band stack used for sub-banding */
+    int       band_top;         /* band stack top                  */
+
+    TPoint    arcs[2 * MaxBezier + 1];  /* The Bezier stack */
+
+#if defined( FT_RASTER_OPTION_ANTI_ALIAS )
+
+    long      grays[20];        /* Palette of gray levels used for render */
+
+    int       gray_width;       /* length in bytes of the monochrome       */
+                                /* intermediate scanline of gray_lines.    */
+                                /* Each gray pixel takes 2 or 4 bits long  */
+
+                        /* The gray_lines must hold 2 lines, thus with size */
+                        /* in bytes of at least `gray_width*2'              */
+
+    int       grays_count;      /* number of entries in the palette */
+
+    char      gray_lines[ANTI_ALIAS_BUFFER_SIZE];
+                                /* Intermediate table used to render the   */
+                                /* graylevels pixmaps.                     */
+                                /* gray_lines is a buffer holding 2 or 4   */
+                                /* monochrome scanlines                    */
+
+    int       count_table[256];    /* Look-up table used to quickly count  */
+                                   /* set bits in several gray 2x2 cells   */
+                                   /* at once.                             */
+
+#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+  };
+
+
+
+#ifdef DEBUG_RASTER
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Pset                                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used for debugging only.  Plots a point in VRAM during rendering   */
+  /*    (not afterwards).                                                  */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This procedure relies on the value of cProfile->start, which may   */
+  /*    not be set when Pset() is called sometimes.  This will usually     */
+  /*    result in a dot plotted on the first screen scanline (far away     */
+  /*    from its original position).                                       */
+  /*                                                                       */
+  /*    This `feature' reflects nothing wrong in the current               */
+  /*    implementation, and the bitmap is rendered correctly, so don't     */
+  /*    panic if you see `flying' dots in debugging mode.                  */
+  /*                                                                       */
+  static
+  void  Pset( RAS_ARG )
+  {
+    long  o;
+    long  x;
+
+
+    x = ras.cursor[-1];
+
+    switch ( ras.cur_prof->flow )  
+    {
+    case FT_Flow_Up:
+      o = Vio_ScanLineWidth *
+         ( ras.cursor - ras.cur_prof->offset + ras.cur_prof->start ) +
+         ( x / (ras.precision * 8) );
+      break;
+
+    case FT_Flow_Down:
+      o = Vio_ScanLineWidth *
+         ( ras.cur_prof->start - ras.cursor + ras.cur_prof->offset ) +
+         ( x / (ras.precision * 8) );
+      break;
+    }
+
+    if ( o > 0 )
+      Vio[o] |= (unsigned)0x80 >> ( (x/ras.precision) & 7 );
+  }
+
+
+  static
+  void  Clear_Band( RAS_ARG_ TScan  y1,
+                             TScan  y2 )
+  {
+    MEM_Set( Vio + y1*Vio_ScanLineWidth, (y2-y1+1)*Vio_ScanLineWidth, 0 );
+  }
+
+#endif /* DEBUG_RASTER */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Set_High_Precision                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets precision variables according to the parameter flag.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    High :: Set to True for high precision (typically for ppem < 18),  */
+  /*    false otherwise.                                                   */
+  /*                                                                       */
+  static
+  void  Set_High_Precision( RAS_ARG_  char  High )
+  {
+    if ( High )
+    {
+      ras.precision_bits   = 10;
+      ras.precision_step   = 128;
+      ras.precision_jitter = 24;
+    }
+    else
+    {
+      ras.precision_bits   = 6;
+      ras.precision_step   = 32;
+      ras.precision_jitter = 2;
+    }
+
+    ras.precision       = 1 << ras.precision_bits;
+    ras.precision_half  = ras.precision / 2;
+    ras.precision_shift = ras.precision_bits - Pixel_Bits;
+    ras.precision_mask  = -ras.precision;
+  }
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* A simple technical note on how the raster works:                      */
+  /*                                                                       */
+  /*   Converting an outline into a bitmap is achieved in several steps    */
+  /*   which are:                                                          */
+  /*                                                                       */
+  /*   1 - Decomposing the outline into successive `profiles'.  Each       */
+  /*       profile is simply an array of scanline intersections on a given */
+  /*       dimension.  A profile's main attributes are                     */
+  /*                                                                       */
+  /*       o its scanline position boundaries, i.e. `Ymin' and `Ymax'.     */
+  /*                                                                       */
+  /*       o an array of intersection coordinates for each scanline        */
+  /*         between `Ymin' and `Ymax'.                                    */
+  /*                                                                       */
+  /*       o a direction, indicating wether is was built going `up' or     */
+  /*         `down', as this is very important for filling rules.          */
+  /*                                                                       */
+  /*   2 - Sweeping the target map's scanlines in order to compute segment */
+  /*       `spans' which are then filled.  Additionaly, this pass performs */
+  /*       drop-out control.                                               */
+  /*                                                                       */
+  /*   The outline data is parsed during step 1 only.  The profiles are    */
+  /*   built from the bottom of the render pool, used as a stack.  The     */
+  /*   following graphics shows the profile list under construction:       */
+  /*                                                                       */
+  /*     ____________________________________________________________ _ _  */
+  /*    |         |                   |         |                 |        */
+  /*    | profile | coordinates for   | profile | coordinates for |-->     */
+  /*    |    1    |  profile 1        |    2    |  profile 2      |-->     */
+  /*    |_________|___________________|_________|_________________|__ _ _  */
+  /*                                                                       */
+  /*    ^                                                         ^        */
+  /*    |                                                         |        */
+  /*    start of render pool                                   cursor      */
+  /*                                                                       */
+  /*   The top of the profile stack is kept in the `cursor' variable.      */
+  /*                                                                       */
+  /*   As you can see, a profile record is pushed on top of the render     */
+  /*   pool, which is then followed by its coordinates/intersections.  If  */
+  /*   a change of direction is detected in the outline, a new profile is  */
+  /*   generated until the end of the outline.                             */
+  /*                                                                       */
+  /*   Note that when all profiles have been generated, the function       */
+  /*   Finalize_Profile_Table() is used to record, for each profile, its   */
+  /*   bottom-most scanline as well as the scanline above its upmost       */
+  /*   boundary.  These positions are called `extrema' because they (sort  */
+  /*   of) correspond to local extrema.  They are stored in a sorted list  */
+  /*   built from the top of the render pool as a downwards stack:         */
+  /*                                                                       */
+  /*      _ _ _______________________________________                      */
+  /*                            |                    |                     */
+  /*                         <--| sorted list of     |                     */
+  /*                         <--|  extrema scanlines |                     */
+  /*      _ _ __________________|____________________|                     */
+  /*                                                                       */
+  /*                            ^                    ^                     */
+  /*                            |                    |                     */
+  /*                       pool_limit        end of render pool            */
+  /*                                                                       */
+  /*   This list is later used during the sweep phase in order to          */
+  /*   optimize performance (see technical note on the sweep below).       */
+  /*                                                                       */
+  /*   Of course, the raster detects whether the two stacks collide and    */
+  /*   handles the situation propertly.                                    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    New_Profile                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new Profile in the render pool.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    aState :: The state/orientation of the new profile.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TResult  New_Profile( RAS_ARG_ TDirection  direction )
+  {
+    if ( ras.start_prof == NULL )
+    {
+      ras.cur_prof   = (PProfile)ras.cursor; /* current profile          */
+      ras.start_prof = ras.cur_prof;         /* first profile in pool    */
+      ras.cursor    += AlignProfileSize;     /* record profile in buffer */
+    }
+
+    /* check for overflow */
+    if ( ras.cursor >= ras.pool_limit )
+    {
+      ras.error = ErrRaster_Overflow;
+      return FAILURE;
+    }
+
+    /* record profile direction */
+    switch ( direction )
+    {
+    case Ascending:
+      ras.cur_prof->flow = Flow_Up;
+      break;
+
+    case Descending:
+      ras.cur_prof->flow = Flow_Down;
+      break;
+
+    default:
+      ras.error = ErrRaster_Invalid_Map;
+      return FAILURE;
+    }
+
+    /* initialize a few fields */
+    {
+      PProfile  cur = ras.cur_prof;
+
+
+      cur->start  = 0;            /* current start scanline          */
+      cur->height = 0;            /* current height                  */
+      cur->offset = ras.cursor;   /* address of first coordinate     */
+      cur->link   = (PProfile)0;  /* link to next profile in pool    */
+      cur->next   = (PProfile)0;  /* link to next profile in contour */
+    }
+
+    /* record the first profile in a contour */
+    if ( ras.first_prof == NULL )
+      ras.first_prof = ras.cur_prof;
+
+    ras.state  = direction;
+    ras.fresh  = TRUE;       /* this profile has no coordinates yet */
+    ras.joint  = FALSE;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    End_Profile                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finalizes the current Profile and computes its height.  If it is   */
+  /*    not 0, the profile's fields are updated and a new profile is       */
+  /*    pushed on top of its coordinates.  Otherwise the current profile   */
+  /*    is kept and the recording of intersections is restarted.           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TResult  End_Profile( RAS_ARG )
+  {
+    int  h;
+
+
+    h = ras.cursor - ras.cur_prof->offset;
+
+    if ( h < 0 )
+    {
+      /* This error should _never_ occur unless the raster is buggy */
+      ras.error = ErrRaster_Negative_Height;
+      return FAILURE;
+    }
+
+    if ( h > 0 )
+    {
+      PProfile  old, new;
+
+      /* record scanline height in current profile, create a new one */
+      /* and set a link from the old one to it                       */
+      old          = ras.cur_prof;
+      old->height  = h;
+      ras.cur_prof = new = (PProfile)ras.cursor;
+
+      ras.cursor  += AlignProfileSize;
+
+      new->height  = 0;
+      new->offset  = ras.cursor;
+      old->next    = new;
+
+      ras.num_profs++;
+    }
+
+    /* check for overflow */
+    if ( ras.cursor >= ras.pool_limit )
+    {
+      ras.error = ErrRaster_Overflow;
+      return FAILURE;
+    }
+
+    ras.joint = FALSE;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Insert_Extrema                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Records that a given scanline contains at least one local          */
+  /*    extremum.  The table of extrema is placed at the end of the render */
+  /*    pool and grows downwards.  It is used during the sweep phase.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*     y :: The coordinate of the scanline containing an extremum.       */
+  /*                                                                       */
+  static
+  TResult  Insert_Extrema( RAS_ARG_ TScan  y )
+  {
+    PPos   extrema;
+    TScan  y2;
+    int    n;
+
+
+    PTRACE2(( "EXTREMA += %d", y ));
+    n       = ras.n_extrema - 1;
+    extrema = ras.pool_size - ras.n_extrema;
+
+    /* look for first y extremum that is <= */
+    while ( n >= 0 && y < extrema[n] )
+      n--;
+
+    /* if it is <, simply insert it, ignore if == */
+    if ( n >= 0 && y > extrema[n] )
+      while ( n >= 0 )
+      {
+        y2 = extrema[n];
+        extrema[n] = y;
+        y = y2;
+        n--;
+      }
+
+    if ( n < 0 )
+    {
+      ras.pool_limit--;
+      ras.n_extrema++;
+      ras.pool_size[-ras.n_extrema] = y;
+
+      if ( ras.pool_limit <= ras.cursor )
+      {
+        ras.error = ErrRaster_Overflow;
+        return FAILURE;
+      }
+    }
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Finalize_Profile_Table                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Adjusts all links in the profiles list.  Called when the outline   */
+  /*    parsing is done.                                                   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TResult  Finalize_Profile_Table( RAS_ARG )
+  {
+    int       n, bottom, top;
+    PProfile  p;
+
+
+    n = ras.num_profs;
+
+    if ( n > 1 )
+    {
+      p = ras.start_prof;
+      while ( n > 0 )
+      {
+        if ( n > 1 )
+          p->link = (PProfile)( p->offset + p->height );
+        else
+          p->link = NULL;
+
+        switch ( p->flow )
+        {
+          case Flow_Down:
+            PTRACE2(( "FLOW DOWN (start = %d, height = %d)",
+                      p->start, p->height ));
+            bottom     = p->start - p->height+1;
+            top        = p->start;
+            p->start   = bottom;
+            p->offset += p->height-1;
+            break;
+
+          case Flow_Up:
+          default:
+            PTRACE2(( "FLOW UP (start = %d, height = %d)",
+                      p->start, p->height ));
+            bottom = p->start;
+            top    = p->start + p->height-1;
+        }
+
+        if ( Insert_Extrema( RAS_VAR_  bottom ) ||
+             Insert_Extrema( RAS_VAR_  top+1 )  )
+          return FAILURE;
+
+        p = p->link;
+        n--;
+      }
+    }
+    else
+      ras.start_prof = NULL;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Line_Up                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the scan-line intersections of an ascending line segment  */
+  /*    and stores them in the render pool.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    x1   :: The start x coordinate.                                    */
+  /*    y1   :: The start y coordinate.                                    */
+  /*    x2   :: The end x coordinate.                                      */
+  /*    y2   :: The end y coordinate.                                      */
+  /*    miny :: The minimum vertical grid coordinate.                      */
+  /*    maxy :: The maximum vertical grid coordinate.                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TResult  Line_Up( RAS_ARG_ TPos  x1,   TPos  y1,
+                             TPos  x2,   TPos  y2,
+                             TPos  miny, TPos  maxy )
+  {
+    TPos   Dx, Dy;
+    int    e1, e2, f1, f2, size;
+    TPos   Ix, Rx, Ax;
+
+    PPos  top;
+
+
+    Dx = x2 - x1;
+    Dy = y2 - y1;
+
+    if ( Dy <= 0 || y2 < miny || y1 > maxy )
+      return SUCCESS;
+
+    /* clip to higher scanline when necessary */
+    if ( y2 > maxy )
+    {
+      /* x2 += FMulDiv( Dx, maxy-y2, Dy );  UNNECESSARY */
+      e2  = TRUNC( maxy );
+      f2  = 0;
+    }
+    else
+    {
+      e2 = TRUNC( y2 );
+      f2 = FRAC( y2 );
+    }
+
+    /* clip to lower scanline when necessary */
+    if ( y1 < miny )
+    {
+      TPos  x, y;
+
+      /* we use a binary search to compute the lower
+      // clipping intersection. That's because we don't
+      // want to use an external function like FT_MulDiv
+      // to compute it directly.
+      */
+      if ( y2 == miny ) goto Exit;
+      do
+      {
+        x = (x1 + x2) >> 1;
+        y = (y1 + y2) >> 1;
+
+        if (y <= miny)
+        {
+          x1 = x;
+          y1 = y;
+        }
+        else
+        {
+          x2 = x;
+          y2 = y;
+        }
+      }
+      while ( y1 < miny );
+
+      e1  = TRUNC( miny );
+      f1  = 0;
+    }
+    else
+    {
+      e1 = TRUNC( y1 );
+      f1 = FRAC( y1 );
+    }
+
+    /* adjust start point so that we begin on an integer scanline position */
+    if ( f1 > 0 )
+    {
+      if ( e1 == e2 ) goto Exit;
+      else
+      {
+        x1 += FMulDiv( Dx, ras.precision - f1, Dy );
+        e1 += 1;
+      }
+    }
+    else
+      if ( ras.joint )
+      {
+        ras.cursor--;
+        ras.joint = FALSE;
+      }
+
+    ras.joint = ( f2 == 0 );
+
+    /* if this is a `fresh' profile, record its starting scanline */
+    if ( ras.fresh )
+    {
+      ras.cur_prof->start = e1;
+      ras.fresh           = FALSE;
+    }
+
+    /* check for overflow */
+    size = e2 - e1 + 1;
+    if ( ras.cursor + size >= ras.pool_limit )
+    {
+      ras.error = ErrRaster_Overflow;
+      return FAILURE;
+    }
+
+    /* compute decision variables and push the intersections on top */
+    /* of the render pool                                           */
+    Dx <<= ras.precision_bits;
+    Ix   = Dx / Dy;
+    Rx   = Dx % Dy;
+    if (Rx < 0)
+    {
+      Ix --;
+      Rx += Dy;
+    }
+    
+    Ax   = -Dy;
+    Rx <<= 1;
+    Dy <<= 1;
+
+    top = ras.cursor;
+
+    while ( size > 0 )
+    {
+      *top++ = x1;
+
+      DEBUG_PSET;
+
+      x1 += Ix;
+      Ax += Rx;
+      if ( Ax >= 0 )
+      {
+        Ax -= Dy;
+        x1 ++;
+      }
+      size--;
+    }
+
+    ras.cursor = top;
+  Exit:
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Line_Down                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the scan-line intersections of a descending line segment  */
+  /*    and stores them in the render pool.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    x1   :: The start x coordinate.                                    */
+  /*    y1   :: The start y coordinate.                                    */
+  /*    x2   :: The end x coordinate.                                      */
+  /*    y2   :: The end y coordinate.                                      */
+  /*    miny :: The minimum vertical grid coordinate.                      */
+  /*    maxy :: The maximum vertical grid coordinate.                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TResult  Line_Down( RAS_ARG_ TPos  x1,   TPos  y1,
+                               TPos  x2,   TPos  y2,
+                               TPos  miny, TPos  maxy )
+  {
+    TResult  result, fresh;
+
+
+    /* simply invert the coordinates and call Line_Up */
+    fresh  = ras.fresh;
+    result = Line_Up( RAS_VAR_ x1, -y1, x2, -y2, -maxy, -miny );
+
+    /* if this was a fresh profile, invert the recorded start position */
+    if ( fresh && !ras.fresh )
+      ras.cur_prof->start = -ras.cur_prof->start;
+
+    return result;
+  }
+
+
+
+
+ /* A function type describing the functions used to split bezier arcs */
+  typedef  void  (*TSplitter)( TPoint*  base );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Bezier_Up                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the scan-line intersections of an ascending second-order  */
+  /*    Bezier arc and stores them in the render pool.  The arc is taken   */
+  /*    from the top of the stack.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    miny :: The minimum vertical grid coordinate.                      */
+  /*    maxy :: The maximum vertical grid coordinate.                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TResult  Bezier_Up( RAS_ARG_ int        degree,
+                               TSplitter  splitter,
+                               TPos       miny,
+                               TPos       maxy )
+  {
+    TPos  y1, y2, e, e2, e0;
+    int   f1;
+
+    TPoint*  arc;
+    TPoint*  start_arc;
+
+    PPos top;
+
+
+    arc = ras.arc;
+    y1  = arc[degree].y;
+    y2  = arc[0].y;
+    top = ras.cursor;
+
+    if ( y2 < miny || y1 > maxy )
+      goto Fin;
+
+    e2 = FLOOR( y2 );  /* integer end y */
+
+    if ( e2 > maxy )
+      e2 = FLOOR(maxy);
+
+    e0 = CEILING(miny);
+
+    if ( y1 < miny )
+    {
+      e = e0;        /* integer start y == current scanline */
+    }
+    else
+    {
+      e  = CEILING( y1 );   /* integer start y == current scanline */
+      f1 = FRAC( y1 );      /* fractional shift of start y         */
+      e0 = e;               /* first integer scanline to be pushed */
+      
+      if ( f1 == 0 )        /* do we start on an integer scanline? */
+      {
+        if ( ras.joint )
+        {
+          top--;
+          ras.joint = FALSE;
+        }
+
+        *top++ = arc[degree].x;  /* write directly start position */
+
+        DEBUG_PSET;
+
+        e += ras.precision; /* go to next scanline */
+      }
+    }
+
+    /* record start position if necessary */
+    if ( ras.fresh )
+    {
+      ras.cur_prof->start = TRUNC( e0 );
+      ras.fresh = FALSE;
+    }
+
+    /* exit if the current scanline is already above the max scanline */
+    if ( e2 < e )
+      goto Fin;
+
+    /* check for overflow */
+    if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.pool_limit )
+    {
+      ras.cursor = top;
+      ras.error  = ErrRaster_Overflow;
+      return FAILURE;
+    }
+
+    start_arc = arc;
+
+    /* loop while there is still an arc on the bezier stack */
+    /* and the current scan line is below y max == e2       */
+    while ( arc >= start_arc && e <= e2 )
+    {
+      ras.joint = FALSE;
+
+      y2 = arc[0].y;  /* final y of the top-most arc */
+
+      if ( y2 > e )   /* the arc intercepts the current scanline */
+      {
+        y1 = arc[degree].y;  /* start y of top-most arc */
+        
+        if ( y2 - y1 >= ras.precision_step )
+        {
+          /* if the arc's height is too great, split it */
+          splitter( arc );
+          arc += degree;
+        }
+        else
+        {
+          /* otherwise, approximate it as a segment and compute */
+          /* its intersection with the current scanline         */
+          *top++ = arc[degree].x +
+                   FMulDiv( arc[0].x-arc[degree].x,
+                            e  - y1,
+                            y2 - y1 );
+
+          DEBUG_PSET;
+
+          arc -= degree;         /* pop the arc         */
+          e   += ras.precision;  /* go to next scanline */
+        }
+      }
+      else
+      {
+        if ( y2 == e )        /* if the arc falls on the scanline */
+        {                     /* record its _joint_ intersection  */
+          ras.joint  = TRUE;
+          *top++     = arc[0].x;
+
+          DEBUG_PSET;
+
+          e += ras.precision; /* go to next scanline */
+        }
+        arc -= degree;        /* pop the arc */
+      }
+    }
+
+  Fin:
+    ras.cursor = top;
+    ras.arc   -= degree;
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Bezier_Down                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the scan-line intersections of a descending second-order  */
+  /*    Bezier arc and stores them in the render pool.  The arc is taken   */
+  /*    from the top of the stack.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    miny :: The minimum vertical grid coordinate.                      */
+  /*    maxy :: The maximum vertical grid coordinate.                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TResult  Bezier_Down( RAS_ARG_ int        degree,
+                                 TSplitter  splitter,
+                                 TPos       miny,
+                                 TPos       maxy )
+  {
+    TPoint*  arc = ras.arc;
+    TResult  result, fresh;
+
+    arc[0].y = -arc[0].y;
+    arc[1].y = -arc[1].y;
+    arc[2].y = -arc[2].y;
+    if (degree > 2)
+      arc[3].y = -arc[3].y;
+
+    fresh = ras.fresh;
+
+    result = Bezier_Up( RAS_VAR_ degree, splitter, -maxy, -miny );
+
+    if ( fresh && !ras.fresh )
+      ras.cur_prof->start = -ras.cur_prof->start;
+
+    arc[0].y = -arc[0].y;
+    return result;
+  }
+
+
+#ifdef FT_RASTER_CONIC_BEZIERS
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Split_Conic                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Subdivides one second-order Bezier arc into two joint sub-arcs in  */
+  /*    the Bezier stack.                                                  */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This routine is the `beef' of the component.  It is one of _the_   */
+  /*    inner loops that should be optimized like hell to get the best     */
+  /*    performance.                                                       */
+  /*                                                                       */
+  static
+  void  Split_Conic( TPoint*  base )
+  {
+    TPos  a, b;
+
+
+    base[4].x = base[2].x;
+    b = base[1].x;
+    a = base[3].x = ( base[2].x + b )/2;
+    b = base[1].x = ( base[0].x + b )/2;
+    base[2].x = ( a + b ) / 2;
+
+    base[4].y = base[2].y;
+    b = base[1].y;
+    a = base[3].y = ( base[2].y + b )/2;
+    b = base[1].y = ( base[0].y + b )/2;
+    base[2].y = ( a + b ) / 2;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Push_Conic                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Clears the Bezier stack and pushes a new arc on top of it.         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    p2 :: A pointer to the second (control) point.                     */
+  /*    p3 :: A pointer to the third (end) point.                          */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The first point is taken as `raster->last', so it doesn't appear   */
+  /*    in the signature.                                                  */
+  /*                                                                       */
+  static
+  void  Push_Conic( RAS_ARG_ FT_Vector*  p2,
+                             FT_Vector*  p3 )
+  {
+#undef  STORE
+#define STORE( _arc, point )                    \
+          {                                     \
+            TPos  x = SCALED( point->x );       \
+            TPos  y = SCALED( point->y );       \
+                                                \
+                                                \
+            if ( ras.flipped )                  \
+            {                                   \
+              _arc.x = y;                       \
+              _arc.y = x;                       \
+            }                                   \
+            else                                \
+            {                                   \
+              _arc.x = x;                       \
+              _arc.y = y;                       \
+            }                                   \
+          }
+
+    TPoint*  arc;
+
+
+    ras.arc = arc = ras.arcs;
+
+    arc[2] = ras.last;
+    STORE( arc[1], p2 );
+    STORE( arc[0], p3 );
+#undef  STORE
+  }
+
+#endif /* FT_RASTER_CONIC_BEZIERS */
+
+
+
+#ifdef FT_RASTER_CUBIC_BEZIERS
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>   Split_Cubic                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*     Subdivides a third-order Bezier arc into two joint sub-arcs in    */
+  /*     the Bezier stack.                                                 */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This routine is the `beef' of the component.  It is one of _the_   */
+  /*    inner loops that should be optimized like hell to get the best     */
+  /*    performance.                                                       */
+  /*                                                                       */
+  static
+  void  Split_Cubic( TPoint*  base )
+  {
+    TPos   a, b, c, d;
+
+
+    base[6].x = base[3].x;
+    c = base[1].x;
+    d = base[2].x;
+    base[1].x = a = ( base[0].x + c ) / 2;
+    base[5].x = b = ( base[3].x + d ) / 2;
+    c = ( c + d ) / 2;
+    base[2].x = a = ( a + c ) / 2;
+    base[4].x = b = ( b + c ) / 2;
+    base[3].x = ( a + b ) / 2;
+
+    base[6].y = base[3].y;
+    c = base[1].y;
+    d = base[2].y;
+    base[1].y = a = ( base[0].y + c ) / 2;
+    base[5].y = b = ( base[3].y + d ) / 2;
+    c = ( c + d ) / 2;
+    base[2].y = a = ( a + c ) / 2;
+    base[4].y = b = ( b + c ) / 2;
+    base[3].y = ( a + b ) / 2;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Push_Cubic                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Clears the Bezier stack and pushes a new third-order Bezier arc on */
+  /*    top of it.                                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    p2 :: A pointer to the second (control) point.                     */
+  /*    p3 :: A pointer to the third (control) point.                      */
+  /*    p4 :: A pointer to the fourth (end) point.                         */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The first point is taken as `raster->last', so it doesn't appear   */
+  /*    in the signature.                                                  */
+  /*                                                                       */
+  /*    This is the same as Push_Conic(), except that it deals with        */
+  /*    third-order Beziers.                                               */
+  /*                                                                       */
+  static
+  void  Push_Cubic( RAS_ARG_ FT_Vector*  p2,
+                             FT_Vector*  p3,
+                             FT_Vector*  p4 )
+  {
+#undef  STORE
+#define STORE( _arc, point )                    \
+          {                                     \
+            TPos  x = SCALED( point->x );       \
+            TPos  y = SCALED( point->y );       \
+                                                \
+                                                \
+            if ( ras.flipped )                  \
+            {                                   \
+              _arc.x = y;                       \
+              _arc.y = x;                       \
+            }                                   \
+            else                                \
+            {                                   \
+              _arc.x = x;                       \
+              _arc.y = y;                       \
+            }                                   \
+          }
+
+    TPoint*  arc;
+    ras.arc = arc = ras.arcs;
+
+
+    arc[3] = ras.last;
+    STORE( arc[2], p2 );
+    STORE( arc[1], p3 );
+    STORE( arc[0], p4 );
+
+#undef STORE
+  }
+
+#endif /* FT_RASTER_CUBIC_BEZIERS */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Check_Contour                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Performs some checks at contour closure.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TResult  Check_Contour( RAS_ARG )
+  {
+    PProfile  lastProfile;
+
+
+    /* Sometimes, the first and last profile in a contour join on      */
+    /* an integer scan-line; we must then remove the last intersection */
+    /* from the last profile to get rid of doublets                    */
+    if ( ( FRAC( ras.last.y ) == 0     &&
+           ras.last.y >= ras.minY      &&
+           ras.last.y <= ras.maxY )    )
+    {
+      if ( ras.first_prof && ras.first_prof->flow == ras.cur_prof->flow )
+        ras.cursor--;
+    }
+
+    lastProfile = ras.cur_prof;
+    if ( End_Profile( RAS_VAR ) )
+      return FAILURE;
+
+    /* close the `next profile in contour' linked list */
+    lastProfile->next = ras.first_prof;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Move_To                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function injects a new contour in the render pool.            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    to     :: A pointer to the contour's first point.                  */
+  /*    raster :: A pointer to the current raster object.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function is used as a `FTRasterMoveTo_Func' by the outline    */
+  /*    decomposer.                                                        */
+  /*                                                                       */
+  static
+  int  Move_To( FT_Vector*  to,
+                FT_Raster   raster )
+  {
+    TPos  scaled_x, scaled_y;
+
+    
+    /* if there was already a contour being built, perform some checks */
+    if ( ras.start_prof )
+      if ( Check_Contour( RAS_VAR ) )
+        return FAILURE;
+
+    /* set the `current last point' */
+    scaled_x = SCALED( to->x );
+    scaled_y = SCALED( to->y );
+    
+    if ( ras.flipped )
+    {
+      ras.last.x = scaled_y;
+      ras.last.y = scaled_x;
+    }
+    else
+    {
+      ras.last.x = scaled_x;
+      ras.last.y = scaled_y;
+    }
+
+    ras.state      = Unknown;
+    ras.first_prof = NULL;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Line_To                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function injects a new line segment in the render pool and    */
+  /*    adjusts the profiles list accordingly.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    to     :: A pointer to the target position.                        */
+  /*    raster :: A pointer to the current raster object.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function is used as a `FTRasterLineTo_Func' by the outline    */
+  /*    decomposer.                                                        */
+  /*                                                                       */
+  static
+  int  Line_To( FT_Vector*  to,
+                FT_Raster   raster )
+  {
+    TPos  x, scaled_x;
+    TPos  y, scaled_y;
+
+
+    scaled_x = SCALED( to->x );
+    scaled_y = SCALED( to->y );
+
+    if ( ras.flipped )
+    {
+      x = scaled_y;
+      y = scaled_x;
+    }
+    else
+    {
+      x = scaled_x;
+      y = scaled_y;
+    }
+
+    /* First, detect a change of direction */
+    if ( y != ras.last.y )
+    {
+      TDirection  new_state = ( (y > ras.last.y) ? Ascending : Descending );
+
+
+      if ( ras.state != new_state )
+      {      
+        if ( ras.state != Unknown   &&
+             End_Profile( RAS_VAR ) )
+          goto Fail;
+
+        if ( New_Profile( RAS_VAR_  new_state ) )
+          goto Fail;
+      }
+    }        
+
+    /* Then compute the lines */
+    switch ( ras.state )
+    {
+    case Ascending:
+      if ( Line_Up ( RAS_VAR_  ras.last.x, ras.last.y,
+                               x, y, ras.minY, ras.maxY ) )
+        goto Fail;
+      break;
+
+    case Descending:
+      if ( Line_Down( RAS_VAR_ ras.last.x, ras.last.y,
+                               x, y, ras.minY, ras.maxY ) )
+        goto Fail;
+      break;
+
+    default:
+      ;
+    }
+
+    ras.last.x = x;
+    ras.last.y = y;
+
+    return SUCCESS;
+
+  Fail:
+    return FAILURE;
+  }
+
+
+#ifdef FT_RASTER_CONIC_BEZIERS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Conic_To                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Injects a new conic Bezier arc and adjusts the profile list        */
+  /*    accordingly.                                                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    control :: A pointer to an intermediate control point.             */
+  /*    to      :: A pointer to the end point.                             */
+  /*    raster  :: A handle to the current raster object.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function is used as a `FTRasterConicTo_Func' by the outline   */
+  /*    decomposer.                                                        */
+  /*                                                                       */
+  static
+  int  Conic_To( FT_Vector*  control,
+                 FT_Vector*  to,
+                 FT_Raster   raster )
+  {
+    TPos        y1, y2, y3, x3, ymin, ymax;
+    TDirection  state_bez;
+
+
+    Push_Conic( RAS_VAR_  control, to );
+
+    do
+    {
+      y1 = ras.arc[2].y;
+      y2 = ras.arc[1].y;
+      y3 = ras.arc[0].y;
+      x3 = ras.arc[0].x;
+
+      /* first, categorize the Bezier arc */
+
+      if ( y1 <= y3 )
+      {
+        ymin = y1;
+        ymax = y3;
+      }
+      else
+      {
+        ymin = y3;
+        ymax = y1;
+      }
+      
+      if ( y2 < ymin || y2 > ymax )
+      {
+        /* this arc has no given direction, split it !! */
+        Split_Conic( ras.arc );
+        ras.arc += 2;
+      }
+      else if ( y1 == y3 )
+      {
+        /* this arc is flat, ignore it and pop it from the bezier stack */
+        ras.arc -= 2;
+      }
+      else
+      {
+        /* the arc is y-monotonous, either ascending or descending */
+        /* detect a change of direction                            */
+        state_bez =  y1 < y3 ? Ascending : Descending;
+        if ( ras.state != state_bez )
+        {
+          /* finalize current profile if any */
+          if ( ras.state != Unknown   &&
+               End_Profile( RAS_VAR ) )
+            goto Fail;
+            
+          /* create a new profile */
+          if ( New_Profile( RAS_VAR_ state_bez ) )
+            goto Fail;
+        }
+        
+        /* now call the appropriate routine */
+        if ( state_bez == Ascending )
+        {
+          if ( Bezier_Up( RAS_VAR_  2, Split_Conic, ras.minY, ras.maxY ) )
+            goto Fail;
+        }
+        else
+          if ( Bezier_Down( RAS_VAR_  2, Split_Conic, ras.minY, ras.maxY ) )
+            goto Fail;
+      }    
+
+    } while ( ras.arc >= ras.arcs );
+
+    ras.last.x = x3;
+    ras.last.y = y3;
+
+    return SUCCESS;
+
+  Fail:
+    return FAILURE;
+  }
+
+#else /* FT_RASTER_CONIC_BEZIERS */
+
+
+  static
+  int  Conic_To( FT_Vector*  control,
+                 FT_Vector*  to,
+                 FT_Raster   raster )
+  {
+    UNUSED( control );
+    UNUSED( to );
+    UNUSED( raster );
+
+    return ErrRaster_Invalid_Outline;
+  }
+
+
+#endif /* FT_RASTER_CONIC_BEZIERS */
+
+
+#ifdef FT_RASTER_CUBIC_BEZIERS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Cubic_To                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Injects a new cubic Bezier arc and adjusts the profile list        */
+  /*    accordingly.                                                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    control1 :: A pointer to the first control point.                  */
+  /*    control2 :: A pointer to the second control point.                 */
+  /*    to       :: A pointer to the end point.                            */
+  /*    raster   :: A handle to the current raster object.                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function is used as a `FTRasterCubicTo_Func' by the outline   */
+  /*    decomposer.                                                        */
+  /*                                                                       */
+  static
+  int  Cubic_To( FT_Vector*  control1,
+                 FT_Vector*  control2,
+                 FT_Vector*  to,
+                 FT_Raster   raster )
+  {
+    TPos        y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
+    TDirection  state_bez;
+
+
+    Push_Cubic( RAS_VAR_  control1, control2, to );
+
+    do
+    {
+      y1 = ras.arc[3].y;
+      y2 = ras.arc[2].y;
+      y3 = ras.arc[1].y;
+      y4 = ras.arc[0].y;
+      x4 = ras.arc[0].x;
+
+      /* first, categorize the Bezier arc */
+
+      if ( y1 <= y4 )
+      {
+        ymin1 = y1;
+        ymax1 = y4;
+      }
+      else
+      {
+        ymin1 = y4;
+        ymax1 = y1;
+      }
+      
+      if ( y2 <= y3 )
+      {
+        ymin2 = y2;
+        ymax2 = y3;
+      }
+      else
+      {
+        ymin2 = y3;
+        ymax2 = y2;
+      }
+      
+      if ( ymin2 < ymin1 || ymax2 > ymax1 )
+      {
+        /* this arc has no given direction, split it! */
+        Split_Cubic( ras.arc );
+        ras.arc += 3;
+      }
+      else if ( y1 == y4 )
+      {
+        /* this arc is flat, ignore it and pop it from the bezier stack */
+        ras.arc -= 3;
+      }        
+      else
+      {
+        state_bez = ( y1 <= y4 ) ? Ascending : Descending;
+     
+        /* detect a change of direction */
+        if ( ras.state != state_bez )
+        {
+          if ( ras.state != Unknown   &&
+               End_Profile( RAS_VAR ) )
+            goto Fail;
+
+          if ( New_Profile( RAS_VAR_ state_bez ) )
+            goto Fail;
+        }
+
+        /* compute intersections */
+        if ( state_bez == Ascending )
+        {
+          if ( Bezier_Up ( RAS_VAR_ 3, Split_Cubic, ras.minY, ras.maxY ) )
+            goto Fail;
+        }
+        else
+          if ( Bezier_Down ( RAS_VAR_ 3, Split_Cubic, ras.minY, ras.maxY ) )
+            goto Fail;
+      }
+
+    } while ( ras.arc >= ras.arcs );
+
+    ras.last.x = x4;
+    ras.last.y = y4;
+
+    return SUCCESS;
+
+  Fail:
+    return FAILURE;
+  }
+
+
+#else /* FT_RASTER_CUBIC_BEZIERS */
+
+
+  int  Cubic_To( FT_Vector*  control1,
+                 FT_Vector*  control2,
+                 FT_Vector*  to,
+                 FT_Raster   raster )
+  {
+    UNUSED( control1 );
+    UNUSED( control2 );
+    UNUSED( to );
+    UNUSED( raster );
+
+    return ErrRaster_Invalid_Outline;
+  }
+
+
+#endif /* FT_RASTER_CUBIC_BEZIERS */
+
+
+/********************************************************************/
+/*                                                                  */
+/* The following function is compiled in the raster only when it is */
+/* compile as a stand-alone module..                                */
+
+/* It can, otherwise, be found in the FreeType base layer           */
+
+#ifdef _STANDALONE_
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Decompose_Outline                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Walks over an outline's structure to decompose it into individual  */
+  /*    segments and Bezier arcs.  This function is also able to emit      */
+  /*    `move to' and `close to' operations to indicate the start and end  */
+  /*    of new contours in the outline.                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    outline   :: A pointer to the source target.                       */
+  /*                                                                       */
+  /*    interface :: A table of `emitters', i.e,. function pointers called */
+  /*                 during decomposition to indicate path operations.     */
+  /*                                                                       */
+  /*    user      :: A typeless pointer which is passed to each emitter    */
+  /*                 during the decomposition.  It can be used to store    */
+  /*                 the state during the decomposition.                   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means sucess.                                       */
+  /*                                                                       */
+
+#if 0
+  typedef int  (*FTRasterMoveTo_Func)( FT_Vector*  to,
+                                       void*       user );
+
+  typedef int  (*FTRasterLineTo_Func)( FT_Vector*  to,
+                                       void*       user );
+
+  typedef int  (*FTRasterConicTo_Func)( FT_Vector*  control,
+                                        FT_Vector*  to,
+                                        void*       user );
+
+  typedef int  (*FTRasterCubicTo_Func)( FT_Vector*  control1,
+                                        FT_Vector*  control2,
+                                        FT_Vector*  to,
+                                        void*       user );
+
+  typedef struct  FT_Raster_Funcs_
+  {
+    FTRasterMoveTo_Func   move_to;
+    FTRasterLineTo_Func   line_to;
+    FTRasterConicTo_Func  conic_to;
+    FTRasterCubicTo_Func  cubic_to;
+
+  } FT_Raster_Funcs;
+#endif
+
+  int  FT_Decompose_Outline( FT_Outline*       outline,
+                             FT_Raster_Funcs*  interface,
+                             void*             user )
+  {
+    typedef enum _phases
+    {
+      phase_point,
+      phase_conic,
+      phase_cubic,
+      phase_cubic2
+
+    } TPhase;
+
+    FT_Vector  v_first;
+    FT_Vector  v_last;
+    FT_Vector  v_control;
+    FT_Vector  v_control2;
+    FT_Vector  v_start;
+
+    FT_Vector* point;
+    PByte   flags;
+
+    int    n;         /* index of contour in outline     */
+    int    first;     /* index of first point in contour */
+    int    index;     /* current point's index           */
+
+    int    error;
+
+    char   tag;       /* current point's state           */
+    TPhase phase;
+
+
+    first = 0;
+
+    for ( n = 0; n < outline->n_contours; n++ )
+    {
+      int  last;  /* index of last point in contour */
+
+
+      last = outline->contours[n];
+
+      v_first = outline->points[first];
+      v_last  = outline->points[last];
+
+      v_start = v_control = v_first;
+
+      tag   = FT_CURVE_TAG( outline->flags[first] );
+      index = first;
+
+      /* A contour cannot start with a cubic control point! */
+
+      if ( tag == FT_Curve_Tag_Cubic )
+        return ErrRaster_Invalid_Outline;
+
+
+      /* check first point to determine origin */
+
+      if ( tag == FT_Curve_Tag_Conic )
+      {
+        /* first point is conic control.  Yes, this happens. */
+        if ( FT_CURVE_TAG( outline->flags[last] ) == FT_Curve_Tag_On )
+        {
+          /* start at last point if it is on the curve */
+          v_start = v_last;
+        }
+        else
+        {
+          /* if both first and last points are conic,         */
+          /* start at their middle and record its position    */
+          /* for closure                                      */
+          v_start.x = ( v_start.x + v_last.x ) / 2;
+          v_start.y = ( v_start.y + v_last.y ) / 2;
+
+          v_last = v_start;
+        }
+        phase = phase_conic;
+      }
+      else
+        phase = phase_point;
+
+
+      /* Begin a new contour with MOVE_TO */
+
+      error = interface->move_to( &v_start, user );
+      if ( error )
+        return error;
+
+      point = outline->points + first;
+      flags = outline->flags  + first;
+
+      /* now process each contour point individually */
+
+      while ( index < last )
+      {
+        index++;
+        point++;
+        flags++;
+
+        tag = FT_CURVE_TAG( flags[0] );
+
+        switch ( phase )
+        {
+        case phase_point:     /* the previous point was on the curve */
+
+          switch ( tag )
+          {
+            /* two succesive on points -> emit segment */
+          case FT_Curve_Tag_On:
+            error = interface->line_to( point, user );
+            break;
+
+            /* on point + conic control -> remember control point */
+          case FT_Curve_Tag_Conic:
+            v_control = point[0];
+            phase     = phase_conic;
+            break;
+
+            /* on point + cubic control -> remember first control */
+          default:
+            v_control = point[0];
+            phase     = phase_cubic;
+            break;
+          }
+          break;
+
+        case phase_conic:   /* the previous point was a conic control */
+
+          switch ( tag )
+          {
+            /* conic control + on point -> emit conic arc */
+          case  FT_Curve_Tag_On:
+            error = interface->conic_to( &v_control, point, user );
+            phase = phase_point;
+            break;
+
+            /* two successive conics -> emit conic arc `in between' */
+          case FT_Curve_Tag_Conic:
+            {
+              FT_Vector  v_middle;
+
+
+              v_middle.x = (v_control.x + point->x)/2;
+              v_middle.y = (v_control.y + point->y)/2;
+
+              error = interface->conic_to( &v_control,
+                                           &v_middle, user );
+              v_control = point[0];
+            }
+             break;
+
+          default:
+            error = ErrRaster_Invalid_Outline;
+          }
+          break;
+
+        case phase_cubic:  /* the previous point was a cubic control */
+
+          /* this point _must_ be a cubic control too */
+          if ( tag != FT_Curve_Tag_Cubic )
+            return ErrRaster_Invalid_Outline;
+
+          v_control2 = point[0];
+          phase      = phase_cubic2;
+          break;
+
+
+        case phase_cubic2:  /* the two previous points were cubics */
+
+          /* this point _must_ be an on point */
+          if ( tag != FT_Curve_Tag_On )
+            error = ErrRaster_Invalid_Outline;
+          else
+            error = interface->cubic_to( &v_control, &v_control2,
+                                         point, user );
+          phase = phase_point;
+          break;
+        }
+
+        /* lazy error testing */
+        if ( error )
+          return error;
+      }
+
+      /* end of contour, close curve cleanly */
+      error = 0;
+
+      tag = FT_CURVE_TAG( outline->flags[first] );
+
+      switch ( phase )
+      {
+      case phase_point:
+        if ( tag == FT_Curve_Tag_On )
+          error = interface->line_to( &v_first, user );
+        break;
+
+      case phase_conic:
+        error = interface->conic_to( &v_control, &v_start, user );
+        break;
+
+      case phase_cubic2:
+        if ( tag == FT_Curve_Tag_On )
+          error = interface->cubic_to( &v_control, &v_control2,
+                                       &v_first,   user );
+        else
+          error = ErrRaster_Invalid_Outline;
+        break;
+
+      default:
+        error = ErrRaster_Invalid_Outline;
+        break;
+      }
+
+      if ( error )
+        return error;
+
+      first = last + 1;
+    }
+
+    return SUCCESS;
+  }
+#endif
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Convert_Glyph                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Converts a glyph into a series of segments and arcs and makes a    */
+  /*    profiles list with them.                                           */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    outline :: The glyph outline.                                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TResult  Convert_Glyph( RAS_ARG_ FT_Outline*  outline )
+  {
+    static FT_Outline_Funcs  interface =
+    {
+      (FT_Outline_MoveTo_Func)Move_To,
+      (FT_Outline_LineTo_Func)Line_To,
+      (FT_Outline_ConicTo_Func)Conic_To,
+      (FT_Outline_CubicTo_Func)Cubic_To
+    };
+
+    /* Set up state in the raster object */
+    ras.start_prof = NULL;
+    ras.joint      = FALSE;
+    ras.fresh      = FALSE;
+
+    ras.pool_limit = ras.pool_size - AlignProfileSize;
+
+    ras.n_extrema = 0;
+
+    ras.cur_prof         = (PProfile)ras.cursor;
+    ras.cur_prof->offset = ras.cursor;
+    ras.num_profs        = 0;
+
+    /* Now decompose curve */
+    if ( FT_Decompose_Outline( outline, &interface, &ras ) )
+      return FAILURE;
+    /* XXX: the error condition is in ras.error */
+
+    /* Check the last contour if needed */
+    if ( Check_Contour( RAS_VAR ) )
+      return FAILURE;
+
+    /* Finalize profiles list */
+    return Finalize_Profile_Table( RAS_VAR );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Init_Linked                                                           */
+  /*                                                                       */
+  /*    Inits an empty linked list.                                        */
+  /*                                                                       */
+  static void
+  Init_Linked( TProfileList*  l )
+  {
+    *l = NULL;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* InsNew                                                                */
+  /*                                                                       */
+  /*    Inserts a new Profile in a linked list.                            */
+  /*                                                                       */
+  static
+  void  InsNew( PProfileList  list,
+                PProfile      profile )
+  {
+    PProfile  *old, current;
+    TPos       x;
+
+
+    old     = list;
+    current = *old;
+    x       = profile->X;
+
+    while ( current )
+    {
+      if ( x < current->X )
+        break;
+      old     = &current->link;
+      current = *old;
+    }
+
+    profile->link = current;
+    *old          = profile;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DelOld                                                                */
+  /*                                                                       */
+  /*    Removes an old Profile from a linked list.                         */
+  /*                                                                       */
+  static
+  void  DelOld( PProfileList  list,
+                PProfile      profile )
+  {
+    PProfile  *old, current;
+
+
+    old     = list;
+    current = *old;
+
+    while ( current )
+    {
+      if ( current == profile )
+      {
+        *old = current->link;
+        return;
+      }
+
+      old     = &current->link;
+      current = *old;
+    }
+
+    /* We should never reach this place, unless the Profile was not  */
+    /* part of the list.                                             */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Update                                                                */
+  /*                                                                       */
+  /*    Updates all X offsets of a drawing list.                           */
+  /*                                                                       */
+  static
+  void  Update( PProfile  first )
+  {
+    PProfile  current = first;
+
+
+    while ( current )
+    {
+      current->X       = *current->offset;
+      current->offset += current->flow;
+      current->height--;
+      current = current->link;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Sort                                                                  */
+  /*                                                                       */
+  /*    Sorts a trace list.  In 95%, the list is already sorted.  We need  */
+  /*    an algorithm which is fast in this case.  Bubble sort is enough    */
+  /*    and simple to implement.                                           */
+  /*                                                                       */
+  static
+  void  Sort( PProfileList  list )
+  {
+    PProfile  *old, current, next;
+
+
+    /* First, set the new X coordinate of each profile */
+    Update( *list );
+
+    /* Then sort them */
+    old     = list;
+    current = *old;
+
+    if ( !current )
+      return;
+
+    next = current->link;
+
+    while ( next )
+    {
+      if ( current->X <= next->X )
+      {
+        old     = &current->link;
+        current = *old;
+
+        if ( !current )
+          return;
+      }
+      else
+      {
+        *old          = next;
+        current->link = next->link;
+        next->link    = current;
+
+        old     = list;
+        current = *old;
+      }
+
+      next = current->link;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /********                                                         ********/
+  /********            Vertical Bitmap Sweep Routines               ********/
+  /********                                                         ********/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Sweep_Init                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes the vertical bitmap sweep.  Called by the generic      */
+  /*    sweep/draw routine before its loop.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    min :: The address of the current minimum scanline.                */
+  /*    max :: The address of the current maximum scanline.                */
+  /*                                                                       */
+  static
+  void  Vertical_Sweep_Init( RAS_ARG_ int*  min, int*  max )
+  {
+    long  pitch;
+    
+    UNUSED( max );
+
+    pitch          = ras.target.pitch;
+    
+    /* start from the bottom line, going up !! */
+    ras.trace_bit  = - *min * pitch;
+    ras.trace_incr = -pitch;
+
+    if (pitch > 0)
+      ras.trace_bit += pitch*(ras.target.rows-1);
+
+    ras.gray_min_x = 0;
+    ras.gray_max_x = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Sweep_Span                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Draws a single horizontal bitmap span during the vertical bitmap   */
+  /*    sweep.                                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y  :: The current scanline.                                        */
+  /*    x1 :: The left span edge.                                          */
+  /*    x2 :: The right span edge.                                         */
+  /*                                                                       */
+  static
+  void  Vertical_Sweep_Span( RAS_ARG_ TScan  y,
+                                      TPos   x1,
+                                      TPos   x2 )
+  {
+    TPos   e1, e2;
+    int    c1, c2;
+    Byte   f1, f2;
+    PByte  target;
+
+
+    UNUSED( y );
+
+    /* Drop-out control */
+
+    e1 = TRUNC( CEILING( x1 ) );
+    if ( x2 - x1 - ras.precision <= ras.precision_jitter )
+      e2 = e1;
+    else
+      e2 = TRUNC( FLOOR( x2 ) );
+
+    if ( e1 <= e2 && e2 >= 0 && e1 < ras.bit_width )
+    {
+      if ( e1 < 0 )              e1 = 0;
+      if ( e2 >= ras.bit_width ) e2 = ras.bit_width - 1;
+
+      c1 = e1 >> 3;
+      c2 = e2 >> 3;
+
+      f1 =  ((unsigned char)0xFF >> (e1 & 7));
+      f2 = ~((unsigned char)0x7F >> (e2 & 7));
+
+#ifdef FT_RASTER_ANY_ENDIAN
+      if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
+      if ( ras.gray_max_x < c2 ) ras.gray_max_x = c2;
+#endif
+
+      target = ras.bit_buffer + ras.trace_bit + c1;
+      c2 -= c1;
+
+      if ( c2 > 0 )
+      {
+        target[0] |= f1;
+
+        /* memset() is slower than the following code on many platforms. */
+        /* This is due to the fact that, in the vast majority of cases,  */
+        /* the span length in bytes is relatively small.                 */
+        c2--;
+        while ( c2 > 0 )
+        {
+          *(++target) = 0xFF;
+          c2--;
+        }
+        target[1] |= f2;
+      }
+      else
+        *target |= ( f1 & f2 );
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Test_Pixel                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Tests a pixel `light' during the vertical bitmap sweep.  Used      */
+  /*    during drop-out control only.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y :: The current scanline.                                         */
+  /*    x :: The current x coordinate.                                     */
+  /*                                                                       */
+  static
+  int  Vertical_Test_Pixel( RAS_ARG_ TScan  y,
+                                     int    x )
+  {
+    int c1 = x >> 3;
+
+
+    UNUSED( y );
+
+    return ( x >= 0 && x < ras.bit_width &&
+             ras.bit_buffer[ras.trace_bit + c1] & (0x80 >> (x & 7)) );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Set_Pixel                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets a single pixel in a bitmap during the vertical sweep.  Used   */
+  /*    during drop-out control.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y     :: The current scanline.                                     */
+  /*    x     :: The current x coordinate.                                 */
+  /*    color :: Ignored by this function.                                 */
+  /*                                                                       */
+  static
+  void  Vertical_Set_Pixel( RAS_ARG_ int  y,
+                                     int  x,
+                                     int  color )
+  {
+    UNUSED( color );
+    UNUSED( y );
+
+    if ( x >= 0 && x < ras.bit_width )
+    {
+      int c1 = x >> 3;
+
+      if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
+      if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1;
+
+      ras.bit_buffer[ras.trace_bit+c1] |= (char)(0x80 >> (x & 7));
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Sweep_Step                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Called whenever the sweep jumps to another scanline.  Only updates */
+  /*    the pointers in the vertical bitmap sweep.                         */
+  /*                                                                       */
+  static
+  void Vertical_Sweep_Step( RAS_ARG )
+  {
+    ras.trace_bit += ras.trace_incr;
+  }
+
+
+  static
+  const  Raster_Render   vertical_render_mono =
+  {
+    &Vertical_Sweep_Init,
+    &Vertical_Sweep_Span,
+    &Vertical_Sweep_Step,
+    &Vertical_Test_Pixel,
+    &Vertical_Set_Pixel
+  };
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /********                                                         ********/
+  /********           Horizontal Bitmap Sweep Routines              ********/
+  /********                                                         ********/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Horizontal_Sweep_Init                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes the horizontal bitmap sweep.  Called by the generic    */
+  /*    sweep/draw routine before its loop.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    min :: The address of the current minimum pixel column.            */
+  /*    max :: The address of the current maximum pixel column.            */
+  /*                                                                       */
+  static
+  void  Horizontal_Sweep_Init( RAS_ARG_ int*  min,
+                                        int*  max )
+  {
+    UNUSED( ras );
+    UNUSED( min );
+    UNUSED( max );
+
+    /* nothing, really */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Horizontal_Sweep_Span                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Draws a single vertical bitmap span during the horizontal bitmap   */
+  /*    sweep.  Actually, this function is only used to check for weird    */
+  /*    drop-out cases.                                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y  :: The current pixel column.                                    */
+  /*    x1 :: The top span edge.                                           */
+  /*    x2 :: The bottom span edge.                                        */
+  /*                                                                       */
+  static
+  void  Horizontal_Sweep_Span( RAS_ARG_ TScan  y,
+                                        TPos   x1,
+                                        TPos   x2 )
+  {
+    TPos      e1, e2;
+    PByte  bits;
+    Byte   f1;
+
+    UNUSED( y );
+
+    /* During the horizontal sweep, we only take care of drop-outs */
+    if ( x2 - x1 < ras.precision )
+    {
+      e1 = CEILING( x1 );
+      e2 = FLOOR( x2 );
+
+      if ( e1 == e2 )
+      {
+        bits = ras.bit_buffer + (y >> 3);
+        f1   = (Byte)(0x80 >> (y & 7));
+
+        e1 = TRUNC( e1 );
+
+        if ( e1 >= 0 && e1 < ras.target.rows )
+        {
+          long pitch  = ras.target.pitch;
+          long offset = - pitch * e1;
+          
+          if (pitch > 0)
+            offset += (ras.target.rows-1)*pitch;
+            
+          bits[offset] |= f1;
+        }
+      }
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Horizontal_Test_Pixel                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Tests a pixel `light' during the horizontal bitmap sweep.  Used    */
+  /*    during drop-out control only.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y :: The current pixel column.                                     */
+  /*    x :: The current row/scanline.                                     */
+  /*                                                                       */
+  static
+  int   Horizontal_Test_Pixel( RAS_ARG_ int  y,
+                                        int  x )
+  {
+    char*  bits   = (char*)ras.bit_buffer + (y >> 3);
+    int    f1     = (Byte)(0x80 >> (y & 7));
+    long   pitch  = ras.target.pitch;
+    long   offset = - pitch * x;
+    
+    if (pitch > 0)
+      offset += (ras.target.rows-1)*pitch;
+      
+    return ( x >= 0 && x < ras.target.rows && (bits[0] & f1) );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Horizontal_Set_Pixel                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets a single pixel in a bitmap during the horizontal sweep.  Used */
+  /*    during drop-out control.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y     :: The current pixel column.                                 */
+  /*    x     :: The current row/scanline.                                 */
+  /*    color :: Ignored by this function.                                 */
+  /*                                                                       */
+  static
+  void  Horizontal_Set_Pixel( RAS_ARG_ int  y,
+                                       int  x,
+                                       int  color )
+  {
+    char*  bits = (char*)ras.bit_buffer + (y >> 3);
+    int    f1   = (Byte)(0x80 >> (y  & 7));
+
+
+    UNUSED( color );
+
+    if ( x >= 0 && x < ras.target.rows )
+    {
+      long pitch  = ras.target.pitch;
+      long offset = - x*pitch;
+      
+      if (pitch > 0)
+        offset += (ras.target.rows-1)*pitch; 
+
+      bits[offset] |= f1;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Horizontal_Sweep_Step                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Called whenever the sweep jumps to another pixel column.           */
+  /*                                                                       */
+  static
+  void  Horizontal_Sweep_Step( RAS_ARG )
+  {
+    UNUSED( ras.target );
+
+    /* Nothing, really */
+  }
+
+
+  static
+  const  Raster_Render   horizontal_render_mono =
+  {
+    &Horizontal_Sweep_Init,
+    &Horizontal_Sweep_Span,
+    &Horizontal_Sweep_Step,
+    &Horizontal_Test_Pixel,
+    &Horizontal_Set_Pixel
+  };
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /********                                                         ********/
+  /********      Anti-Aliased Vertical Bitmap Sweep Routines        ********/
+  /********                                                         ********/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Gray_Sweep_Init                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes the vertical bitmap sweep.  Called by the generic      */
+  /*    sweep/draw routine before its loop.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    min :: The address of the current minimum scanline.                */
+  /*    max :: The address of the current maximum scanline.                */
+  /*                                                                       */
+  static
+  void  Vertical_Gray_Sweep_Init( RAS_ARG_ int*  min, int*  max )
+  {
+    long  pitch;
+    
+    UNUSED( max );
+
+    pitch          = ras.target.pitch;
+    
+    /* start from the bottom line, going up */
+    ras.trace_incr = -pitch;
+    ras.trace_bit  = - *min * pitch;
+    
+    if (pitch > 0)
+      ras.trace_bit += (ras.target.rows-1)*pitch;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Gray_Sweep_Span                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Draws a single horizontal bitmap span during the vertical bitmap   */
+  /*    sweep.                                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y  :: The current scanline.                                        */
+  /*    x1 :: The left span edge.                                          */
+  /*    x2 :: The right span edge.                                         */
+  /*                                                                       */
+  static
+  void  Vertical_Gray_Sweep_Span( RAS_ARG_ TScan  y,
+                                           TPos   x1,
+                                           TPos   x2 )
+  {
+    TPos      e1, e2;
+    int       shift = ras.precision_bits - 6;
+    PByte  target;
+
+
+    UNUSED( y );
+
+    x1 += ras.precision_half;
+    x2 += ras.precision_half;
+   
+#ifdef FT_RASTER_OPTION_CONTRAST   
+    if ( x2-x1 < ras.precision )
+    {
+	  x1 = ((x1+x2) >> 1) - ras.precision_half;
+	  x2 = x1 + ras.precision;
+	}
+#endif
+        
+    e1 = TRUNC( x1 );
+    e2 = TRUNC( x2 );
+
+    if ( e1 <= e2 && e2 >= 0 && e1 < ras.bit_width )
+    {
+      x1 = FRAC(x1) >> shift;
+      x2 = FRAC(x2) >> shift;
+
+      if ( e1 < 0 )
+      {
+        e1 = 0;
+        x1 = 0;
+      }
+
+      if ( e2 > ras.bit_width )
+      {
+        e2 = ras.bit_width-1;
+        x2 = 0;
+      }
+
+      target = ras.bit_buffer + ras.trace_bit + e1;
+      e2    -= e1;
+      
+      if ( e2 > 0 )
+      {
+        target[0] += (Byte)(64-x1);
+        e2--;
+        while (e2 > 0)
+        {
+          *(++target) += 64;
+          e2--;
+        }
+        if (x2)
+          target[1] += (Byte)x2;
+      }
+      else
+      {
+        target[0] += (Byte)(x2-x1);
+      }
+    }
+  }
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Gray_Test_Pixel                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Tests a pixel `light' during the vertical bitmap sweep.  Used      */
+  /*    during drop-out control only.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y :: The current scanline.                                         */
+  /*    x :: The current x coordinate.                                     */
+  /*                                                                       */
+  static
+  int  Vertical_Gray_Test_Pixel( RAS_ARG_ TScan  y,
+                                          int    x )
+  {
+    UNUSED( y );
+
+#if 0
+    /* as a rule of thumb, do not add a drop-out if the current */
+    /* gray level is over 0.5                                   */
+    
+    return ( x >= 0 && x < ras.bit_width &&
+             ras.bit_buffer[ras.trace_bit + x] >= 64 );
+#else
+    UNUSED(x);
+    return 0;
+#endif
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Gray_Set_Pixel                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets a single pixel in a bitmap during the vertical sweep.  Used   */
+  /*    during drop-out control.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y     :: The current scanline.                                     */
+  /*    x     :: The current x coordinate.                                 */
+  /*    color :: Ignored by this function.                                 */
+  /*                                                                       */
+  static
+  void  Vertical_Gray_Set_Pixel( RAS_ARG_ int  y,
+                                          int  x,
+                                          int  color )
+  {
+    UNUSED( y );
+
+    if ( x >= 0 && x < ras.bit_width )
+    {
+      unsigned char*  pixel;
+      
+      pixel = ras.bit_buffer + ras.trace_bit + x;
+      
+      /* do not add too much to the pixel gray level */
+      color += *pixel;
+      if (color < 64)
+        color = 64;
+
+      *pixel = ( color >= 128 ? 128 : (unsigned char)color );
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Vertical_Sweep_Step                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Called whenever the sweep jumps to another scanline.  Only updates */
+  /*    the pointers in the vertical bitmap sweep.                         */
+  /*                                                                       */
+  static
+  void Vertical_Gray_Sweep_Step( RAS_ARG )
+  {
+    ras.trace_bit += ras.trace_incr;
+  }
+
+
+
+  static
+  const  Raster_Render   vertical_render_gray =
+  {
+    &Vertical_Gray_Sweep_Init,
+    &Vertical_Gray_Sweep_Span,
+    &Vertical_Gray_Sweep_Step,
+    &Vertical_Gray_Test_Pixel,
+    &Vertical_Gray_Set_Pixel
+  };
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /********                                                         ********/
+  /********           Horizontal Bitmap Sweep Routines              ********/
+  /********                                                         ********/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Horizontal_Sweep_Init                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes the horizontal bitmap sweep.  Called by the generic    */
+  /*    sweep/draw routine before its loop.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    min :: The address of the current minimum pixel column.            */
+  /*    max :: The address of the current maximum pixel column.            */
+  /*                                                                       */
+  static
+  void  Horizontal_Gray_Sweep_Init( RAS_ARG_ int*  min,
+                                             int*  max )
+  {
+    UNUSED( ras );
+    UNUSED( min );
+    UNUSED( max );
+
+    /* nothing, really */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Horizontal_Gray_Sweep_Span                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Draws a single vertical bitmap span during the horizontal bitmap   */
+  /*    sweep.                                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y  :: The current scanline.                                        */
+  /*    x1 :: The left span edge.                                          */
+  /*    x2 :: The right span edge.                                         */
+  /*                                                                       */
+  static
+  void  Horizontal_Gray_Sweep_Span( RAS_ARG_ TScan  y,
+                                             TPos   x1,
+                                             TPos   x2 )
+  {
+    TPos      e1, e2;
+    int       shift = ras.precision_bits - 6;
+    int       incr;
+    PByte  bits;
+
+
+    UNUSED( y );
+
+    x1 += ras.precision_half;
+    x2 += ras.precision_half;
+
+#ifdef FT_RASTER_OPTION_CONTRAST   
+    if (x2-x1 < ras.precision)
+	{
+	  x1 = ((x1+x2) >> 1) - ras.precision_half;
+	  x2 = x1 + ras.precision;
+	}
+#endif
+        
+    e1 = TRUNC( x1 );
+    e2 = TRUNC( x2 );
+
+    if ( e1 <= e2 && e2 >= 0 && e1 < ras.bit_width )
+    {
+      x1 = FRAC(x1) >> shift;
+      x2 = FRAC(x2) >> shift;
+
+      if ( e1 < 0 )
+      {
+        e1 = 0;
+        x1 = 0;
+      }
+
+      if ( e2 >= ras.bit_width )
+      {
+        e2 = ras.bit_width;
+        x2 = 0;
+      }
+
+      incr  = -ras.target.pitch;
+      bits  = ras.bit_buffer + y;
+      bits += incr * e1;
+      if (incr < 0)
+        bits -= incr*(ras.target.rows-1); 
+
+      e2 -= e1;
+      
+      if ( e2 > 0 )
+      {
+        bits[0] += (Byte)(64-x1);
+        e2--;
+        while (e2 > 0)
+        {
+          bits    += incr;
+          bits[0] += 64;
+          e2--;
+        }
+        if (x2)
+          bits[incr] += (Byte)x2;
+      }
+      else
+      {
+        bits[0] += (Byte)(x2-x1);
+      }
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Horizontal_Gray_Test_Pixel                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Tests a pixel `light' during the horizontal bitmap sweep.  Used    */
+  /*    during drop-out control only.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y :: The current pixel column.                                     */
+  /*    x :: The current row/scanline.                                     */
+  /*                                                                       */
+  static
+  int   Horizontal_Gray_Test_Pixel( RAS_ARG_ int  y,
+                                             int  x )
+  {
+#if 0
+    unsigned char*  pixel = (unsigned char*)ras.bit_buffer + y;
+
+    if ( ras.target.flow == Flow_Down )
+      pixel += (ras.target.rows-1 - x) * ras.target.cols;
+    else
+      pixel += x * ras.target.cols;
+
+    return ( x >= 0 && x < ras.target.rows &&
+            *pixel >= 64 );
+#else
+    UNUSED(y);
+    UNUSED(x);
+    return 0;
+#endif
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Horizontal_Set_Pixel                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets a single pixel in a bitmap during the horizontal sweep.  Used */
+  /*    during drop-out control.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    y     :: The current pixel column.                                 */
+  /*    x     :: The current row/scanline.                                 */
+  /*    color :: Ignored by this function.                                 */
+  /*                                                                       */
+  static
+  void  Horizontal_Gray_Set_Pixel( RAS_ARG_ int  y,
+                                            int  x,
+                                            int  color )
+  {
+    unsigned char*  pixel = (unsigned char*)ras.bit_buffer + y;
+
+    if ( x >= 0 && x < ras.target.rows )
+    {
+      long  pitch  = ras.target.pitch;
+      
+      pixel -= pitch*x;
+      if (pitch > 0)
+        pixel += pitch*(ras.target.rows-1); 
+
+      color += *pixel;
+      if (color < 64)
+        color = 64;
+
+      *pixel = (color >= 128 ? 128 : (unsigned char)color );
+    }
+  }
+
+
+  static
+  void Gray_Ignore( void )
+  {
+    ;
+  }
+
+
+  static
+  const  Raster_Render   horizontal_render_gray =
+  {
+    &Horizontal_Gray_Sweep_Init,
+    &Horizontal_Gray_Sweep_Span,
+
+    (Function_Sweep_Step)  &Gray_Ignore,
+    &Horizontal_Gray_Test_Pixel,
+    &Horizontal_Gray_Set_Pixel,
+  };
+
+#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* A technical note to explain how the scanline sweep is performed:      */
+  /*                                                                       */
+  /*   The function Draw_Sweep() is used to sweep the scanlines of the     */
+  /*   target bitmap or pixmap.  For each scanline, it must do the         */
+  /*   following:                                                          */
+  /*                                                                       */
+  /*   - Get the set of all outline intersections for the current          */
+  /*     scanline.                                                         */
+  /*                                                                       */
+  /*   - Sort these intersections (in increasing order).                   */
+  /*                                                                       */
+  /*   - Pair intersections to create spans (horizontal pixel segments)    */
+  /*     that are then `drawn' by calling a `sweep_span' function.         */
+  /*                                                                       */
+  /*   - Check for dropouts: If a span is too small to be drawn, it must   */
+  /*     be re-adjusted in order to make it visible again.                 */
+  /*                                                                       */
+  /*   The sweep starts from the bottom of the outline (ymin) and goes     */
+  /*   upwards (to ymax).  Thus, the function manages the following:       */
+  /*                                                                       */
+  /*   - A linked list of the profiles which are above the current         */
+  /*     scanline.  It is called the `wait' list as it contains all the    */
+  /*     profiles waiting to be `activated' during the sweep.  It contains */
+  /*     all profiles initially.                                           */
+  /*                                                                       */
+  /*   - A linked list of the profiles covering the current scanline,      */
+  /*     i.e., all the profiles that contain an intersection for the       */
+  /*     current scanline.  It is called the `draw' list.                  */
+  /*                                                                       */
+  /*   A profile travels from the wait list to the draw list if the        */
+  /*   current scanline reaches its bottom border (its ymin).  It is also  */
+  /*   removed from the draw list (and becomes unlisted) when the current  */
+  /*   scanline reaches the scanline above its upper border (its ymax).    */
+  /*                                                                       */
+  /*   These positions correspond to the `extrema' table built by          */
+  /*   Finalize_Profile_Table().                                           */
+  /*                                                                       */
+  /*   The draw list is always sorted in increasing order of the X         */
+  /*   coordinates.  We use a bubble sort because it is easy to implement  */
+  /*   on a linked list, and because in 95% cases, the list is already     */
+  /*   correctly sorted when going from one scanline to the other.         */
+  /*                                                                       */
+  /*   The extrema table gives the scanline coordinates at which at least  */
+  /*   one profile must be removed from the `draw' list, or another one    */
+  /*   must be moved from the `wait' to `draw' lists.                      */
+  /*                                                                       */
+  /*   Note that when a dropout is detected, the corresponding span is not */
+  /*   drawn immediately but kept on a temporary list.  All dropout spans  */
+  /*   are drawn after the regular spans on a given scanline.  This is a   */
+  /*   requirement of the TrueType specification to properly implement     */
+  /*   some drop-out control modes -- yes, it's weird!                     */
+  /*                                                                       */
+  /*   Finally, the parser contains four function pointers that are called */
+  /*   by Draw_Sweep().  Each rendering mode (monochrome, anti-aliased-5,  */
+  /*   and anti-aliased-17) provide its own set of such functions.  These  */
+  /*   are:                                                                */
+  /*                                                                       */
+  /*     sweep_init:       Called only when the sweep starts.  Used to set */
+  /*                       up some variables.                              */
+  /*                                                                       */
+  /*     sweep_span:       Used to draw a horizontal span on the current   */
+  /*                       scanline.                                       */
+  /*                                                                       */
+  /*     sweep_test_pixel: Used to test a pixel's intensity, as it is      */
+  /*                       required for drop-out control.                  */
+  /*                                                                       */
+  /*     sweep_put_pixel:  Used to write a single pixel when a drop-out    */
+  /*                       needs to be lighted/drawn.                      */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  Generic Sweep Drawing routine                                        */
+  /*                                                                       */
+  static
+  TResult  Draw_Sweep( RAS_ARG )
+  {
+    TScan  y, y_change, y_height;
+
+    PProfile  P, Q, P_Left, P_Right;
+
+    TScan   min_Y, max_Y, top, bottom, dropouts;
+
+    TPos x1, x2, e1, e2;
+
+    TProfileList  wait;
+    TProfileList  draw;
+
+
+    /* Init empty linked lists */
+    Init_Linked( &wait );
+    Init_Linked( &draw );
+
+    /* first, compute min and max Y -- and add profiles to the wait list */
+    P     = ras.start_prof;
+    max_Y = TRUNC( ras.minY );
+    min_Y = TRUNC( ras.maxY );
+
+    while ( P )
+    {
+      Q = P->link;
+
+      bottom = P->start;
+      top    = P->start + P->height-1;
+
+      if ( min_Y > bottom ) min_Y = bottom;
+      if ( max_Y < top    ) max_Y = top;
+
+      P->X = 0;
+      InsNew( &wait, P );
+
+      P = Q;
+    }
+
+    /* Check the extrema table */
+    if ( ras.n_extrema == 0 )
+    {
+      ras.error = ErrRaster_Invalid_Outline;
+      return FAILURE;
+    }
+
+    /* Now inits the sweep */
+    PTRACE2(( "draw_sweep: initialize sweep\n" ));
+    ras.render.init( RAS_VAR_  &min_Y, &max_Y );
+    PTRACE2(( "  init min_y = %d, max_y = %d\n", min_Y, max_Y ));
+
+    /* Then compute the distance of each profile from min_Y */
+    P = wait;
+    while ( P )
+    {
+      P->countL = P->start - min_Y;
+      P = P->link;
+    }
+
+    /* Let's go */
+    y        = min_Y;
+    y_height = 0;
+
+    if ( ras.n_extrema > 0 &&
+         ras.pool_size[-ras.n_extrema] == min_Y )
+      ras.n_extrema--;
+
+    PTRACE2(( "starting loop with n_extrema = %d", ras.n_extrema ));
+    while ( ras.n_extrema > 0 )
+    {
+      PProfile  prof = wait;
+
+
+      /* look in the wait list for new activations */
+      while ( prof )
+      {
+        PProfile  next = prof->link;
+
+
+        prof->countL -= y_height;
+        if ( prof->countL == 0 )
+        {
+          /* move the profile from the wait list to the draw list */
+          DelOld( &wait, prof );
+          InsNew( &draw, prof );
+        }
+        prof = next;
+      }
+
+      /* Sort the draw list */
+      Sort( &draw );
+
+      /* compute next y extremum scanline; we won't change the */
+      /* elements of the wait and draw lists until there       */
+      y_change = ras.pool_size[-ras.n_extrema--];
+      y_height = y_change - y;
+
+      PTRACE2(( ">>> y = %d, y_change = %d, y_height = %d",
+                y, y_change, y_height ));
+
+      while ( y < y_change )
+      {
+        int       window;
+        PProfile  left;
+
+
+        /* Let's trace */
+        dropouts = 0;
+
+        /* skip to next line if there is no active profile there */
+        if ( !draw ) goto Next_Line;
+
+        left   = draw;
+        window = left->flow;
+        prof   = left->link;
+
+        PTRACE2(( ">>>  line y = %d", y ));
+
+        while ( prof )
+        {
+          PProfile  next = prof->link;
+
+
+          window += prof->flow;
+
+          if ( window == 0 )
+          {
+            x1 = left->X;
+            x2 = prof->X;
+
+            if ( x1 > x2 )
+            {
+              TPos  xs = x1;
+
+
+              x1 = x2;
+              x2 = xs;
+            }
+
+            if ( x2 - x1 <= ras.precision && ras.dropout_mode )
+            {
+              e1 = CEILING( x1 );
+              e2 = FLOOR( x2 );
+
+              if ( e1 > e2 || e2 == e1 + ras.precision )
+              {
+                /* a drop out was detected */
+
+                left->X = x1;
+                prof->X = x2;
+
+                /* mark profiles for drop-out processing */
+                left->countL = 1;
+                prof->countL = 2;
+                dropouts++;
+                goto Skip_To_Next;
+              }
+            }
+
+            PTRACE2(( "drawing span ( y=%d, x1=%d, x2=%d )",
+                      y, x1, x2 ));
+            ras.render.span( RAS_VAR_  y, x1, x2 );
+
+   Skip_To_Next:
+            left = next;
+          }
+          prof = next;
+        }
+
+        /* now perform the dropouts _after_ the span drawing   */
+        /* drop-outs processing has been moved out of the loop */
+        /* for performance tuning                              */
+        if ( dropouts > 0 )
+          goto Scan_DropOuts;
+
+   Next_Line:
+        ras.render.step( RAS_VAR );
+
+        y++;
+
+        if ( y < y_change )
+          Sort( &draw );
+
+        PTRACE2(( "line sorted for next operation" ));
+      }
+
+      /* Now finalize the profiles that needs it */
+
+      PTRACE2(( "finalizing profiles..." ));
+      {
+        PProfile  prof, next;
+
+
+        prof = draw;
+        while ( prof )
+        {
+          next = prof->link;
+          if (prof->height == 0)
+            DelOld( &draw, prof );
+          prof = next;
+        }
+      }
+
+      PTRACE2(( "profiles finalized for this run" ));
+    }
+
+    /* for gray-scaling, flushes the bitmap scanline cache */
+    while ( y <= max_Y )
+    {
+        ras.render.step( RAS_VAR );
+        y++;
+    }
+
+    return SUCCESS;
+
+
+Scan_DropOuts :
+    P_Left = draw;
+
+
+    while ( dropouts > 0 )
+    {
+      TPos      e1,   e2;
+      PProfile  left, right;
+
+
+      while ( P_Left->countL != 1 )
+        P_Left = P_Left->link;
+      P_Right = P_Left->link;
+      while ( P_Right->countL != 2 )
+        P_Right = P_Right->link;
+
+      P_Left->countL  = 0;
+      P_Right->countL = 0;
+
+      /* Now perform the dropout control */
+      x1 = P_Left->X;
+      x2 = P_Right->X;
+
+      left  = ( ras.flipped ? P_Right : P_Left  );
+      right = ( ras.flipped ? P_Left  : P_Right );
+
+      PTRACE2(( "performing drop-out control ( x1= %d, x2 = %d )",
+                x1, x2 ));
+
+      e1 = CEILING( x1 );
+      e2 = FLOOR  ( x2 );
+
+      if ( e1 > e2 )
+      {
+        if ( e1 == e2 + ras.precision )
+        {
+          switch ( ras.dropout_mode )
+          {
+          case 1:
+            e1 = e2;
+            break;
+
+          case 4:
+            e1 = CEILING( (x1 + x2 + 1) / 2 );
+            break;
+
+          case 2:
+          case 5:
+            /* Drop-out Control Rule #4 */
+
+            /* The spec is not very clear regarding rule #4.  It      */
+            /* presents a method that is way too costly to implement  */
+            /* while the general idea seems to get rid of `stubs'.    */
+            /*                                                        */
+            /* Here, we only get rid of stubs recognized when:        */
+            /*                                                        */
+            /*  upper stub:                                           */
+            /*                                                        */
+            /*   - P_Left and P_Right are in the same contour         */
+            /*   - P_Right is the successor of P_Left in that contour */
+            /*   - y is the top of P_Left and P_Right                 */
+            /*                                                        */
+            /*  lower stub:                                           */
+            /*                                                        */
+            /*   - P_Left and P_Right are in the same contour         */
+            /*   - P_Left is the successor of P_Right in that contour */
+            /*   - y is the bottom of P_Left                          */
+            /*                                                        */
+
+            /* upper stub test */
+            if ( ( left->next == right && left->height <= 0 ) ||
+
+            /* lower stub test */
+                 ( right->next == left && left->start == y )  ||
+
+            /* check that the rightmost pixel isn't set */
+                 ras.render.test_pixel( RAS_VAR_  y, TRUNC(e1))       )
+              goto Next_Dropout;
+
+            if ( ras.dropout_mode == 2 )
+              e1 = e2;
+            else
+              e1 = CEILING( (x1 + x2 + 1)/2 );
+
+            break;
+
+          default:
+            goto Next_Dropout;  /* Unsupported mode */
+          }
+        }
+        else
+          goto Next_Dropout;
+      }
+
+      PTRACE2(( "  -> setting pixel" ));
+      ras.render.set_pixel( RAS_VAR_ y,
+                            TRUNC( e1 ),
+                            (x2 - x1) >> ras.scale_shift );
+    Next_Dropout:
+
+      dropouts--;
+    }
+    goto Next_Line;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Render_Single_Pass                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Performs one sweep with sub-banding.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    flipped :: whether or not we have to flip.                         */
+  /*                                                                       */
+  /* <Returns>                                                             */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  static
+  int  Render_Single_Pass( RAS_ARG_ int  flipped )
+  {
+    TBand*  band;
+
+
+    ras.flipped = flipped;
+
+    band = ras.band_stack;
+
+    PTRACE2(( "raster: entering render_single_pass (flipped = %d)\n",
+              flipped ));
+
+    while ( band >= ras.band_stack )
+    {
+      ras.maxY = ((long)band[0].y_max << (ras.scale_shift+6)) - 1;
+
+      ras.minY = (long)band[0].y_min << (ras.scale_shift+6);
+
+      ras.cursor = ras.pool;
+      ras.error  = 0;
+
+      PTRACE2(( "raster: band = [ %d, %d ]\n",
+                band[0].y_min,
+                band[0].y_max ));
+
+      if ( Convert_Glyph( RAS_VAR_  ras.outline ) )
+      {
+        int  bottom, top, half;
+
+
+        if ( ras.error != ErrRaster_Overflow )
+          return FAILURE;
+        ras.error = ErrRaster_Ok;
+
+        PTRACE2(( "conversion failure, performing sub-banding\n" ));
+
+        /* sub-banding */
+
+#ifdef DEBUG_RASTER
+        ClearBand( RAS_VAR_  TRUNC( ras.minY ), TRUNC( ras.maxY ) );
+#endif
+
+        bottom = band[0].y_min;
+        top    = band[0].y_max;
+        half   = ( top - bottom ) >> 1;
+
+        if ( band >= ras.band_stack + 7 || half == 0 )
+        {
+          ras.band_top = 0;
+          ras.error    = ErrRaster_Invalid_Outline;
+          return ras.error;
+        }
+
+        band[1].y_min = bottom + half;
+        band[1].y_max = top;
+        band[0].y_max = bottom + half;
+
+        band ++;
+      }
+      else
+      {
+        PTRACE2(( "conversion succeeded, span drawing sweep\n" ));
+        if ( ras.start_prof )
+          if ( Draw_Sweep( RAS_VAR ) )
+            return ras.error;
+        band --;
+      }
+    }
+
+    PTRACE2(( "raster: exiting render_single_pass\n" ));
+
+    return SUCCESS;  /* success */
+  }
+
+
+  static
+  int  Raster_Render1( FT_Raster  raster )
+  {
+    int  error;
+
+
+    if ( ras.target.width > ABS(ras.target.pitch)*8 )
+      return ErrRaster_Invalid_Map;
+
+    ras.scale_shift  = ras.precision_bits - 6;
+    ras.scale_delta  = ras.precision_half;
+
+    /* Vertical Sweep */
+    ras.band_top            = 0;
+    ras.band_stack[0].y_min = 0;
+    ras.band_stack[0].y_max = ras.target.rows;
+
+    ras.render     = vertical_render_mono;
+    ras.bit_width  = ras.target.width;
+    ras.bit_buffer = (unsigned char*)ras.target.buffer;
+
+    if ( (error = Render_Single_Pass( RAS_VAR_ 0 )) != 0 )
+      return error;
+
+    /* Horizontal Sweep */
+
+    if ( ras.second_pass && ras.dropout_mode != 0 )
+    {
+      ras.render              = horizontal_render_mono;
+      ras.band_top            = 0;
+      ras.band_stack[0].y_min = 0;
+      ras.band_stack[0].y_max = ras.target.width;
+
+      if ( (error = Render_Single_Pass( RAS_VAR_  1 )) != 0 )
+        return error;
+    }
+
+    return ErrRaster_Ok;
+  }
+
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+
+
+  static
+  int  Raster_Render8( FT_Raster  raster )
+  {
+    int  error;
+
+    if ( ras.target.width > ABS(ras.target.pitch) )
+      return ErrRaster_Invalid_Map;
+
+    /* Vertical Sweep */
+    ras.band_top            = 0;
+    ras.band_stack[0].y_min = 0;
+    ras.band_stack[0].y_max = ras.target.rows;
+
+    ras.scale_shift  = (ras.precision_bits-6);
+    ras.scale_delta  = ras.precision_half;
+    ras.dropout_mode = 2;
+
+    ras.render     = vertical_render_gray;
+    ras.bit_width  = ras.target.width;
+    ras.bit_buffer = (unsigned char*)ras.target.buffer;
+    ras.pix_buffer = (unsigned char*)ras.target.buffer;
+
+    error = Render_Single_Pass( RAS_VAR_  0 );
+    if ( error )
+      return error;
+
+#if 1
+    /* Horizontal Sweep */
+    ras.render              = horizontal_render_gray;
+    ras.band_top            = 0;
+    ras.bit_width           = ras.target.rows;
+    ras.band_stack[0].y_min = 0;
+    ras.band_stack[0].y_max = ras.target.width;
+
+    return Render_Single_Pass( RAS_VAR_  1 );
+#else
+    return 0;
+#endif
+  }
+
+
+#else  /* FT_RASTER_OPTION_ANTI_ALIAS */
+
+
+  static
+  int  Raster_Render8( FT_Raster  raster )
+  {
+    return ErrRaster_Unimplemented;
+  }
+
+
+#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Raster_Render                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Renders an outline into a target bitmap.                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    raster  :: A handle to the raster object used during rendering.    */
+  /*    outline :: A pointer to the source outline record/object.          */
+  /*    bitmap  :: A pointer to the target bitmap descriptor.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code, interpreted as a FT_Error by FreeType.  0 means        */
+  /*    success.                                                           */
+  /*                                                                       */
+  EXPORT_FUNC
+  int  FT_Raster_Render( FT_Raster    raster,
+                         FT_Outline*  outline,
+                         FT_Bitmap*   target_map )
+  {
+    if ( !raster || !raster->pool || !raster->pool_size )
+      return ErrRaster_Uninitialized_Object;
+
+    /* return immediately if the outline is empty */
+    if ( outline->n_points == 0 || outline->n_contours <= 0 )
+      return ErrRaster_Ok;
+
+    if ( !outline || !outline->contours || !outline->points )
+      return ErrRaster_Invalid_Outline;
+
+    if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 )
+      return ErrRaster_Invalid_Outline;
+
+    if ( !target_map || !target_map->buffer )
+      return ErrRaster_Invalid_Map;
+
+    ras.outline  = outline;
+    ras.target   = *target_map;
+
+    ras.dropout_mode = outline->dropout_mode;
+    ras.second_pass  = outline->second_pass;
+    SET_High_Precision( outline->high_precision );
+
+    switch ( target_map->pixel_mode )
+    {
+    case ft_pixel_mode_mono:
+      return Raster_Render1( raster );
+    case ft_pixel_mode_grays:
+      return Raster_Render8( raster );
+
+    default:
+      return ErrRaster_Unimplemented;
+    }
+  }
+
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Reset_Palette_5                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Resets lookup table when the 5-gray-levels palette changes.        */
+  /*                                                                       */
+  static
+  void  Reset_Palette_5( RAS_ARG )
+  {
+
+
+#ifdef FT_RASTER_ANY_ENDIAN
+
+
+    int  i, j, l, c;
+
+
+    for ( i = 0; i < 256; i++ )
+    {
+      l = 0;
+      j = i;
+
+      for ( c = 0; c < 4; c++ )
+      {
+        l <<= 4;
+
+        if ( j & 0x80 ) l++;
+        if ( j & 0x40 ) l++;
+
+        j = ( j << 2 ) & 0xFF;
+      }
+
+      ras.count_table[i] = l;
+    }
+
+
+#else /* FT_RASTER_ANY_ENDIAN */
+
+
+    int  i;
+
+
+    for ( i = 0; i < 256; i++ )
+    {
+      int  cnt1, cnt2;
+
+      cnt1 = ((i & 128) >> 7) +
+             ((i & 64)  >> 6) +
+             ((i & 8)   >> 3) +
+             ((i & 4)   >> 2);
+
+      cnt2 = ((i & 32) >> 5) +
+             ((i & 16) >> 4) +
+             ((i & 2)  >> 1) +
+              (i & 1);
+
+    /*                                                                 */
+    /* Note that when the endianess isn't specified through one of the */
+    /* configuration, we use the big-endian storage in `count_table'   */
+    /*                                                                 */
+
+#if defined( FT_RASTER_LITTLE_ENDIAN )
+      ras.count_table[i] = (ras.grays[cnt2] << 8) | ras.grays[cnt1];
+#else
+      ras.count_table[i] = (ras.grays[cnt1] << 8) | ras.grays[cnt2];
+#endif
+    }
+
+
+#endif /* FT_RASTER_ANY_ENDIAN */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Reset_Palette_17                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Resets lookup table when 17-gray-levels palette changes.           */
+  /*                                                                       */
+#ifdef FT_RASTER_ANTI_ALIAS_17
+
+
+  static
+  void  Reset_Palette_17( RAS_ARG )
+  {
+    int  i;
+
+
+    for ( i = 0; i < 256; i++ )
+      ras.count_table[i] = ((i & 128) >> 7) +
+                           ((i &  64) >> 6) +
+                           ((i &   8) >> 3) +
+                           ((i &   4) >> 2) +
+                           ((i &  32) >> 5) +
+                           ((i &  16) >> 4) +
+                           ((i &   2) >> 1) +
+                            (i &   1);
+}
+
+
+#endif /* FT_RASTER_ANTI_ALIAS_17 */
+
+
+#endif /* TT_RASTER_OPTION_ANTI_ALIAS */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Raster_ObjSize                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function returns the size of a raster object in bytes.        */
+  /*    Client applications are thus able to allocate objects in their own */
+  /*    heap/memory space, without revealing the internal structures of    */
+  /*    the scan-line converter.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The size in bytes of a single raster object.                       */
+  /*                                                                       */
+  EXPORT_FUNC
+  long  FT_Raster_ObjSize( void )
+  {
+    return (long)sizeof( struct FT_RasterRec_ );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Raster_Init                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a fresh raster object which should have been allocated */
+  /*    by client applications.  This function is also used to set the     */
+  /*    object's render pool.  It can be used repeatedly on a single       */
+  /*    object if one wants to change the pool's address or size.          */
+  /*                                                                       */
+  /*    Note that the render pool has no state and is only used during a   */
+  /*    call to FT_Raster_Render().  It is thus theorically possible to    */
+  /*    share it between several non-concurrent components of your         */
+  /*    applications when memory is a scarce resource.                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    pool_size :: The render pool's size in bytes.  This must be at     */
+  /*                 least 4 kByte.                                        */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    raster    :: A handle to the target raster object.                 */
+  /*                                                                       */
+  /*    pool_base :: The render pool's base address in memory.             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    An error condition, used as a FT_Error in the FreeType library.    */
+  /*    0 means success.                                                   */
+  /*                                                                       */
+  EXPORT_FUNC
+  int  FT_Raster_Init( FT_Raster    raster,
+                       const char*  pool_base,
+                       long         pool_size )
+  {
+/*    static const char  default_palette[5] = { 0, 1, 2, 3, 4 }; */
+
+    /* check the object address */
+    if ( !raster )
+      return ErrRaster_Uninitialized_Object;
+
+    /* check the render pool - we won't go under 4 Kb */
+    if ( !pool_base || pool_size < 4096 )
+      return ErrRaster_Invalid_Pool;
+
+    /* save the pool */
+    raster->pool      = (PPos)pool_base;
+    raster->pool_size = raster->pool + pool_size / sizeof ( TPos );
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+    raster->gray_width = ANTI_ALIAS_BUFFER_SIZE/2;
+    /* clear anti-alias intermediate lines */
+    {
+      char*  p     = raster->gray_lines;
+      char*  limit = p + ANTI_ALIAS_BUFFER_SIZE; 
+
+      do *p++ = 0; while ( p < limit );
+    }
+#endif
+
+#if 0
+    /* set the default palette: 5 levels = 0, 1, 2, 3, and 4 */
+    FT_Raster_SetPalette( raster, 5, default_palette );
+#endif
+
+    return ErrRaster_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Raster_SetPalette                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets the pixmap rendering palette.  Anti-aliasing modes are        */
+  /*    implemented/possible, they differ from the number of entries in    */
+  /*    the palette.                                                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    count   :: The number of palette entries.  Valid values are 2, 5,  */
+  /*               and 17, which are the number of intermediate gray       */
+  /*               levels supported.                                       */
+  /*                                                                       */
+  /*    palette :: An array of `count' chars giving the 8-bit palette of   */
+  /*               intermediate `gray' levels for anti-aliased rendering.  */
+  /*                                                                       */
+  /*               In all modes, palette[0] corresponds to the background, */
+  /*               while palette[count-1] to the foreground.  Hence, a     */
+  /*               count of 2 corresponds to no anti-aliasing; a count of  */
+  /*               5 uses 3 intermediate levels between the background and */
+  /*               foreground, while a count of 17 uses 15 of them.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    An error code, used as a FT_Error by the FreeType library.         */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    By default, a new object uses mode 5, with a palette of 0, 1, 2,   */
+  /*    3, and 4.  You don't need to set the palette if you don't need to  */
+  /*    render pixmaps.                                                    */
+  /*                                                                       */
+  EXPORT_FUNC
+  int   FT_Raster_SetPalette( FT_Raster    raster,
+                              int          count,
+                              const char*  palette )
+  {
+    switch ( count )
+    {
+#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+
+
+      /******************************/
+      /* The case of 17 gray levels */
+      /******************************/
+
+      case 17:
+#ifdef FT_RASTER_ANTI_ALIAS_17
+      {
+        int  n;
+
+
+        raster->grays_count = count;
+        for ( n = 0; n < count; n++ )
+          raster->grays[n] = (unsigned char)palette[n];
+        Reset_Palette_17( RAS_VAR );
+        break;
+      }
+#else
+      return ErrRaster_Unimplemented;
+#endif
+
+      /*****************************/
+      /* The case of 5 gray levels */
+      /*****************************/
+
+      case 5:
+#ifdef FT_RASTER_ANTI_ALIAS_5
+      {
+        int  n;
+
+
+        raster->grays_count = count;
+        for ( n = 0; n < count; n++ )
+          raster->grays[n] = (unsigned char)palette[n];
+        Reset_Palette_5( RAS_VAR );
+        break;
+      }
+#else
+      return ErrRaster_Unimplemented;
+#endif
+
+
+#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+      default:
+        return ErrRaster_Bad_Palette_Count;
+    }
+
+    return ErrRaster_Ok;
+  }
+
+  FT_Raster_Interface  ft_default_raster =
+  {
+    sizeof( struct FT_RasterRec_ ),
+    ft_glyph_format_outline,
+    
+    (FT_Raster_Init_Proc)     FT_Raster_Init,
+    (FT_Raster_Set_Mode_Proc) 0,
+    (FT_Raster_Render_Proc)   FT_Raster_Render    
+  };
+
+
+/* END */
diff --git a/src/base/ftstream.c b/src/base/ftstream.c
new file mode 100644
index 0000000..f373c66
--- /dev/null
+++ b/src/base/ftstream.c
@@ -0,0 +1,436 @@
+#include <ftstream.h>
+#include <ftdebug.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_stream
+
+
+  BASE_FUNC
+  void  FT_New_Memory_Stream( FT_Library     library,
+                              void*          base,
+     			      unsigned long  size,
+                              FT_Stream      stream )
+  {
+    stream->memory = library->memory;
+    stream->base   = (char*)base;
+    stream->size   = size;
+    stream->pos    = 0;
+    stream->cursor = 0;
+    stream->read   = 0;
+    stream->close  = 0;
+  }
+
+
+  BASE_FUNC
+  FT_Error  FT_Seek_Stream( FT_Stream  stream,
+                            FT_ULong   pos )
+  {
+    FT_Error  error;
+    
+    stream->pos = pos;
+    
+    if (stream->read)
+    {
+      if (stream->read( stream, pos, 0, 0 ))
+      {
+        error = FT_Err_Invalid_Stream_Operation;
+
+        FT_ERROR(( "FT_Seek_Stream:" ));
+        FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx\n",
+                   pos, stream->size ));
+      }
+      else
+        error = FT_Err_Ok;
+    }
+    /* note that seeking to the first position after the file is valid */
+    else if (pos > stream->size)
+    {
+      error = FT_Err_Invalid_Stream_Operation;
+
+      FT_ERROR(( "FT_Seek_Stream:" ));
+      FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx\n",
+                 pos, stream->size ));
+    }
+ 
+    else
+      error = FT_Err_Ok;
+ 
+    return error; 
+  }
+  
+  
+  BASE_FUNC
+  FT_Error  FT_Skip_Stream( FT_Stream  stream,
+                            FT_Long    distance )
+  {
+    return FT_Seek_Stream( stream, (FT_ULong)(stream->pos + distance) );
+  }
+  
+  
+  
+  BASE_FUNC
+  FT_Long   FT_Stream_Pos( FT_Stream  stream )
+  {
+    return stream->pos;
+  }
+  
+  
+  BASE_FUNC
+  FT_Error  FT_Read_Stream( FT_Stream  stream,
+                            void*      buffer,
+                            FT_ULong   count )
+  {
+    return FT_Read_Stream_At( stream, stream->pos, buffer, count );
+  }
+  
+  
+  BASE_FUNC
+  FT_Error  FT_Read_Stream_At( FT_Stream  stream,
+                               FT_ULong   pos,
+                               void*      buffer,
+                               FT_ULong   count )
+  {
+    FT_Error  error = FT_Err_Ok;
+    FT_ULong  read_bytes;
+    
+    if (pos >= stream->size)
+    {
+      FT_ERROR(( "FT_Read_Stream_At:" ));
+      FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx\n",
+                 pos, stream->size ));
+ 
+      return FT_Err_Invalid_Stream_Operation;
+    }
+ 
+    if (stream->read)
+      read_bytes = stream->read( stream, pos, buffer, count );
+    else
+    {
+      read_bytes = stream->size - pos;
+      if (read_bytes > count)
+        read_bytes = count;
+      
+      MEM_Copy( buffer, stream->base + pos, read_bytes );
+    }
+    
+    stream->pos = pos + read_bytes;
+
+    if (read_bytes < count)
+    {
+      FT_ERROR(( "FT_Read_Stream_At:" ));
+      FT_ERROR(( " invalid read, expected %lu bytes, got %lu",
+                 count, read_bytes ));
+      error = FT_Err_Invalid_Stream_Operation;
+    }
+
+    return error;
+  }
+  
+  
+  
+  BASE_FUNC
+  FT_Error  FT_Access_Frame( FT_Stream  stream,
+                             FT_ULong   count )
+  {
+    FT_Error  error = FT_Err_Ok;
+    FT_ULong  read_bytes;
+
+    /* check for nested frame access */
+    FT_Assert( stream && stream->cursor == 0 );    
+     
+    if (stream->read)
+    {
+      /* allocate the frame in memory */
+      FT_Memory  memory = stream->memory;
+        
+      if ( ALLOC( stream->base, count ) )
+        goto Exit;
+          
+      /* read it */
+      read_bytes = stream->read( stream, stream->pos,
+                                 stream->base, count ); 
+      if (read_bytes < count)
+      {
+        FT_ERROR(( "FT_Access_Frame:" ));
+        FT_ERROR(( " invalid read, expected %lu bytes, got %lu",
+                   count, read_bytes ));
+                   
+        FREE( stream->base );
+        error = FT_Err_Invalid_Stream_Operation;
+      }
+      stream->cursor = stream->base;
+      stream->limit  = stream->cursor + count;
+      stream->pos   += read_bytes;
+    }
+    else
+    {
+      /* check current and new position */
+      if (stream->pos >= stream->size || stream->pos + count > stream->size)
+      {
+        FT_ERROR(( "FT_Access_Frame:" ));
+        FT_ERROR(( " invalid i/o, pos = 0x%lx, count = %lu, size = 0x%lx",
+                   stream->pos, count, stream->size ));
+                   
+        error = FT_Err_Invalid_Stream_Operation;
+        goto Exit;
+      }
+      
+      /* set cursor */
+      stream->cursor = stream->base + stream->pos;      
+      stream->limit  = stream->cursor + count;
+      stream->pos   += count;
+    }
+  Exit:
+    return error;
+  }
+  
+  
+  BASE_FUNC
+  void  FT_Forget_Frame( FT_Stream  stream )
+  {
+    FT_Assert( stream && stream->cursor != 0 );
+    
+    if (stream->read)
+    {
+      FT_Memory  memory = stream->memory;
+      
+      FREE( stream->base );
+    }
+    stream->cursor = 0;
+    stream->limit  = 0;
+  }
+
+
+  BASE_FUNC
+  FT_Char  FT_Get_Char( FT_Stream  stream )
+  {
+    FT_Char  result;
+    
+    FT_Assert( stream && stream->cursor && stream->cursor );
+
+    result = 0;
+    if (stream->cursor < stream->limit)    
+      result = *stream->cursor++;
+      
+    return result;
+  }
+  
+  
+  BASE_FUNC
+  FT_Short  FT_Get_Short( FT_Stream  stream )
+  {
+    char*     p;
+    FT_Short  result;
+    
+    FT_Assert( stream && stream->cursor );
+    
+    result         = 0;
+    p              = stream->cursor;
+    if (p+1 < stream->limit)
+      result       = NEXT_Short(p);
+    stream->cursor = p;
+    return result;
+  }
+  
+
+  BASE_FUNC
+  FT_Long  FT_Get_Offset( FT_Stream  stream )
+  {
+    char*    p;
+    FT_Long  result;
+    
+    FT_Assert( stream && stream->cursor );
+    
+    result         = 0;
+    p              = stream->cursor;
+    if (p+2 < stream->limit)
+      result       = NEXT_Offset(p);
+    stream->cursor = p;
+    return result;
+  }
+  
+
+  BASE_FUNC
+  FT_Long  FT_Get_Long( FT_Stream  stream )
+  {
+    char*    p;
+    FT_Long  result;
+    
+    FT_Assert( stream && stream->cursor );
+
+    result         = 0;    
+    p              = stream->cursor;
+    if (p+3 < stream->limit)
+      result       = NEXT_Long(p);
+    stream->cursor = p;
+    return result;
+  }
+  
+ 
+  BASE_FUNC
+  FT_Char  FT_Read_Char( FT_Stream  stream,
+                         FT_Error*  error )
+  {
+    char  result = 0;
+    
+    FT_Assert( stream );
+    
+    *error = FT_Err_Ok;
+    
+    if (stream->read)
+    {
+      if ( stream->read( stream, stream->pos, &result, 1L ) != 1L )
+        goto Fail;
+    }
+    else
+    {
+      if (stream->pos < stream->size)
+        result = stream->base[stream->pos++];
+      else
+        goto Fail;
+    }
+    return result;
+    
+  Fail:
+    *error = FT_Err_Invalid_Stream_Operation;
+    FT_ERROR(( "FT_Read_Char:" ));
+    FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx",
+               stream->pos, stream->size ));
+    return 0;
+  }
+ 
+
+  BASE_FUNC
+  FT_Short  FT_Read_Short( FT_Stream  stream,
+                           FT_Error*  error )
+  {
+    char     reads[2];
+    char*    p = 0;
+    FT_Short result = 0;
+    
+    FT_Assert( stream );
+    
+    *error = FT_Err_Ok;
+    
+    if (stream->pos+1 < stream->size)
+    {
+      if (stream->read)
+      {
+        if (stream->read( stream, stream->pos, reads, 2L ) != 2L )
+          goto Fail;
+          
+        p = reads;
+      }
+      else
+      {
+        p = stream->base + stream->pos;
+      }
+      
+      if (p)
+      {
+        result       = NEXT_Short(p);
+        stream->pos += 2;
+      }
+    }
+    else goto Fail;
+
+    return result;
+    
+  Fail:
+    *error = FT_Err_Invalid_Stream_Operation;
+    FT_ERROR(( "FT_Read_Short:" ));
+    FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx",
+               stream->pos, stream->size ));
+    return 0;
+  }
+ 
+
+  BASE_FUNC
+  FT_Long  FT_Read_Offset( FT_Stream  stream,
+                           FT_Error*  error )
+  {
+    char     reads[3];
+    char*    p = 0;
+    FT_Long  result = 0;
+    
+    FT_Assert( stream );
+    
+    *error = FT_Err_Ok;
+    
+    if (stream->pos+2 < stream->size)
+    {
+      if (stream->read)
+      {
+        if (stream->read( stream, stream->pos, reads, 3L ) != 3L )
+          goto Fail;
+          
+        p = reads;
+      }
+      else
+      {
+        p = stream->base + stream->pos;
+      }
+      
+      if (p)
+      {
+        result       = NEXT_Offset(p);
+        stream->pos += 3;
+      }
+    }
+    else goto Fail;
+      
+    return result;
+    
+  Fail:
+    *error = FT_Err_Invalid_Stream_Operation;
+    FT_ERROR(( "FT_Read_Offset:" ));
+    FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx",
+               stream->pos, stream->size ));
+    return 0;
+  }
+ 
+
+  BASE_FUNC
+  FT_Long  FT_Read_Long( FT_Stream  stream,
+                         FT_Error*  error )
+  {
+    char     reads[4];
+    char*    p = 0;
+    FT_Long  result = 0;
+    
+    FT_Assert( stream );
+    
+    *error = FT_Err_Ok;
+    
+    if (stream->pos+3 < stream->size)
+    {
+      if (stream->read)
+      {
+        if (stream->read( stream, stream->pos, reads, 4L ) != 4L )
+          goto Fail;
+          
+        p = reads;
+      }
+      else
+      {
+        p = stream->base + stream->pos;
+      }
+      
+      if (p)
+      {
+        result       = NEXT_Long(p);
+        stream->pos += 4;
+      }
+    }
+    else goto Fail;
+
+    return result;
+    
+  Fail:
+    *error = FT_Err_Invalid_Stream_Operation;
+    FT_ERROR(( "FT_Read_Long:" ));
+    FT_ERROR(( " invalid i/o, pos = 0x%lx, size = 0x%lx",
+               stream->pos, stream->size ));
+    return 0;
+  }
+
diff --git a/src/base/ftstream.h b/src/base/ftstream.h
new file mode 100644
index 0000000..944795c
--- /dev/null
+++ b/src/base/ftstream.h
@@ -0,0 +1,178 @@
+#ifndef FTSTREAM_H
+#define FTSTREAM_H
+
+#include <ftobjs.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* integer extraction macros - the `buffer' parameter must ALWAYS be of  */
+  /* type `char*' or equivalent (1-byte elements).                         */
+  /*                                                                       */
+#define NEXT_Char(buffer)    ((signed char)*buffer++)
+#define NEXT_Byte(buffer)    ((unsigned char)*buffer++)
+
+#define NEXT_Short(buffer)   ( buffer += 2,                                \
+                               ( (short)((signed   char)buffer[-2] << 8) | \
+                                         (unsigned char)buffer[-1]       ) )
+
+#define NEXT_UShort(buffer)  ((unsigned short)NEXT_Short(buffer))
+
+#define NEXT_Offset(buffer)  ( buffer += 3,                                \
+                               ( ((long)(signed   char)buffer[-3] << 16) | \
+                                 ((long)(unsigned char)buffer[-2] <<  8) | \
+                                  (long)(unsigned char)buffer[-1]        ) )
+
+#define NEXT_UOffset(buffer) ((unsigned long)NEXT_Offset(buffer))
+
+#define NEXT_Long(buffer)    ( buffer += 4,                                \
+                               ( ((long)(signed   char)buffer[-4] << 24) | \
+                                 ((long)(unsigned char)buffer[-3] << 16) | \
+                                 ((long)(unsigned char)buffer[-2] <<  8) | \
+                                  (long)(unsigned char)buffer[-1]        ) )
+
+#define NEXT_ULong(buffer)   ((unsigned long)NEXT_Long(buffer))
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Each GET_xxxx() macro uses an implicit `stream' variable.             */
+  /*                                                                       */
+#define FT_GET_MACRO( func, type )        ( (type)func(stream) )
+
+#define GET_Char()     FT_GET_MACRO( FT_Get_Char, FT_Char )
+#define GET_Byte()     FT_GET_MACRO( FT_Get_Char, FT_Byte )
+#define GET_Short()    FT_GET_MACRO( FT_Get_Short, FT_Short )
+#define GET_UShort()   FT_GET_MACRO( FT_Get_Short, FT_UShort )
+#define GET_Offset()   FT_GET_MACRO( FT_Get_Offset, FT_Long )
+#define GET_UOffset()  FT_GET_MACRO( FT_Get_Offset, FT_ULong )
+#define GET_Long()     FT_GET_MACRO( FT_Get_Long, FT_Long )
+#define GET_ULong()    FT_GET_MACRO( FT_Get_Long, FT_ULong )
+#define GET_Tag4()     FT_GET_MACRO( FT_Get_Long, FT_ULong )
+
+
+#define FT_READ_MACRO( func, type, var )        \
+          ( var = (type)func( stream, &error ), \
+            error != FT_Err_Ok )
+
+#define READ_Byte( var )     FT_READ_MACRO( FT_Read_Char, FT_Byte, var )
+#define READ_Char( var )     FT_READ_MACRO( FT_Read_Char, FT_Char, var )
+#define READ_Short( var )    FT_READ_MACRO( FT_Read_Short, FT_Short, var )
+#define READ_UShort( var )   FT_READ_MACRO( FT_Read_Short, FT_UShort, var )
+#define READ_Offset( var )   FT_READ_MACRO( FT_Read_Offset, FT_Long, var )
+#define READ_UOffset( var )  FT_READ_MACRO( FT_Read_Offset, FT_ULong, var )
+#define READ_Long( var )     FT_READ_MACRO( FT_Read_Long, FT_Long, var )
+#define READ_ULong( var )    FT_READ_MACRO( FT_Read_Long, FT_ULong, var )
+
+
+
+  BASE_DEF
+  void  FT_New_Memory_Stream( FT_Library     library,
+                              void*          base,
+     			      unsigned long  size,
+                              FT_Stream      stream );
+ 
+  BASE_DEF
+  FT_Error  FT_Seek_Stream( FT_Stream  stream,
+                            FT_ULong   pos );
+
+  BASE_DEF
+  FT_Error  FT_Skip_Stream( FT_Stream  stream,
+                            FT_Long    distance );
+                            
+  BASE_DEF
+  FT_Long   FT_Stream_Pos( FT_Stream  stream );
+
+
+  BASE_DEF
+  FT_Error  FT_Read_Stream( FT_Stream  stream,
+                            void*      buffer,
+                            FT_ULong   count );
+                            
+  BASE_DEF
+  FT_Error  FT_Read_Stream_At( FT_Stream  stream,
+                               FT_ULong   pos,
+                               void*      buffer,
+                               FT_ULong   count );
+                               
+  BASE_DEF
+  FT_Error  FT_Access_Frame( FT_Stream  stream,
+                             FT_ULong   count );
+                             
+  BASE_DEF
+  void      FT_Forget_Frame( FT_Stream  stream );
+
+
+
+  BASE_DEF
+  FT_Char   FT_Get_Char( FT_Stream  stream );
+  
+  BASE_DEF
+  FT_Short  FT_Get_Short( FT_Stream  stream );
+  
+  BASE_DEF
+  FT_Long   FT_Get_Offset( FT_Stream  stream );
+  
+  BASE_DEF
+  FT_Long   FT_Get_Long( FT_Stream  stream );
+
+
+
+  BASE_DEF
+  FT_Char  FT_Read_Char( FT_Stream  stream,
+                         FT_Error*  error ); 
+
+  BASE_DEF
+  FT_Short  FT_Read_Short( FT_Stream  stream,
+                           FT_Error*  error ); 
+
+  BASE_DEF
+  FT_Long  FT_Read_Offset( FT_Stream  stream,
+                           FT_Error*  error ); 
+
+  BASE_DEF
+  FT_Long  FT_Read_Long( FT_Stream  stream,
+                         FT_Error*  error ); 
+
+
+#define USE_Stream( resource, stream )  \
+          FT_SET_ERROR( FT_Open_Stream( resource, stream ) )
+
+#define DONE_Stream( stream )  \
+          FT_Done_Stream( stream )
+
+
+#define ACCESS_Frame( size )  \
+          FT_SET_ERROR( FT_Access_Frame( stream, size ) )
+
+#define ACCESS_Compressed_Frame( size )  \
+          FT_SET_ERROR( FT_Access_Compressed_Frame( stream, size ) )
+
+
+#define FORGET_Frame() \
+          FT_Forget_Frame( stream )
+
+
+#define FILE_Seek( position )  \
+          FT_SET_ERROR( FT_Seek_Stream( stream, position ) )
+
+#define FILE_Skip( distance )  \
+          FT_SET_ERROR( FT_Skip_Stream( stream, distance ) )
+
+#define FILE_Pos() \
+          FT_Stream_Pos( stream )
+
+#define FILE_Read( buffer, count )                         \
+          FT_SET_ERROR( FT_Read_Stream( stream,            \
+                                        (FT_Char*)buffer,  \
+                                        count ) )
+
+#define FILE_Read_At( position, buffer, count )              \
+          FT_SET_ERROR( FT_Read_Stream_At( stream,           \
+                                           position,         \
+                                           (FT_Char*)buffer, \
+                                           count ) )
+
+
+
+#endif /* FTIO_H */
diff --git a/src/base/rules.mk b/src/base/rules.mk
new file mode 100644
index 0000000..7e6473c
--- /dev/null
+++ b/src/base/rules.mk
@@ -0,0 +1,136 @@
+#****************************************************************************
+#*                                                                          *
+#*  Base layer Makefile                                                     *
+#*                                                                          *
+#*  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.                                         *
+#*                                                                          *
+#****************************************************************************
+
+
+#****************************************************************************
+#*                                                                          *
+#*  IMPORTANT NOTE: This Makefile is intended for GNU Make!                 *
+#*                  If you provide Makefiles for other make utilities,      *
+#*                  please place them in `freetype/lib/arch/<system>.'      *
+#*                                                                          *
+#*                                                                          *
+#*  This file is to be included by the root FreeType sub-Makefile, usually  *
+#*  named `freetype/lib/Makefile.lib.'  Here is the list of the variables   *
+#*  that must be defined to use it:                                         *
+#*                                                                          *
+#*     BASE_DIR:  The location of the base layer's directory.  This is      *
+#*                usually `freetype/lib/base.'                              *
+#*                                                                          *
+#*     ARCH_DIR:  The location of the architecture-dependent directory.     *
+#*                This is usually `freetype/lib/arch/<system>.'             *
+#*                                                                          *
+#*     OBJ_DIR:   The location where the compiled object(s) file will be    *
+#*                placed.                                                   *
+#*                                                                          *
+#*     FT_CFLAGS: A set of flags used for compilation of object files.      *
+#*                This contains at least the include paths of the `arch'    *
+#*                and `base' directories + optimization + warnings +        *
+#*                ANSI compliance.                                          *
+#*                                                                          *
+#*     FT_IFLAGS: The flag used to specify an include path on the compiler  *
+#*                command line.  For example, with GCC, this is `-I', while *
+#*                some other compilers use `/i=' or `-J', etc.              *
+#*                                                                          *
+#*     FT_OBJ:    The suffix of an object file for the platform.  Can be    *
+#*                `o', `obj', `coff', `tco', etc.                           *
+#*                                                                          *
+#*     FT_CC:     The C compiler to use.                                    *
+#*                                                                          *
+#*                                                                          *
+#*  It sets the following variables, which are used by the parent Makefile  *
+#*  after the call:                                                         *
+#*                                                                          *
+#*     BASE_H:       The list of base layer header files on which the rest  *
+#*                   of the library (i.e., drivers) rely.                   *
+#*                                                                          *
+#*     BASE_OBJ_S:   The single-object base layer.                          *
+#*     BASE_OBJ_M:   A list of all objects for a multiple-objects build.    *
+#*     BASE_EXT_OBJ: A list of base layer extensions, i.e., components      *
+#*                   found in `freetype/lib/base' which are not compiled    *
+#*                   within the base layer proper.                          *
+#*                                                                          *
+#****************************************************************************
+
+INCLUDES += $(SRC_)base
+
+# Base layer sources
+#
+BASE_SRC := $(BASE_)ftstream.c  \
+            $(BASE_)ftcalc.c    \
+            $(BASE_)ftobjs.c    \
+            $(BASE_)ftextend.c  \
+            $(BASE_)ftlist.c
+
+# Base layer headers
+#
+BASE_H := $(BASE_)ftcalc.h    \
+          $(BASE_)ftobjs.h    \
+          $(BASE_)ftdriver.h  \
+          $(BASE_)ftextend.h  \
+          $(BASE_)ftlist.h
+
+
+# Base layer `extensions' sources
+#
+# An extension is added to the library file (.a or .lib) as a separate
+# object.  It will then be linked to the final executable only if one of
+# its symbols is used by the application.
+#
+BASE_EXT_SRC := $(BASE_)ftbbox.c   \
+                $(BASE_)ftraster.c \
+                $(BASE_)ftoutln.c
+
+
+# Base layer extensions headers
+#
+BASE_EXT_H := $(BASE_EXT_SRC:%c=%h)
+
+
+# Base layer object(s)
+#
+#   BASE_OBJ_M is used during `multi' builds (each base source file
+#   compiles to a single object file).
+#
+#   BASE_OBJ_S is used during `single' builds (the whole base layer
+#   is compiled as a single object file using ftbase.c).
+#
+BASE_OBJ_M := $(BASE_SRC:$(BASE_)%.c=$(OBJ_)%.$O)
+BASE_OBJ_S := $(OBJ_)ftbase.$O
+
+
+# Default extensions objects
+#
+BASE_EXT_OBJ := $(BASE_EXT_SRC:$(BASE_)%.c=$(OBJ_)%.$O)
+
+
+# Base layer root source file(s)
+#
+BASE_SRC_M := $(BASE_SRC)
+BASE_SRC_S := $(BASE_)ftbase.c
+
+
+# Multiple objects build + extensions
+#
+$(OBJ_)ft%.$O: $(BASE_)ft%.c $(PUBLIC_H) $(BASE_H)
+	$(FT_CC) $T$@ $<
+
+
+# Base layer - single object build
+#
+$(BASE_OBJ_S): $(PUBLIC_H) $(BASE_H) $(BASE_SRC_S) $(BASE_SRC)
+	$(FT_CC) $T$@ $(BASE_SRC_S)
+
+
+# END
diff --git a/src/oldapi/Makefile b/src/oldapi/Makefile
new file mode 100644
index 0000000..3b5858c
--- /dev/null
+++ b/src/oldapi/Makefile
@@ -0,0 +1,29 @@
+#
+#  The OldApi component had not been migrated to the new design yet
+#  please wait a few days for some updates. This file should be
+#  completely ignored during a BUILD !!
+#
+#
+include drivers/shared/sfnt/Makefile
+
+OLDAPI_DIR := $(TOP_DIR)/oldapi
+
+OLDAPI_INCLUDES := $(FT_IFLAG)$(SFNT_DIR)    \
+                   $(FT_IFLAG)$(OLDAPI_DIR)  \
+                   $(FT_IFLAG)$(TT_DIR)
+
+OLDAPI_CFLAGS   := $(FT_CFLAGS) $(OLDAPI_INCLUDES)
+
+OLDAPI_OBJ := $(OBJ_DIR)/ttapi.$(FT_OBJ)
+
+# FreeType-1.1 compatible interface
+#
+$(OLDAPI_OBJ): $(OLDAPI_DIR)/ttapi.c $(OLDAPI_DIR)/truetype.h \
+                    $(BASE_H) $(SFNT_H) $(TT_DRV_H)
+	$(FT_CC) $(OLDAPI_CFLAGS) $< -o $@
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(OLDAPI_OBJ)
+DRV_OBJS_M += $(OLDAPI_OBJ)
+
diff --git a/src/oldapi/readme.txt b/src/oldapi/readme.txt
new file mode 100644
index 0000000..da50fd7
--- /dev/null
+++ b/src/oldapi/readme.txt
@@ -0,0 +1,18 @@
+This directory is provided in order to compile a stand-alone
+TrueType driver which should be backwards and binary compatible
+with FreeType 1.1
+
+Reason is some important design changes were introduced in FreeType
+lately, in order to support several font formats transparently.
+
+The files are :
+
+"truetype.h"        - a replacement for the old "freetype.h" file
+                      that was included by client applications and
+                      font servers of 1.1
+
+"ttapi.c"           - a front-end for the new TrueType driver, that
+                      presents exactly the same interface as the one
+                      in 1.1
+
+
diff --git a/src/oldapi/truetype.h b/src/oldapi/truetype.h
new file mode 100644
index 0000000..fbde469
--- /dev/null
+++ b/src/oldapi/truetype.h
@@ -0,0 +1,1709 @@
+/*******************************************************************
+ *
+ *  truetype.h
+ *
+ *    Backwards-compatible high-level interface for the TrueType
+ *    driver. This file is a replacement for the old "freetype.h"
+ *    from 1.0 and 1.1. It can be used to compile applications
+ *    and tools using the old API..
+ *
+ *    Note that this (old) interface is now deprecated and won't
+ *    be modified in the future. Developers will have to switch to
+ *    the newer interface to get new features ( kerning, embedded
+ *    bitmaps, etc.. ).
+ *
+ *
+ *
+ *  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.
+ *
+ *  Note:
+ *
+ *    This is the only file that should be included by client            
+ *    application sources.  All other types and functions defined
+ *    in the "tt*.h" files are library internals and should not be
+ *    included.
+ *
+ ******************************************************************/
+
+#ifndef TRUETYPE_H
+#define TRUETYPE_H
+
+/* To make freetype.h independent from configuration files we check */
+/* whether EXPORT_DEF has been defined already.                     */
+
+#ifndef EXPORT_DEF
+#define EXPORT_DEF extern
+#endif
+
+/* The same for TT_Text.  If you define the HAVE_TT_TEXT macro, you */
+/* have to provide a typedef declaration for TT_Text before         */
+/* including this file.                                             */
+
+#ifndef HAVE_TT_TEXT
+#define HAVE_TT_TEXT
+  typedef char  TT_Text;              /* the data type to represent */
+                                      /* file name string elements  */
+#endif
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+/* The following types are also defined in "drivers/ttlib/ttobjs.h"  */
+/* We use the _TRUETYPE_ macro to prevent their redefinition when    */
+/* _compiling_ the backwards-compatible layer called "ttapi.c"       */
+/*                                                                   */
+#ifndef _TRUETYPE_
+
+  /*******************************************************************/
+  /*                                                                 */
+  /*  FreeType types definitions.                                    */
+  /*                                                                 */
+  /*  All these begin with a 'TT_' prefix.                           */
+  /*                                                                 */
+  /*******************************************************************/
+
+  typedef unsigned short  TT_Bool;
+
+  typedef signed long     TT_Fixed;   /* Signed Fixed 16.16 Float */
+
+  typedef signed short    TT_FWord;   /* Distance in FUnits */
+  typedef unsigned short  TT_UFWord;  /* Unsigned distance */
+
+  typedef char            TT_String;
+  typedef signed char     TT_Char;
+  typedef unsigned char   TT_Byte;
+  typedef signed short    TT_Short;
+  typedef unsigned short  TT_UShort;
+  typedef signed long     TT_Long;
+  typedef unsigned long   TT_ULong;
+  typedef int             TT_Int;
+
+  typedef signed short    TT_F2Dot14; /* Signed fixed float 2.14 used for */
+                                      /* unit vectors, with layout:       */
+                                      /*                                  */
+                                      /*  s : 1  -- sign bit              */
+                                      /*  m : 1  -- integer bit           */
+                                      /*  f : 14 -- unsigned fractional   */
+                                      /*                                  */
+                                      /*  's:m' is the 2-bit signed int   */
+                                      /*  value to which the positive     */
+                                      /*  fractional part should be       */
+                                      /*  added.                          */
+                                      /*                                  */
+
+  typedef signed long     TT_F26Dot6; /* 26.6 fixed float, used for       */
+                                      /* glyph points pixel coordinates.  */
+
+  typedef signed long     TT_Pos;     /* point position, expressed either */
+                                      /* in fractional pixels or notional */
+                                      /* units, depending on context.     */
+                                      /* For example, glyph coordinates   */
+                                      /* returned by TT_Load_Glyph are    */
+                                      /* expressed in font units when     */
+                                      /* scaling wasn't requested, and    */
+                                      /* in 26.6 fractional pixels if it  */
+                                      /* was.                             */
+
+
+  struct  TT_UnitVector_      /* guess what...  */
+  { 
+    TT_F2Dot14  x;
+    TT_F2Dot14  y;
+  };
+
+  typedef struct TT_UnitVector_  TT_UnitVector;
+
+
+  struct  TT_Vector_          /* Simple vector type */
+  {
+    TT_F26Dot6  x;
+    TT_F26Dot6  y;
+  };
+
+  typedef struct TT_Vector_  TT_Vector;
+
+
+  /* A simple 2x2 matrix used for transformations. */
+  /* You should use 16.16 fixed floats.            */
+  /*                                               */
+  /*  x' = xx*x + xy*y                             */
+  /*  y' = yx*x + yy*y                             */
+  /*                                               */
+
+  struct  TT_Matrix_
+  {
+    TT_Fixed  xx, xy;
+    TT_Fixed  yx, yy;
+  };
+
+  typedef struct TT_Matrix_  TT_Matrix;
+
+
+  /* A structure used to describe a simple bounding box */
+
+  struct TT_BBox_
+  {
+    TT_Pos  xMin;
+    TT_Pos  yMin;
+    TT_Pos  xMax;
+    TT_Pos  yMax;
+  };
+
+  typedef struct TT_BBox_  TT_BBox;
+
+
+
+#endif /* _TRUETYPE_ */
+
+
+
+
+  /* A structure used to describe the source glyph to the renderer. */
+
+  struct  TT_Outline_
+  {
+    TT_Short         n_contours;   /* number of contours in glyph        */
+    TT_UShort        n_points;     /* number of points in the glyph      */
+
+    TT_Vector*       points;       /* the outline's points   */
+    TT_Byte*         flags;        /* the points flags       */
+    TT_UShort*       contours;     /* the contour end points */
+
+    /* The following flag indicates that the outline owns the arrays it  */
+    /* refers to.  Typically, this is true of outlines created from the  */
+    /* TT_New_Outline() API, while it isn't for those returned by        */
+    /* TT_Get_Glyph_Outline().                                           */
+
+    TT_Bool          owner;      /* the outline owns the coordinates,    */
+                                 /* flags and contours array it uses     */
+
+    /* The following flags are set automatically by                      */
+    /* TT_Get_Glyph_Outline().  Their meaning is the following:          */
+    /*                                                                   */
+    /*  high_precision   When true, the scan-line converter will use     */
+    /*                   a higher precision to render bitmaps (i.e. a    */
+    /*                   1/1024 pixel precision).  This is important for */
+    /*                   small ppem sizes.                               */
+    /*                                                                   */
+    /*  second_pass      When true, the scan-line converter performs     */
+    /*                   a second sweep phase dedicated to find          */
+    /*                   vertical drop-outs.  If false, only horizontal  */
+    /*                   drop-outs will be checked during the first      */
+    /*                   vertical sweep (yes, this is a bit confusing    */
+    /*                   but it's really the way it should work).        */
+    /*                   This is important for small ppems too.          */
+    /*                                                                   */
+    /*  dropout_mode     Specifies the TrueType drop-out mode to         */
+    /*                   use for continuity checking. valid values       */
+    /*                   are 0 (no check), 1, 2, 4, and 5.               */
+    /*                                                                   */
+    /*  Most of the engine's users will safely ignore these fields...    */
+
+    TT_Bool          high_precision;  /* high precision rendering */
+    TT_Bool          second_pass;     /* two sweeps rendering     */
+    TT_Char          dropout_mode;    /* dropout mode */
+  };
+
+  typedef struct TT_Outline_  TT_Outline;
+
+ 
+  /* A structure used to return glyph metrics.                          */
+  /*                                                                    */
+  /* The "bearingX" isn't called "left-side bearing" anymore because    */
+  /* it has different meanings depending on the glyph's orientation.    */
+  /*                                                                    */
+  /* The same is true for "bearingY", which is the top-side bearing     */
+  /* defined by the TT_Spec, i.e., the distance from the baseline to    */
+  /* the top of the glyph's bbox.  According to our current convention, */
+  /* this is always the same as "bbox.yMax" but we make it appear for   */
+  /* consistency in its proper field.                                   */
+  /*                                                                    */
+  /* The "advance" width is the advance width for horizontal layout,    */
+  /* and advance height for vertical layouts.                           */
+  /*                                                                    */
+  /* Finally, the library (ver. 1.1) doesn't support vertical text yet  */
+  /* but these changes were introduced to accomodate it, as it will     */
+  /* most certainly be introduced in later releases.                    */
+
+  struct  TT_Glyph_Metrics_
+  {
+    TT_BBox  bbox;      /* glyph bounding box */
+
+    TT_Pos   bearingX;  /* left-side bearing                    */
+    TT_Pos   bearingY;  /* top-side bearing, per se the TT spec */
+
+    TT_Pos   advance;   /* advance width (or height) */
+  };
+
+
+  /* A structure used to return horizontal _and_ vertical glyph         */
+  /* metrics.                                                           */
+  /*                                                                    */
+  /* A glyph can be used either in a horizontal or vertical layout.     */
+  /* Its glyph metrics vary with orientation.  The Big_Glyph_Metrics    */
+  /* structure is used to return _all_ metrics in one call.             */
+  /*                                                                    */
+
+  struct TT_Big_Glyph_Metrics_
+  {
+    TT_BBox  bbox;          /* glyph bounding box */
+
+    TT_Pos   horiBearingX;  /* left side bearing in horizontal layouts */
+    TT_Pos   horiBearingY;  /* top side bearing in horizontal layouts  */
+
+    TT_Pos   vertBearingX;  /* left side bearing in vertical layouts */
+    TT_Pos   vertBearingY;  /* top side bearing in vertical layouts  */
+
+    TT_Pos   horiAdvance;   /* advance width for horizontal layout */
+    TT_Pos   vertAdvance;   /* advance height for vertical layout  */
+
+    /* The following fields represent unhinted scaled metrics values. */
+    /* They can be useful for applications needing to do some device  */
+    /* independent placement of glyphs.                               */
+    /*                                                                */
+    /* Applying these metrics to hinted glyphs will most surely ruin  */
+    /* the grid fitting performed by the bytecode interpreter.  These */
+    /* values are better used to compute accumulated positioning      */
+    /* distances.                                                     */
+
+    TT_Pos   linearHoriBearingX;  /* linearly scaled horizontal lsb     */
+    TT_Pos   linearHoriAdvance;   /* linearly scaled horizontal advance */
+
+    TT_Pos   linearVertBearingY;  /* linearly scaled vertical tsb     */
+    TT_Pos   linearVertAdvance;   /* linearly scaled vertical advance */
+  };
+
+  typedef struct TT_Glyph_Metrics_      TT_Glyph_Metrics;
+  typedef struct TT_Big_Glyph_Metrics_  TT_Big_Glyph_Metrics;
+
+
+  /* A structure used to return instance metrics. */
+
+  struct  TT_Instance_Metrics_
+  {
+    TT_F26Dot6  pointSize;     /* char. size in points (1pt = 1/72 inch) */
+
+    TT_UShort   x_ppem;        /* horizontal pixels per EM square */
+    TT_UShort   y_ppem;        /* vertical pixels per EM square   */
+
+    TT_Fixed    x_scale;     /* 16.16 to convert from EM units to 26.6 pix */
+    TT_Fixed    y_scale;     /* 16.16 to convert from EM units to 26.6 pix */
+
+    TT_UShort   x_resolution;  /* device horizontal resolution in dpi */
+    TT_UShort   y_resolution;  /* device vertical resolution in dpi   */
+  };
+
+  typedef struct TT_Instance_Metrics_  TT_Instance_Metrics;
+
+
+  /* Flow constants:                                             */
+  /*                                                             */
+  /* The flow of a bitmap refers to the way lines are oriented   */
+  /* within the bitmap data, i.e., the orientation of the Y      */
+  /* coordinate axis.                                            */
+
+  /* For example, if the first bytes of the bitmap pertain to    */
+  /* its top-most line, then the flow is 'down'.  If these bytes */
+  /* pertain to its lowest line, the the flow is 'up'.           */
+
+#define TT_Flow_Down  -1  /* bitmap is oriented from top to bottom */
+#define TT_Flow_Up     1  /* bitmap is oriented from bottom to top */
+#define TT_Flow_Error  0  /* an error occurred during rendering    */
+
+
+  /* A structure used to describe the target bitmap or pixmap to the   */
+  /* renderer.  Note that there is nothing in this structure that      */
+  /* gives the nature of the buffer.                                   */
+
+  /* IMPORTANT NOTE:                                                   */
+  /*                                                                   */
+  /*   In the case of a pixmap, the 'width' and 'cols' fields must     */
+  /*   have the _same_ values, and _must_ be padded to 32-bits, i.e.,  */
+  /*   be a multiple of 4.  Clipping problems will arise otherwise,    */
+  /*   if not even page faults!                                        */
+  /*                                                                   */
+  /*   The typical settings are:                                       */
+  /*                                                                   */
+  /*   - for an WxH bitmap:                                            */
+  /*                                                                   */
+  /*       rows  = H                                                   */
+  /*       cols  = (W+7)/8                                             */
+  /*       width = W                                                   */
+  /*       flow  = your_choice                                         */
+  /*                                                                   */
+  /*   - for an WxH pixmap:                                            */
+  /*                                                                   */
+  /*       rows  = H                                                   */
+  /*       cols  = (W+3) & ~3                                          */
+  /*       width = cols                                                */
+  /*       flow  = your_choice                                         */
+
+  struct  TT_Raster_Map_
+  {
+    int    rows;    /* number of rows                    */
+    int    cols;    /* number of columns (bytes) per row */
+    int    width;   /* number of pixels per line         */
+    int    flow;    /* bitmap orientation                */
+
+    void*  bitmap;  /* bit/pixmap buffer                 */
+    long   size;    /* bit/pixmap size in bytes          */
+  };
+
+  typedef struct TT_Raster_Map_  TT_Raster_Map;
+
+
+
+/* The following tables are also defined in "drivers/ttlib/ttobjs.h" */
+/* We use the _TRUETYPE_ macro to prevent their redefinition when    */
+/* _compiling_ the backwards-compatible layer called "oldapi.c"      */
+/*                                                                   */
+#ifndef _TRUETYPE_
+
+  /* ------- The font header TrueType table structure ----- */
+
+  struct  TT_Header_
+  {
+    TT_Fixed   Table_Version;
+    TT_Fixed   Font_Revision;
+
+    TT_Long    CheckSum_Adjust;
+    TT_Long    Magic_Number;
+
+    TT_UShort  Flags;
+    TT_UShort  Units_Per_EM;
+
+    TT_Long    Created [2];
+    TT_Long    Modified[2];
+
+    TT_FWord   xMin;
+    TT_FWord   yMin;
+    TT_FWord   xMax;
+    TT_FWord   yMax;
+
+    TT_UShort  Mac_Style;
+    TT_UShort  Lowest_Rec_PPEM;
+
+    TT_Short   Font_Direction;
+    TT_Short   Index_To_Loc_Format;
+    TT_Short   Glyph_Data_Format;
+  };
+
+  typedef struct TT_Header_  TT_Header;
+
+
+  /* ------- The horizontal header TrueType table structure ----- */
+
+  /*******************************************************/
+  /*  This structure is the one defined by the TrueType  */
+  /*  specification, plus two fields used to link the    */
+  /*  font-units metrics to the header.                  */
+
+  struct  TT_Horizontal_Header_
+  {
+    TT_Fixed   Version;
+    TT_FWord   Ascender;
+    TT_FWord   Descender;
+    TT_FWord   Line_Gap;
+
+    TT_UFWord  advance_Width_Max;      /* advance width maximum */
+
+    TT_FWord   min_Left_Side_Bearing;  /* minimum left-sb       */
+    TT_FWord   min_Right_Side_Bearing; /* minimum right-sb      */
+    TT_FWord   xMax_Extent;            /* xmax extents          */
+    TT_FWord   caret_Slope_Rise;
+    TT_FWord   caret_Slope_Run;
+
+    TT_Short   caret_Offset;           /* only used in vertical header */
+    TT_Short   Reserved[4];
+
+    TT_Short   metric_Data_Format;
+    TT_UShort  number_Of_HMetrics;
+    
+    /* The following fields are not defined by the TrueType specification */
+    /* but they're used to connect the metrics header to the relevant     */
+    /* "HMTX" or "VMTX" table.                                            */
+
+    void*      long_metrics;
+    void*      short_metrics;
+  };
+
+
+  /*******************************************************/
+  /*  This structure is the one defined by the TrueType  */
+  /*  specification.  Note that it has exactly the same  */
+  /*  layout as the horizontal header (both are loaded   */
+  /*  by the same function).                             */
+
+  struct  TT_Vertical_Header_
+  {
+    TT_Fixed   Version;
+    TT_FWord   Ascender;
+    TT_FWord   Descender;
+    TT_FWord   Line_Gap;
+
+    TT_UFWord  advance_Height_Max;      /* advance height maximum */
+
+    TT_FWord   min_Top_Side_Bearing;    /* minimum left-sb or top-sb       */
+    TT_FWord   min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb   */
+    TT_FWord   yMax_Extent;             /* xmax or ymax extents            */
+    TT_FWord   caret_Slope_Rise;
+    TT_FWord   caret_Slope_Run;
+    TT_FWord   caret_Offset;
+
+    TT_Short   Reserved[4];
+
+    TT_Short   metric_Data_Format;
+    TT_UShort  number_Of_VMetrics;
+    
+    /* The following fields are not defined by the TrueType specification */
+    /* but they're used to connect the metrics header to the relevant     */
+    /* "HMTX" or "VMTX" table.                                            */
+
+    void*      long_metrics;
+    void*      short_metrics;
+  };
+
+
+  typedef struct TT_Horizontal_Header_  TT_Horizontal_Header;
+  typedef struct TT_Vertical_Header_    TT_Vertical_Header;
+
+
+  /* ----------- OS/2 Table ----------------------------- */
+
+  struct  TT_OS2_
+  {
+    TT_UShort  version;                /* 0x0001 */
+    TT_FWord   xAvgCharWidth;
+    TT_UShort  usWeightClass;
+    TT_UShort  usWidthClass;
+    TT_Short   fsType;
+    TT_FWord   ySubscriptXSize;
+    TT_FWord   ySubscriptYSize;
+    TT_FWord   ySubscriptXOffset;
+    TT_FWord   ySubscriptYOffset;
+    TT_FWord   ySuperscriptXSize;
+    TT_FWord   ySuperscriptYSize;
+    TT_FWord   ySuperscriptXOffset;
+    TT_FWord   ySuperscriptYOffset;
+    TT_FWord   yStrikeoutSize;
+    TT_FWord   yStrikeoutPosition;
+    TT_Short   sFamilyClass;
+
+    TT_Byte    panose[10];
+
+    TT_ULong   ulUnicodeRange1;        /* Bits 0-31   */
+    TT_ULong   ulUnicodeRange2;        /* Bits 32-63  */
+    TT_ULong   ulUnicodeRange3;        /* Bits 64-95  */
+    TT_ULong   ulUnicodeRange4;        /* Bits 96-127 */
+
+    TT_Char    achVendID[4];
+
+    TT_UShort  fsSelection;
+    TT_UShort  usFirstCharIndex;
+    TT_UShort  usLastCharIndex;
+    TT_Short   sTypoAscender;
+    TT_Short   sTypoDescender;
+    TT_Short   sTypoLineGap;
+    TT_UShort  usWinAscent;
+    TT_UShort  usWinDescent;
+
+    /* only version 1 tables: */
+
+    TT_ULong   ulCodePageRange1;       /* Bits 0-31   */
+    TT_ULong   ulCodePageRange2;       /* Bits 32-63  */
+  };
+
+  typedef struct TT_OS2_  TT_OS2;
+
+
+  /* ----------- Postscript table ------------------------ */
+
+  struct  TT_Postscript_
+  {
+    TT_Fixed  FormatType;
+    TT_Fixed  italicAngle;
+    TT_FWord  underlinePosition;
+    TT_FWord  underlineThickness;
+    TT_ULong  isFixedPitch;
+    TT_ULong  minMemType42;
+    TT_ULong  maxMemType42;
+    TT_ULong  minMemType1;
+    TT_ULong  maxMemType1;
+
+    /* Glyph names follow in the file, but we don't         */
+    /* load them by default.  See the ftxpost.c extension.  */
+  };
+
+  typedef struct TT_Postscript_  TT_Postscript;
+
+
+  /* ------------ horizontal device metrics "hdmx" ---------- */
+
+  struct  TT_Hdmx_Record_
+  {
+    TT_Byte   ppem;
+    TT_Byte   max_width;
+    TT_Byte*  widths;
+  };
+
+  typedef struct TT_Hdmx_Record_  TT_Hdmx_Record;
+
+
+  struct  TT_Hdmx_
+  {
+    TT_UShort        version;
+    TT_Short         num_records;
+    TT_Hdmx_Record*  records;
+  };
+
+  typedef struct TT_Hdmx_  TT_Hdmx;
+
+
+#else
+
+  typedef  TT_HoriHeader   TT_Horizontal_Header;
+  typedef  TT_VertHeader   TT_Vertical_Header;
+
+#endif /* _TRUETYPE_ */
+
+
+  /* A structure used to describe face properties.                        */
+  /* be aware that this is not the same structure as the one define       */
+  /* in "freetype/ttlib/ttdriver.h". A suitable conversion is performed   */
+  /* in "oldapi/ttapi.c" to build a binary driver that is backwards       */
+  /* compatible with FreeType 1.1, in the function TT_Get_Face_Properties */
+
+  struct  TT_Face_Properties_
+  {
+    TT_UShort  num_Glyphs;      /* number of glyphs in face              */
+    TT_UShort  max_Points;      /* maximum number of points in a glyph   */
+    TT_UShort  max_Contours;    /* maximum number of contours in a glyph */
+
+    TT_UShort  num_CharMaps;    /* number of charmaps in the face     */
+    TT_UShort  num_Names;       /* number of name records in the face */
+
+    TT_ULong   num_Faces;  /* 1 for normal TrueType files, and the  */
+                           /* number of embedded faces for TrueType */
+                           /* collections                           */
+
+    TT_Header*             header;        /* TrueType header table          */
+    TT_Horizontal_Header*  horizontal;    /* TrueType horizontal header     */
+    TT_OS2*                os2;           /* TrueType OS/2 table            */
+    TT_Postscript*         postscript;    /* TrueType Postscript table      */
+    TT_Hdmx*               hdmx;
+    TT_Vertical_Header*    vertical;      /* TT Vertical header, if present */
+  };
+
+  typedef struct TT_Face_Properties_  TT_Face_Properties;
+
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Type> TT_Engine                                                    */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    A handle to a TrueType driver/engine instance. Engine objects    */
+  /*    can be created with the TT_New_Engine and TT_Build_Engine APIs   */
+  /*                                                                     */
+  /*    TT_Done_Engine will destroy an engine, as well as all the        */
+  /*    objects that were created within it.                             */
+  /*                                                                     */
+
+  typedef struct TT_EngineRec_   *TT_Engine;
+
+  /* Note : The type TT_Engine is not defined in "drivers/ttlib/ttobjs.h" */
+
+
+
+
+/* The TT_Face type is already defined in "drivers/ttlib/ttobjs.h"   */
+/* We use the _TRUETYPE_ macro to prevent their redefinition when    */
+/* _compiling_ the backwards-compatible layer called "oldapi.c"      */
+/*                                                                   */
+#ifndef _TRUETYPE_
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Type> TT_Face                                                      */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    A handle to a TrueType face/font object. A TT_Face encapsulates  */
+  /*    the resolution and scaling independent parts of a TrueType font  */
+  /*    file. Instances (a.k.a. fontsizes) and glyph objects must be     */
+  /*    created from them before a glyph can be loaded in memory.        */
+  /*                                                                     */
+  /*    They are created through TT_New_Face and destroyed with          */
+  /*    TT_Done_Face. This will destroy all instance and glyph objects   */
+  /*                                                                     */
+
+  typedef struct TT_FaceRec_*   TT_Face;
+
+#endif  /* _TRUETYPE_ */
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Type> TT_Instance                                                  */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    A handle to a TrueType instance/fontsize object. A TT_Instance   */
+  /*    encapsulates all the resolution and scaling dependent part of    */
+  /*    a given font size, but doesn't contain any glyph. They must be   */
+  /*    used with glyph objects in order to load glyph objects from      */
+  /*    a TT file.                                                       */
+  /*                                                                     */
+  /*    They are created from face objects with TT_New_Instance, and     */
+  /*    destroyed with TT_Done_Instance                                  */
+  /*                                                                     */
+  /*    A fresh new instance has a default resolution of 96x96 dpi,      */
+  /*    and a default point size of 10 pt. Each of these can be changed  */
+  /*    dynamically with various APIs defined below..                    */
+  /*                                                                     */
+
+  typedef struct TT_InstanceRec_*  TT_Instance;
+
+  /* Note: The TT_Instance type is not defined in "drivers/ttlib/ttobjs.h" */
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Type> TT_Glyph                                                     */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    A handle to a TrueType glyph object. A glyph object acts as a    */
+  /*    container for any of the glyphs of a given face object. It       */
+  /*    encapsulates glyph metrics as well as outline space sized large  */
+  /*    enough to allow the loading of any glyph without further         */
+  /*    allocation. A glyph object doesn't contain any bitmap or         */
+  /*    pixmap data/buffer.                                              */
+  /*                                                                     */
+  /*    They are created from face objects with TT_New_Glyph, and        */
+  /*    destroyed with TT_Done_Glyph                                     */
+  /*                                                                     */
+  /*    One can create several glyph objects per face, and use           */
+  /*    a single instance to load multiple glyphs, even concurrently     */
+  /*    in thread-safe and reentrant modes..                             */
+  /*                                                                     */
+
+  typedef struct TT_GlyphRec_*    TT_Glyph;
+
+  /* Note: the TT_Glyph type is not defined in "drivers/ttlib/ttobjs.h" */
+
+
+/* The TT_CharMap type is already defined in "drivers/ttlib/ttobjs.h" */
+/* We use the _TRUETYPE_ macro to prevent their redefinition when     */
+/* _compiling_ the backwards-compatible layer called "oldapi.c"       */
+/*                                                                    */
+#ifndef _TRUETYPE_
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Type> TT_CharMap                                                   */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    A handle to a TrueType character mapping object. These objects   */
+  /*    are used to convert character codes in a specific locale or      */
+  /*    encoding into font/face glyph indexes.                           */
+  /*                                                                     */
+  /*    The list of character maps found within a face can be            */
+  /*    enumerated with API functions defined below. An CharMap object   */
+  /*    is created with TT_New_CharMap. They are destroyed automatically */
+  /*    when their parent face objects are discarded.                    */
+  /*                                                                     */
+
+  typedef struct TT_CharMapRec_*   TT_CharMap;
+
+  typedef long  TT_Error;
+
+#endif /* _TRUETYPE_ */
+
+
+
+  EXPORT_DEF
+  const TT_Instance   TT_Null_Instance;
+
+
+  /*******************************************************************/
+  /*                                                                 */
+  /*  Postscript Names extension                                     */
+  /*                                                                 */
+  /*******************************************************************/
+
+#define TT_Err_Invalid_Post_Table_Format  0x0B00
+#define TT_Err_Invalid_Post_Table         0x0B01
+
+  /* Initialise the Postscript Names extension */
+  EXPORT_DEF
+  TT_Error TT_Init_Post_Extension( TT_Engine  engine );
+
+  /* Load the Postscript Names table - notice that the 'post' parameter */
+  /* will be ignored in 2.0.                                            */
+  EXPORT_DEF
+  TT_Error TT_Load_PS_Names( TT_Face   face,
+                             void*     post );
+
+  /* Gets the postscript name of a single glyph */
+  EXPORT_DEF
+  TT_Error TT_Get_PS_Name( TT_Face      face,
+                           TT_UShort    index,
+                           TT_String**  PSname );
+
+
+  /*******************************************************************/
+  /*                                                                 */
+  /*  Embedded Bitmaps (sbits) extension                             */
+  /*                                                                 */
+  /*******************************************************************/
+
+#ifndef _TRUETYPE_
+  /*************************************************************/
+  /*                                                           */
+  /* <Struct> TT_SBit_Metrics                                  */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    A structure used to hold the big metrics of a given    */
+  /*    glyph bitmap in a TrueType or OpenType font. These     */
+  /*    are usually found in the "EBDT" table.                 */
+  /*                                                           */
+  /* <Fields>                                                  */
+  /*    height       :: glyph height in pixels                 */
+  /*    width        :: glyph width in pixels                  */
+  /*                                                           */
+  /*    horiBearingX :: horizontal left bearing                */
+  /*    horiBearingY :: horizontal top bearing                 */
+  /*    horiAdvance  :: horizontal advance                     */
+  /*                                                           */
+  /*    vertBearingX :: vertical left bearing                  */
+  /*    vertBearingY :: vertical top bearing                   */
+  /*    vertAdvance  :: vertical advance                       */
+  /*                                                           */
+  typedef struct TT_SBit_Metrics_
+  {
+    TT_Byte  height;
+    TT_Byte  width;
+
+    TT_Char  horiBearingX;
+    TT_Char  horiBearingY;
+    TT_Byte  horiAdvance;
+
+    TT_Char  vertBearingX;
+    TT_Char  vertBearingY;
+    TT_Byte  vertAdvance;
+
+  } TT_SBit_Metrics;
+
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Struct> TT_SBit_Small_Metrics                            */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    A structure used to hold the small metrics of a given  */
+  /*    glyph bitmap in a TrueType or OpenType font. These     */
+  /*    are usually found in the "EBDT" table.                 */
+  /*                                                           */
+  /* <Fields>                                                  */
+  /*    height    :: glyph height in pixels                    */
+  /*    width     :: glyph width in pixels                     */
+  /*                                                           */
+  /*    bearingX  :: left-side bearing                         */
+  /*    bearingY  :: top-side bearing                          */
+  /*    advance   :: advance width or height                   */
+  /*                                                           */
+  typedef struct TT_SBit_Small_Metrics_
+  {
+    TT_Byte  height;
+    TT_Byte  width;
+
+    TT_Char  bearingX;
+    TT_Char  bearingY;
+    TT_Byte  advance;
+
+  } TT_SBit_Small_Metrics;
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Struct> TT_SBit_Line_Metrics                             */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    A structure used to describe the text line metrics of  */
+  /*    a given bitmap strike, for either an horizontal or     */
+  /*    vertical layout.                                       */
+  /*                                                           */
+  /* <Fields>                                                  */
+  /*    ascender  :: ascender in pixels                        */
+  /*    descender :: descender in pixels                       */
+  /*    max_width :: maximum glyph width in pixels             */
+  /*                                                           */
+  /*    caret_slope_enumerator  :: ?                           */
+  /*    caret_slope_denominator :: ?                           */
+  /*    caret_offset            :: ?                           */
+  /*                                                           */
+  /*    min_origin_SB  :: ?                                    */
+  /*    min_advance_SB :: ?                                    */
+  /*    max_before_BL  :: ?                                    */
+  /*    min_after_BL   :: ?                                    */
+  /*                                                           */
+  typedef struct TT_SBit_Line_Metrics_
+  {
+    TT_Char  ascender;
+    TT_Char  descender;
+    TT_Byte  max_width;
+    TT_Char  caret_slope_numerator;
+    TT_Char  caret_slope_denominator;
+    TT_Char  caret_offset;
+    TT_Char  min_origin_SB;
+    TT_Char  min_advance_SB;
+    TT_Char  max_before_BL;
+    TT_Char  min_after_BL;
+    TT_Char  pads[2];
+
+  } TT_SBit_Line_Metrics;
+
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Struct> TT_SBit_Range                                    */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    A TrueType/OpenType subIndexTable as defined in the    */
+  /*    "EBLC" or "bloc" tables.                               */
+  /*                                                           */
+  /* <Fields>                                                  */
+  /*                                                           */
+  /*    first_glyph  :: first glyph index in range             */
+  /*    last_glyph   :: last glyph index in range              */
+  /*                                                           */
+  /*    index_format :: format of index table. valid           */
+  /*                    values are 1 to 5.                     */
+  /*                                                           */
+  /*    image_format :: format of 'EBDT' image data            */
+  /*    image_offset :: offset to image data in 'EBDT'         */
+  /*                                                           */
+  /*    image_size   :: for index formats 2 and 5. This is     */
+  /*                    the size in bytes of each glyph bitmap */
+  /*                    glyph bitmap                           */
+  /*                                                           */
+  /*    big_metrics  :: for index formats 2 and 5. This is     */
+  /*                    the big metrics for each glyph bitmap  */
+  /*                                                           */
+  /*    num_glyphs   :: for index formats 4 and 5. This is     */
+  /*                    the number of glyphs in the code       */
+  /*                    array.                                 */
+  /*                                                           */
+  /*    glyph_offsets :: for index formats 1 and 3.            */
+  /*    glyph_codes   :: for index formats 4 and 5.            */
+  /*                                                           */
+  /*    table_offset  :: offset of index table in 'EBLC' table */
+  /*                     only used during strike loading..     */
+  /*                                                           */
+  typedef struct TT_SBit_Range
+  {
+    TT_UShort        first_glyph;
+    TT_UShort        last_glyph;
+
+    TT_UShort        index_format;
+    TT_UShort        image_format;
+    TT_ULong         image_offset;
+
+    TT_ULong         image_size;
+    TT_SBit_Metrics  metrics;
+    TT_ULong         num_glyphs;
+
+    TT_ULong*        glyph_offsets;
+    TT_UShort*       glyph_codes;
+
+    TT_ULong         table_offset;
+
+  } TT_SBit_Range;
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Struct> TT_SBit_Strike                                   */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    A structure used describe a given bitmap strike in the */
+  /*    "EBLC" or "bloc" tables.                               */
+  /*                                                           */
+  /* <Fields>                                                  */
+  /*                                                           */
+  /*   num_index_ranges  :: number of index ranges             */
+  /*   index_ranges      :: array of glyph index ranges        */
+  /*                                                           */
+  /*   color_ref   :: unused. color reference ??               */
+  /*   hori        :: line metrics for horizontal layouts.     */
+  /*   vert        :: line metrics for vertical layouts.       */
+  /*                                                           */
+  /*   start_glyph :: lowest glyph index for this strike.      */
+  /*   end_glyph   :: higher glyph index for this strike.      */
+  /*                                                           */
+  /*   x_ppem      :: horizontal pixels per EM                 */
+  /*   y_ppem      :: vertical pixels per EM                   */
+  /*   bit_depth   :: bit depth. valid values are 1, 2, 4 & 8  */
+  /*   flags       :: vertical or horizontal ?                 */
+  /*                                                           */
+  typedef struct TT_SBit_Strike_
+  {
+    TT_Int                 num_ranges;
+    TT_SBit_Range*         sbit_ranges;
+    TT_ULong               ranges_offset;
+
+    TT_ULong               color_ref;
+
+    TT_SBit_Line_Metrics   hori;
+    TT_SBit_Line_Metrics   vert;
+
+    TT_UShort              start_glyph;
+    TT_UShort              end_glyph;
+
+    TT_Byte                x_ppem;
+    TT_Byte                y_ppem;
+    TT_Byte                bit_depth;
+    TT_Char                flags;
+
+  } TT_SBit_Strike;
+
+
+
+  
+  /*************************************************************/
+  /*                                                           */
+  /* <Struct> TT_SBit_Component                                */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    A simple structure to describe a compound sbit element */
+  /*                                                           */
+  /* <Fields>                                                  */
+  /*    glyph_code  :: element's glyph index                   */
+  /*    x_offset    :: element's left bearing                  */
+  /*    y_offset    :: element's top bearing                   */
+  /*                                                           */
+  typedef struct TT_SBit_Component_
+  {
+    TT_UShort  glyph_code;
+    TT_Char    x_offset;
+    TT_Char    y_offset;
+
+  } TT_SBit_Component;
+
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Struct> TT_SBit_Scale                                    */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    A structure used describe a given bitmap scaling       */
+  /*    table, asdefined for the "EBSC" table.                 */
+  /*                                                           */
+  /* <Fields>                                                  */
+  /*                                                           */
+  /*    hori   :: horizontal line metrics                      */
+  /*    vert   :: vertical line metrics                        */
+  /*                                                           */
+  /*    x_ppem :: horizontal pixels per EM                     */
+  /*    y_ppem :: vertical pixels per EM                       */
+  /*                                                           */
+  /*    x_ppem_substitute  :: substitution x_ppem              */
+  /*    y_ppem_substitute  :: substitution y_ppem              */
+  /*                                                           */
+  typedef struct TT_SBit_Scale_
+  {
+    TT_SBit_Line_Metrics  hori;
+    TT_SBit_Line_Metrics  vert;
+    TT_Byte               x_ppem;
+    TT_Byte               y_ppem;
+    TT_Byte               x_ppem_substitute;
+    TT_Byte               y_ppem_substitute;
+
+  } TT_SBit_Scale;
+#endif /* _TRUETYPE_ */
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Struct> TT_SBit_Image                                    */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    A structure used to describe a given embedded bitmap   */
+  /*    image.                                                 */
+  /*                                                           */
+  /* <Fields>                                                  */
+  /*    map        :: bitmap descriptor                        */
+  /*    bit_depth  :: pixel bit depth                          */
+  /*    metrics    :: glyph metrics for the bitmap             */
+  /*                                                           */
+  typedef struct TT_SBit_Image_
+  {
+    TT_Raster_Map         map;
+    int                   bit_depth;
+    TT_Big_Glyph_Metrics  metrics;
+
+  } TT_SBit_Image;
+
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Struct> TT_EBLC                                          */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    A structure used to describe the "EBLC" table from     */
+  /*    a TrueTYpe font.                                       */
+  /*                                                           */
+  /* <Fields>                                                  */
+  /*                                                           */
+  /*    version     :: version number of the EBLC table        */
+  /*                                                           */
+  /*    num_strikes :: the number of strikes, i.e. bitmap      */
+  /*                   sizes, present in this font             */
+  /*                                                           */
+  /*    strikes     :: array of strikes                        */
+  /*                                                           */
+  typedef struct TT_EBLC_
+  {
+    TT_ULong         version;
+    TT_ULong         num_strikes;
+    TT_SBit_Strike*  strikes;
+
+  } TT_EBLC;
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_Init_SBit_Extension                                 */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Initialise the embedded bitmaps extension for the      */
+  /*    FreeType engine.                                       */
+  /*                                                           */
+  /* <Input>                                                   */
+  /*    engine  :: handle to current FreeType library instance */
+  /*                                                           */
+  /* <Return>                                                  */
+  /*    Error code. 0 means success.                           */
+  /*                                                           */
+  EXPORT_DEF
+  TT_Error  TT_Init_SBit_Extension( TT_Engine  engine );
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_Get_Face_Bitmaps                                    */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Loads the "EBLC" table from a font file, if any.       */
+  /*                                                           */
+  /* <Input>                                                   */
+  /*    face :: handle to the source TrueType font/face        */
+  /*                                                           */
+  /* <Output>                                                  */
+  /*    eblc_table :: a descriptor for the EBLC table          */
+  /*                                                           */
+  /* <Return>                                                  */
+  /*    Error code. 0 means success.                           */
+  /*                                                           */
+  /* <Note>                                                    */
+  /*    This function returns TT_Err_Table_Missing when the    */
+  /*    font contains no embedded bitmaps. All fields in       */
+  /*    "eblc_table" will then be set to 0.                    */
+  /*                                                           */
+  EXPORT_DEF
+  TT_Error  TT_Get_Face_Bitmaps( TT_Face   face,
+                                 TT_EBLC  *eblc_table );
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_New_SBit_Image                                      */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Allocates a new embedded bitmap container              */
+  /*                                                           */
+  /* <Output>                                                  */
+  /*    image :: sbit image                                    */
+  /*                                                           */
+  /* <Return>                                                  */
+  /*    Error code. 0 means success.                           */
+  /*                                                           */
+  EXPORT_DEF
+  TT_Error  TT_New_SBit_Image( TT_SBit_Image*  *image );
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_Done_SBit_Image                                     */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Releases an embedded bitmap container                  */
+  /*                                                           */
+  /* <Input>                                                   */
+  /*    image :: sbit image                                    */
+  /*                                                           */
+  EXPORT_DEF
+  void      TT_Done_SBit_Image( TT_SBit_Image*  image );
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_Load_Glyph_Bitmap                                   */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Loads a given glyph embedded bitmap                    */
+  /*                                                           */
+  /* <Input>                                                   */
+  /*    face        :: handle to the source TrueType font/face */
+  /*    instance    :: current size/transform instance         */
+  /*    glyph_index :: index of source glyph                   */
+  /*    bitmap      :: target embedded bitmap descriptor       */
+  /*                                                           */
+  /* <Return>                                                  */
+  /*    Error code. 0 means success.                           */
+  /*                                                           */
+  /* <Note>                                                    */
+  /*    This function returns an error if there is no          */
+  /*    embedded bitmap for the glyph at the given             */
+  /*    instance.                                              */
+  /*                                                           */
+  EXPORT_DEF
+  TT_Error  TT_Load_Glyph_Bitmap( TT_Face         face,
+                                  TT_Instance     instance,
+                                  TT_UShort       glyph_index,
+                                  TT_SBit_Image*  bitmap );
+
+
+  /*******************************************************************/
+  /*                                                                 */
+  /*  FreeType API                                                   */
+  /*                                                                 */
+  /*  All these begin with a 'TT_' prefix.                           */
+  /*                                                                 */
+  /*  Most of them are implemented in the 'ttapi.c' source file.     */
+  /*                                                                 */
+  /*******************************************************************/
+
+  /* Initialize the engine. */
+
+  EXPORT_DEF
+  TT_Error  TT_Init_FreeType( TT_Engine*  engine );
+
+
+  /* Finalize the engine, and release all allocated objects. */
+
+  EXPORT_DEF
+  TT_Error  TT_Done_FreeType( TT_Engine  engine );
+
+
+  /* Set the gray level palette.  This is an array of 5 bytes used */
+  /* to produce the font smoothed pixmaps.  By convention:         */
+  /*                                                               */
+  /*  palette[0] = background (white)                              */
+  /*  palette[1] = light                                           */
+  /*  palette[2] = medium                                          */
+  /*  palette[3] = dark                                            */
+  /*  palette[4] = foreground (black)                              */
+  /*                                                               */
+
+  EXPORT_DEF
+  TT_Error  TT_Set_Raster_Gray_Palette( TT_Engine       engine,
+                                        const TT_Byte*  palette );
+  
+
+  /* ----------------------- face management ----------------------- */
+
+  /* Open a new TrueType font file, and returns a handle for */
+  /* it in variable '*face'.                                 */
+
+  /* Note: The file can be either a TrueType file (*.ttf) or  */
+  /*       a TrueType collection (*.ttc, in this case, only   */
+  /*       the first face is opened).  The number of faces in */
+  /*       the same collection can be obtained in the face's  */
+  /*       properties, using TT_Get_Face_Properties() and the */
+  /*       'max_Faces' field.                                 */
+
+  EXPORT_DEF
+  TT_Error  TT_Open_Face( TT_Engine       engine,
+                          const TT_Text*  fontPathName,
+                          TT_Face*        face );
+
+
+  /* Open a TrueType font file located inside a collection. */
+  /* The font is assigned by its index in 'fontIndex'.      */
+
+  EXPORT_DEF
+  TT_Error  TT_Open_Collection( TT_Engine       engine,
+                                const TT_Text*  collectionPathName,
+                                TT_ULong        fontIndex,
+                                TT_Face*        face );
+
+
+  /* Return face properties in the 'properties' structure. */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Face_Properties( TT_Face              face,
+                                    TT_Face_Properties*  properties );
+
+
+  /* Set a face object's generic pointer */
+
+  EXPORT_DEF
+  TT_Error  TT_Set_Face_Pointer( TT_Face  face,
+                                 void*    data );
+
+
+  /* Get a face object's generic pointer */
+
+  EXPORT_DEF
+  void*     TT_Get_Face_Pointer( TT_Face  face );
+
+
+  /* Close a face's file handle to save system resources.  The file */
+  /* will be re-opened automatically on the next disk access.       */
+
+  EXPORT_DEF
+  TT_Error  TT_Flush_Face( TT_Face  face );
+
+  /* Get a face's glyph metrics expressed in font units.  Returns any   */
+  /* number of arrays.  Set the fields to NULL if you're not interested */
+  /* by a given array.                                                  */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Face_Metrics( TT_Face     face,
+                                 TT_UShort   firstGlyph,
+                                 TT_UShort   lastGlyph,
+                                 TT_Short*   leftBearings,
+                                 TT_UShort*  widths,
+                                 TT_Short*   topBearings,
+                                 TT_UShort*  heights );
+
+  /* Close a given font object, destroying all associated */
+  /* instances.                                           */
+
+  EXPORT_DEF
+  TT_Error  TT_Close_Face( TT_Face  face );
+
+
+  /* Get font or table data. */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Font_Data( TT_Face   face,
+                              TT_ULong  tag,
+                              TT_Long   offset,
+                              void*     buffer,
+                              TT_Long*  length );
+
+
+/* A simple macro to build table tags from ASCII chars */
+
+#define MAKE_TT_TAG( _x1, _x2, _x3, _x4 ) \
+          (((TT_ULong)_x1 << 24) |        \
+           ((TT_ULong)_x2 << 16) |        \
+           ((TT_ULong)_x3 << 8)  |        \
+            (TT_ULong)_x4)
+
+
+
+  /* ----------------------- instance management -------------------- */
+
+  /* Open a new font instance and returns an instance handle */
+  /* for it in '*instance'.                                  */
+
+  EXPORT_DEF
+  TT_Error  TT_New_Instance( TT_Face       face,
+                             TT_Instance*  instance );
+
+
+  /* Set device resolution for a given instance.  The values are      */
+  /* given in dpi (Dots Per Inch).  Default is 96 in both directions. */
+
+  EXPORT_DEF
+  TT_Error  TT_Set_Instance_Resolutions( TT_Instance  instance,
+                                         TT_UShort    xResolution,
+                                         TT_UShort    yResolution );
+
+
+  /* Set the pointsize for a given instance.  Default is 10pt. */
+
+  EXPORT_DEF
+  TT_Error  TT_Set_Instance_CharSize( TT_Instance  instance,
+                                      TT_F26Dot6   charSize );
+
+  EXPORT_DEF
+  TT_Error  TT_Set_Instance_CharSizes( TT_Instance  instance,
+                                       TT_F26Dot6   charWidth,
+                                       TT_F26Dot6   charHeight );
+
+#define TT_Set_Instance_PointSize( ins, ptsize )   \
+            TT_Set_Instance_CharSize( ins, ptsize*64 )
+
+  EXPORT_DEF
+  TT_Error  TT_Set_Instance_PixelSizes( TT_Instance  instance,
+                                        TT_UShort    pixelWidth,
+                                        TT_UShort    pixelHeight,
+                                        TT_F26Dot6   pointSize );
+
+
+  /* This function has been deprecated !! Do not use it, as it    */
+  /* doesn't work reliably. You can perfectly control hinting     */
+  /* yourself when loading glyphs, then apply transforms as usual */
+
+  EXPORT_DEF
+  TT_Error  TT_Set_Instance_Transform_Flags( TT_Instance  instance,
+                                             TT_Bool      rotated,
+                                             TT_Bool      stretched );
+
+
+  /* Return instance metrics in 'metrics'. */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Instance_Metrics( TT_Instance           instance,
+                                     TT_Instance_Metrics*  metrics );
+
+
+  /* Set an instance's generic pointer. */
+
+  EXPORT_DEF
+  TT_Error  TT_Set_Instance_Pointer( TT_Instance  instance,
+                                     void*        data );
+
+
+  /* Get an instance's generic pointer. */
+
+  EXPORT_DEF
+  void*     TT_Get_Instance_Pointer( TT_Instance  instance );
+
+
+  /* Close a given instance object, destroying all associated data. */
+
+  EXPORT_DEF
+  TT_Error  TT_Done_Instance( TT_Instance  instance );
+
+
+
+  /* ----------------------- glyph management ----------------------- */
+
+  /* Create a new glyph object related to the given 'face'. */
+
+  EXPORT_DEF
+  TT_Error  TT_New_Glyph( TT_Face    face,
+                          TT_Glyph*  glyph );
+
+
+  /* Discard (and destroy) a given glyph object. */
+
+  EXPORT_DEF
+  TT_Error  TT_Done_Glyph( TT_Glyph  glyph );
+
+
+#define TTLOAD_SCALE_GLYPH  1
+#define TTLOAD_HINT_GLYPH   2
+
+#define TTLOAD_DEFAULT  (TTLOAD_SCALE_GLYPH | TTLOAD_HINT_GLYPH)
+
+
+  /* Load and process (scale/transform and hint) a glyph from the */
+  /* given 'instance'.  The glyph and instance handles must be    */
+  /* related to the same face object.  The glyph index can be     */
+  /* computed with a call to TT_Char_Index().                     */
+
+  /* The 'load_flags' argument is a combination of the macros     */
+  /* TTLOAD_SCALE_GLYPH and TTLOAD_HINT_GLYPH.  Hinting will be   */
+  /* applied only if the scaling is selected.                     */
+
+  /* When scaling is off (i.e., load_flags = 0), the returned     */
+  /* outlines are in EM square coordinates (also called FUnits),  */
+  /* extracted directly from the font with no hinting.            */
+  /* Other glyph metrics are also in FUnits.                      */
+
+  /* When scaling is on, the returned outlines are in fractional  */
+  /* pixel units (i.e. TT_F26Dot6 = 26.6 fixed floats).           */
+
+  /* NOTE:  The glyph index must be in the range 0..num_glyphs-1  */
+  /*        where 'num_glyphs' is the total number of glyphs in   */
+  /*        the font file (given in the face properties).         */
+
+  EXPORT_DEF
+  TT_Error  TT_Load_Glyph( TT_Instance  instance,
+                           TT_Glyph     glyph,
+                           TT_UShort    glyphIndex,
+                           TT_UShort    loadFlags );
+
+
+  /* Return glyph outline pointers in 'outline'.  Note that the returned */
+  /* pointers are owned by the glyph object, and will be destroyed with  */
+  /* it.  The client application should _not_ change the pointers.       */
+  
+  EXPORT_DEF
+  TT_Error  TT_Get_Glyph_Outline( TT_Glyph     glyph,
+                                  TT_Outline*  outline );
+
+
+  /* Copy the glyph metrics into 'metrics'. */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Glyph_Metrics( TT_Glyph           glyph,
+                                  TT_Glyph_Metrics*  metrics );
+
+
+  /* Copy the glyph's big metrics into 'metrics'. */
+  /* Necessary to obtain vertical metrics.        */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Glyph_Big_Metrics( TT_Glyph               glyph,
+                                      TT_Big_Glyph_Metrics*  metrics );
+
+
+  /* Render the glyph into a bitmap, with given position offsets.     */
+
+  /*  Note:  Only use integer pixel offsets to preserve the fine      */
+  /*         hinting of the glyph and the 'correct' anti-aliasing     */
+  /*         (where vertical and horizontal stems aren't grayed).     */
+  /*         This means that xOffset and yOffset must be multiples    */
+  /*         of 64!                                                   */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Glyph_Bitmap( TT_Glyph        glyph,
+                                 TT_Raster_Map*  map,
+                                 TT_F26Dot6      xOffset,
+                                 TT_F26Dot6      yOffset );
+
+
+  /* Render the glyph into a pixmap, with given position offsets.     */
+
+  /*  Note : Only use integer pixel offsets to preserve the fine      */
+  /*         hinting of the glyph and the 'correct' anti-aliasing     */
+  /*         (where vertical and horizontal stems aren't grayed).     */
+  /*         This means that xOffset and yOffset must be multiples    */
+  /*         of 64!                                                   */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Glyph_Pixmap( TT_Glyph        glyph,
+                                 TT_Raster_Map*  map,
+                                 TT_F26Dot6      xOffset,
+                                 TT_F26Dot6      yOffset );
+
+
+
+  /* ----------------------- outline support ------------------------ */
+
+  /* Allocate a new outline.  Reserve space for 'numPoints' and */
+  /* 'numContours'.                                             */
+
+  EXPORT_DEF
+  TT_Error  TT_New_Outline( TT_UShort    numPoints,
+                            TT_Short     numContours,
+                            TT_Outline*  outline );
+
+
+  /* Release an outline. */
+
+  EXPORT_DEF
+  TT_Error  TT_Done_Outline( TT_Outline*  outline );
+
+
+  /* Copy an outline into another one. */
+
+  EXPORT_DEF
+  TT_Error  TT_Copy_Outline( TT_Outline*  source,
+                             TT_Outline*  target );
+
+
+  /* Render an outline into a bitmap. */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Outline_Bitmap( TT_Engine       engine,
+                                   TT_Outline*     outline,
+                                   TT_Raster_Map*  map );
+
+
+  /* Render an outline into a pixmap -- note that this function uses */
+  /* a different pixel scale, where 1.0 pixels = 128           XXXX  */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Outline_Pixmap( TT_Engine       engine,
+                                   TT_Outline*     outline,
+                                   TT_Raster_Map*  map );
+
+
+  /* Return an outline's bounding box -- this function is slow as it */
+  /* performs a complete scan-line process, without drawing, to get  */
+  /* the most accurate values.                                 XXXX  */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Outline_BBox( TT_Outline*  outline,
+                                 TT_BBox*     bbox );
+
+
+  /* Apply a transformation to a glyph outline. */
+
+  EXPORT_DEF
+  void      TT_Transform_Outline( TT_Outline*  outline,
+                                  TT_Matrix*   matrix );
+
+
+  /* Apply a translation to a glyph outline. */
+
+  EXPORT_DEF
+  void      TT_Translate_Outline( TT_Outline*  outline,
+                                  TT_F26Dot6   xOffset,
+                                  TT_F26Dot6   yOffset );
+
+
+  /* Apply a transformation to a vector. */
+
+  EXPORT_DEF
+  void      TT_Transform_Vector( TT_F26Dot6*  x,
+                                 TT_F26Dot6*  y,
+                                 TT_Matrix*   matrix );
+
+
+  /* Multiply a matrix with another -- computes "b := a*b". */
+
+  EXPORT_DEF
+  void      TT_Matrix_Multiply( TT_Matrix*  a,
+                                TT_Matrix*  b );
+                 
+
+  /* Invert a transformation matrix. */
+
+  EXPORT_DEF
+  TT_Error  TT_Matrix_Invert( TT_Matrix*  matrix );
+
+
+  /* Compute A*B/C with 64 bits intermediate precision. */
+
+  EXPORT_DEF
+  TT_Long   TT_MulDiv( TT_Long A, TT_Long B, TT_Long C );
+
+  
+  /* Compute A*B/0x10000 with 64 bits intermediate precision. */
+  /* Useful to multiply by a 16.16 fixed float value.         */
+
+  EXPORT_DEF
+  TT_Long   TT_MulFix( TT_Long A, TT_Long B );
+
+
+
+  /* ----------------- character mappings support ------------- */
+
+  /* Return the number of character mappings found in this file. */
+  /* Returns -1 in case of failure (invalid face handle).        */
+  /*                                                             */
+  /* DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED!            */
+  /*                                                             */
+  /* It is retained for backwards compatibility only and will    */
+  /* fail on 16bit systems.                                      */
+  /*                                                             */
+  /* You can now get the charmap count in the "num_CharMaps"     */
+  /* field of a face's properties.                               */
+  /*                                                             */
+
+  EXPORT_DEF
+  int  TT_Get_CharMap_Count( TT_Face  face );
+
+
+  /* Return the ID of charmap number 'charmapIndex' of a given face */
+  /* used to enumerate the charmaps present in a TrueType file.     */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_CharMap_ID( TT_Face     face,
+                               TT_UShort   charmapIndex,
+                               TT_UShort*  platformID,
+                               TT_UShort*  encodingID );
+
+
+  /* Look up the character maps found in 'face' and return a handle */
+  /* for the one matching 'platformID' and 'platformEncodingID'     */
+  /* (see the TrueType specs relating to the 'cmap' table for       */
+  /* information on these ID numbers).  Returns an error code.      */
+  /* In case of failure, the handle is set to NULL and is invalid.  */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_CharMap( TT_Face      face,
+                            TT_UShort    charmapIndex,
+                            TT_CharMap*  charMap );
+
+
+  /* Translate a character code through a given character map   */
+  /* and return the corresponding glyph index to be used in     */
+  /* a TT_Load_Glyph call.  This function returns 0 in case of  */
+  /* failure.                                                   */
+
+  EXPORT_DEF
+  TT_UShort  TT_Char_Index( TT_CharMap  charMap,
+                            TT_UShort   charCode );
+
+
+
+  /* --------------------- names table support ------------------- */
+
+  /* Return the number of name strings found in the name table.  */
+  /* Returns -1 in case of failure (invalid face handle).        */
+  /*                                                             */
+  /* DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED!            */
+  /*                                                             */
+  /* It is retained for backwards compatibility only and will    */
+  /* fail on 16bit systems.                                      */
+  /*                                                             */
+  /* You can now get the number of name strings in a face with   */
+  /* the "num_Names" field of its properties..                   */
+  /*                                                             */
+
+  EXPORT_DEF
+  int  TT_Get_Name_Count( TT_Face  face );
+
+
+  /* Return the ID of the name number 'nameIndex' of a given face */
+  /* used to enumerate the charmaps present in a TrueType file.   */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Name_ID( TT_Face     face,
+                            TT_UShort   nameIndex,
+                            TT_UShort*  platformID,
+                            TT_UShort*  encodingID,
+                            TT_UShort*  languageID,
+                            TT_UShort*  nameID );
+
+
+  /* Return the address and length of the name number 'nameIndex' */
+  /* of a given face.  The string is part of the face object and  */
+  /* shouldn't be written to or released.                         */
+
+  /* Note that if for an invalid platformID a null pointer will   */
+  /* be returned.                                                 */
+
+  EXPORT_DEF
+  TT_Error  TT_Get_Name_String( TT_Face      face,
+                                TT_UShort    nameIndex,
+                                TT_String**  stringPtr, /* pointer address */
+                                TT_UShort*   length );  /* string length
+                                                           address */
+
+ 
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* TRUETYPE_H */
+
+
+/* END */
diff --git a/src/oldapi/ttapi.c b/src/oldapi/ttapi.c
new file mode 100644
index 0000000..ae31f02
--- /dev/null
+++ b/src/oldapi/ttapi.c
@@ -0,0 +1,2267 @@
+/*******************************************************************
+ *
+ *  ttapi.c    
+ *
+ *    High-level interface implementation
+ *
+ *  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.
+ *
+ *  Notes:
+ *
+ *    This file is used to implement most of the functions that are
+ *    defined in the file "freetype.h". However, two functions are
+ *    implemented elsewhere :                                
+ *
+ ******************************************************************/
+
+#include <freetype.h>
+
+#include <ftdebug.h>
+#include <ftstream.h>
+#include <ftcalc.h>
+#include <ftlist.h>
+#include <ftraster.h>
+
+#include <ttdriver.h>
+#include <ttobjs.h>
+#include <ttcmap.h>
+
+#define _TRUETYPE_
+#include <truetype.h>  /* backwards compatible interface */
+
+
+
+/* required by the tracing mode */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_ttapi
+
+
+#define RENDER_POOL_SIZE  64000
+
+  static
+  const FT_DriverInterface*  tt_interface = &tt_driver_interface;
+  
+  static
+  const TT_DriverInterface*  tt_extension = &tt_format_interface;
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Init_FreeType                                         */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Creates a new TrueType driver/engine object.                     */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*    engine   ::  handle to the new engine object                     */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    This function is provided for stand-alone compiles of the        */
+  /*    TrueType driver.                                                 */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Init_FreeType( TT_Engine*  engine )
+  {
+    FT_Library library;
+    FT_System  system;
+    TT_Error   error;
+
+    *engine = 0;
+
+    error = FT_New_System( &system );
+    if (error) return error;
+    
+    error = FT_New_Library( system, &library );
+    if (!error)
+      /* Now create a new TrueType driver object */
+      error = FT_Add_Driver( library,
+                             (FT_DriverInterface*)&tt_driver_interface );
+    if (error)
+      FT_Done_Library(library);
+    else
+      *engine = (TT_Engine)library;
+
+    return error;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Done_FreeType                                         */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Destroys a given TrueType engine object created with             */
+  /*    TT_Init_FreeType. All associated objects, (i.e. faces, outlines  */
+  /*    and charmaps) will be destroyed..                                */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    engine   :: handle to the engine object                          */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    This function is provided for stand-alone compiles of the        */
+  /*    TrueType driver. The FreeType library uses the TT_Done_Engine    */
+  /*    API.                                                             */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Done_FreeType( TT_Engine  engine )
+  {
+    FT_Library  library = (FT_Library)engine;
+
+    FT_Done_FreeType( library );
+    return FT_Err_Ok;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Set_Raster_Gray_Palette                               */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Sets the raster's gray 5-levels palette. Entry 0 correspond to   */
+  /*    the background, Entry 4 to the foreground. Intermediate entries  */
+  /*    correspond to gray levels..                                      */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    engine   :: handle to the engine object                          */
+  /*    palette  :: an array of 5 bytes used to render 8-bit pixmaps     */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    This function is provided for stand-alone compiles of the        */
+  /*    TrueType driver. The FreeType library accesses directly the      */
+  /*    raster object to set the palette.                                */
+  /*                                                                     */
+  /*    This function ONLY supports 5 levels of grays.                   */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Set_Raster_Gray_Palette( TT_Engine       engine,
+                                        const TT_Byte*  palette )
+  {  
+    FT_Library  library;
+    
+    if (!engine)
+      return TT_Err_Invalid_Engine;
+    
+    library = (FT_Library)engine;
+    return FT_Set_Raster_Palette( library, 5, (unsigned char*)palette );
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Open_Face                                             */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Creates a new face object from a given resource. The file can    */
+  /*    be either a TrueType file (ttf) or a TrueType collection (ttc).  */
+  /*    In the latter case, only the first face is opened. The number    */
+  /*    of faces in a collection can be obtained in the face's           */
+  /*    properties field "num_Faces". Other faces can be opened with     */
+  /*    TT_Open_Collection (see below).                                  */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    engine    :: the parent engine object where to create the face   */
+  /*                 object.                                             */
+  /*                                                                     */
+  /*    pathname  :: pathname for the font file.                         */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*    face      :: a handle to the fresh face object.                  */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success..                           */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    Yes.                                                             */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    This API is provided fro backwards compatibility. Please use     */
+  /*    the functions TT_New_Face/TT_Done_Face now to create and         */
+  /*    discard face objects..                                           */
+  /*                                                                     */
+
+
+        static
+        TT_Error  open_face( FT_Library      library,
+                             const TT_Text*  pathname,
+                             TT_Int          face_index,
+                             TT_Face        *aface )
+        {
+          TT_Error    error;
+          FT_Resource resource;
+      
+          *aface = 0;
+      
+          error = FT_New_Resource( library, pathname, &resource );
+          if (error) return error;
+
+#if 0      
+          error = FT_Add_Resource( library, resource );
+          if (error) goto Fail_Install;
+#endif
+          error = FT_New_Face( resource, face_index, (FT_Face*)aface );
+
+          /* Destroy glyph slot to comply with the 1.x API */
+          if (!error)
+            FT_Done_GlyphSlot( (*aface)->root.slot );
+      
+          if (error)
+            FT_Done_Resource(resource);
+      
+          return error;
+        }
+
+
+  EXPORT_DEF
+  TT_Error  TT_Open_Face( TT_Engine      engine,
+                          const TT_Text* pathname,
+                          TT_Face*       aface )
+  {
+    if (!engine)
+      return TT_Err_Invalid_Driver_Handle;
+
+    return  open_face( (FT_Library)engine, pathname, 0, aface );
+  }
+  
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Open_Collection                                       */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Loads a given face within a collection.                          */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    engine    :: TrueType engine object where to load the face       */
+  /*    pathname  :: the collection's pathname                           */
+  /*    fontIndex :: index of face within the collection. first is 0     */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*    face      :: handle to the new face object. Always set to NULL   */
+  /*                 in case of error                                    */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    Yes.                                                             */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    This API is provided for backwards compatibility. Please use     */
+  /*    the functions TT_New_Collection/TT_Done_Face now to create and   */
+  /*    discard face/collection objects.                                 */
+  /*                                                                     */
+
+  EXPORT_DEF
+  TT_Error  TT_Open_Collection( TT_Engine       engine,
+                                const TT_Text*  pathname,
+                                TT_ULong        fontIndex,
+                                TT_Face*        aface )
+  {
+    if (!engine)
+      return TT_Err_Invalid_Driver_Handle;
+
+    return open_face( (FT_Library)engine, pathname, fontIndex, aface );
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Close_Face                                            */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Destroys a given face object opened through either TT_Open_Face  */
+  /*    of TT_Open_Collection.                                           */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    face  :: handle to the target face object                        */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    This API is provided for backwards compatibility. Please use     */
+  /*    the functions TT_New_Face/TT_Done_Face now to create and         */
+  /*    discard face/collection objects.                                 */
+  /*                                                                     */
+
+  EXPORT_DEF
+  TT_Error  TT_Close_Face( TT_Face  face )
+  {
+    FT_Resource  resource;
+    
+    if (!face)
+      return TT_Err_Invalid_Face_Handle;
+
+    resource = face->root.resource;
+    FT_Done_Face( (FT_Face)face );
+
+    /* uninstall corresponding resource */
+    FT_Done_Resource( resource );
+
+    return TT_Err_Ok;
+  }
+
+
+  /***********************************************************************/
+  /***********************************************************************/
+  /***********************************************************************/
+  /***********************************************************************/
+  /***********                                                 ***********/
+  /***********   End of backwards compatible APIs..            ***********/
+  /***********                                                 ***********/
+  /***********************************************************************/
+  /***********************************************************************/
+  /***********************************************************************/
+  /***********************************************************************/
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Get_Face_Properties                                   */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Return a given face's properties to the caller.                  */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    face  :: handle to the source face object                        */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*    properties :: target properties structure                        */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success.                            */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    Yes.                                                             */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Face_Properties( TT_Face              face,
+                                    TT_Face_Properties*  props )
+  {
+    props->num_Glyphs   = (TT_UShort)face->root.num_glyphs;
+    props->max_Points   = (TT_UShort)face->root.max_points;
+    props->max_Contours = (TT_UShort)face->root.max_contours;
+    props->num_CharMaps = (TT_UShort)face->root.num_charmaps;
+    props->num_Faces    = face->root.num_faces;
+    props->num_Names    = face->num_names;
+    props->header       = &face->header;
+    props->horizontal   = &face->horizontal;
+      
+      /* The driver supports old Mac fonts where there are no OS/2  */
+      /* tables present in the file. However, this is not true of   */
+      /* FreeType 1.1. For the sake of backwards compatibility, we  */
+      /* always return the address of the face's os2 table, even if */
+      /* it is empty (in which case, the 'props.os2' field is set   */
+      /* to NULL..                                                  */
+      /*                                                            */
+      /* Note however, that the 'os2->version' field is set to      */
+      /* 0xFFFF to indicate a missing table though...               */
+      /*                                                            */
+
+    props->os2          = &face->os2;
+      
+    props->postscript    = &face->postscript;
+    props->hdmx          = &face->hdmx;
+    props->vertical      = ( face->vertical_info ? &face->vertical : 0 );
+
+    return TT_Err_Ok;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Set_Face_Pointer.                                     */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Each face object contains a typeless pointer, which use is left  */
+  /*    to client applications (or the high-level library). This API is  */
+  /*    used to set this generic pointer. It is ignored by the driver.   */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    face   :: target face object                                     */
+  /*    data   :: generic pointer's value                                */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    The generic pointer is used by the HLib when using the driver    */
+  /*    within the FreeType library.                                     */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Set_Face_Pointer( TT_Face  face,
+                                 void*    data )
+  {
+    if ( !face )
+      return TT_Err_Invalid_Face_Handle;
+    else
+      face->root.generic.data = data;
+
+    return TT_Err_Ok;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Get_Face_Pointer                                      */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Each face object contains a typeless pointer, which use is left  */
+  /*    to client applications (or the high-level library). This API is  */
+  /*    used to retrieve this generic pointer, which is ignored by the   */
+  /*    driver.                                                          */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    face    :: handle to source face object                          */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    generic pointer value. NULL if the face handle is invalid..      */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  void*  TT_Get_Face_Pointer( TT_Face  face )
+  {
+    return ( face ? face->root.generic.data : NULL );
+  }
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Get_Face_Metrics                                      */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Get the metrics of a given array of glyphs. Returns any number   */
+  /*    of metrics arrays.                                               */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    face       :: handle to the source face object                   */
+  /*    firstGlyph :: index of first glyph in the array                  */
+  /*    lastGlyph  :: index of last glyph in the array                   */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*    leftBearings :: target array of shorts for the glyph left side   */
+  /*                    bearings. Set this field to NULL if you're not   */
+  /*                    interested in these metrics.                     */
+  /*                                                                     */
+  /*    widths :: target array of unsigned shorts for the glyph advance  */
+  /*              widths. Set this field to NULL if you're not           */
+  /*              interested in these metrics.                           */
+  /*                                                                     */
+  /*    topBearings :: target array of shorts for the glyph top side     */
+  /*                   bearings. Set this field to NULL if you're not    */
+  /*                   interested in these metrics.                      */
+  /*                                                                     */
+  /*    heights :: target array of unsigned shorts for the glyph advance */
+  /*               heights. Set this field to NULL if you're not         */
+  /*               interested in these metrics.                          */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success.                            */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+
+        /********************************************************/
+        /* Return horizontal or vertical metrics in font units  */
+        /* for a given glyph.  The metrics are the left side    */
+        /* bearing (resp. top side bearing) and advance width   */
+        /* (resp. advance height).                              */
+        /*                                                      */
+        /* This function will much probably move to another     */
+        /* component in the short future, but I haven't decided */
+        /* which yet...                                         */
+    
+          static
+          void  get_metrics( TT_HoriHeader*  header,
+                             TT_Int          index,
+                             TT_Short*       bearing,
+                             TT_UShort*      advance )
+          {
+            TT_LongMetrics*  longs_m;
+    
+            TT_UShort  k = header->number_Of_HMetrics;
+    
+    
+            if ( index < k )
+            {
+              longs_m = (TT_LongMetrics*)header->long_metrics + index;
+              *bearing = longs_m->bearing;
+              *advance = longs_m->advance;
+            }
+            else
+            {
+              *bearing = ((TT_ShortMetrics*)header->short_metrics)[index - k];
+              *advance = ((TT_LongMetrics*)header->long_metrics)[k - 1].advance;
+            }
+          }
+    
+
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Face_Metrics( TT_Face     face,
+                                 TT_UShort   firstGlyph,
+                                 TT_UShort   lastGlyph,
+                                 TT_Short*   leftBearings,
+                                 TT_UShort*  widths,
+                                 TT_Short*   topBearings,
+                                 TT_UShort*  heights )
+  {
+    TT_UShort  num;
+
+    if ( !face )
+      return TT_Err_Invalid_Face_Handle;
+
+    /* Check the glyph range */
+    if ( lastGlyph >= face->root.num_glyphs || firstGlyph > lastGlyph )
+      return TT_Err_Invalid_Argument;
+
+    num = lastGlyph - firstGlyph;   /* number of elements-1 in each array */
+
+    /* store the left side bearings and advance widths first */
+    {
+      TT_UShort  n;
+      TT_Short   left_bearing;
+      TT_UShort  advance_width;
+
+
+      for ( n = 0; n <= num; n++ )
+      {
+        get_metrics( &face->horizontal,
+                      firstGlyph + n, &left_bearing, &advance_width );
+
+        if ( leftBearings )  leftBearings[n] = left_bearing;
+        if ( widths )        widths[n]       = advance_width;
+      }
+    }
+
+    /* check for vertical data if topBearings or heights is non-NULL */
+    if ( !topBearings && !heights )
+      return TT_Err_Ok;
+
+    if ( !face->vertical_info )
+      return TT_Err_No_Vertical_Data;
+
+    /* store the top side bearings */
+    {
+      TT_UShort  n;
+      TT_Short   top_bearing;
+      TT_UShort  advance_height;
+
+      for ( n = 0; n <= num; n++ )
+      {
+        get_metrics( (TT_HoriHeader*)&face->vertical,
+                     firstGlyph + n, &top_bearing, &advance_height );
+
+        if ( topBearings )  topBearings[n] = top_bearing;
+        if ( heights )      heights[n]     = advance_height;
+      }
+    }
+
+    return TT_Err_Ok;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_New_Instance                                          */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Creates a new instance object from a given face                  */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    face  :: handle to source/parent face object                     */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*    instance :: handle to fresh object. Set to NULL in case of       */
+  /*                error.                                               */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    Yes.                                                             */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    Any new instance uses a default resolution of 96x96 dpi, and     */
+  /*    a default point size of 10 pts. You can change these anytime     */
+  /*    with TT_Set_Instance_Resolutions/CharSize/CharSizes/PixelSizes   */
+  /*    (see below).                                                     */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_New_Instance( TT_Face       face,
+                             TT_Instance*  instance )
+  {
+    return FT_New_Size( (FT_Face)face, (FT_Size*)instance );
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Set_Instance_Resolutions                              */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Sets an instance resolutions in dot-per-inches. Default values   */
+  /*    for "new" instances are 96x96 dpi, but these can be changed any  */
+  /*    time by calling this API.                                        */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    instance    :: handle to target instance object                  */
+  /*    xResolution :: horizontal device resolution in dpi.              */
+  /*    yResolution :: vertical device resolution in dpi.                */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    You should set the charsize or pixel size immediately after      */
+  /*    call in multi-htreaded programs. This will force the instance    */
+  /*    data to be resetted. Otherwise, you may encounter corruption     */
+  /*    when loading two glyphs from the same instance concurrently!     */
+  /*                                                                     */
+  /*    Happily, 99.99% will do just that :-)                            */
+  /*                                                                     */
+  /*                                                                     */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Set_Instance_Resolutions( TT_Instance  ins,
+                                         TT_UShort    xResolution,
+                                         TT_UShort    yResolution )
+  {
+    return FT_Set_Resolutions( (FT_Size)ins, xResolution, yResolution );
+  }
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Set_Instance_CharSizes                                */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Same as TT_Set_Instance_CharSize, but used to specify distinct   */
+  /*    horizontal and vertical coordinates.                             */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    instance   :: handle to target instance object                   */
+  /*    charWidth  :: horizontal character size (26.6 points)            */
+  /*    charHeight :: vertical character size (26.6 points)              */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    There is no check for overflow; with other words, the product    */
+  /*    of glyph dimensions times the device resolution must have        */
+  /*    reasonable values.                                               */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Set_Instance_CharSizes( TT_Instance  ins,
+                                       TT_F26Dot6   charWidth,
+                                       TT_F26Dot6   charHeight )
+  {
+    return FT_Set_Char_Sizes( (FT_Size)ins, charWidth, charHeight );
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Set_Instance_CharSize                                 */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Sets an instance's character size. The size is in fractional     */
+  /*    (26.6) point units. This function sets the horizontal and        */
+  /*    vertical sizes to be equal. Use TT_Set_Instance_CharSizes        */
+  /*    for distinct X and Y char sizes.                                 */
+  /*                                                                     */
+  /*    The default charsize of a new instance object is 10 pts.         */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    instance  :: handle to target instance object                    */
+  /*    charSize  :: character size expressed in 26.6 fixed float        */
+  /*                 points. 1 point = 1/72 dpi.                         */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Set_Instance_CharSize( TT_Instance  instance,
+                                      TT_F26Dot6   charSize )
+  {
+    return TT_Set_Instance_CharSizes( instance, charSize, charSize );
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Set_Instance_PixelSizes                               */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    This function is used to set an instance's pixel sizes directly  */
+  /*    It ignores the instance's resolutions fields, and you'll have to */
+  /*    specify the corresponding pointsize in 26.6 fixed float point    */
+  /*    units. The latter is a requirement of the TrueType bytecode      */
+  /*    interpreter but can be ignored (or more safely, set to the       */
+  /*    maximum pixel size multiplied by 64).                            */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    instance    :: handle to target instance object                  */
+  /*    pixelWidth  :: horizontal pixel width (integer value)            */
+  /*    pixelHeight :: vertical pixel height (integer value)             */
+  /*    pointSize   :: corresponding point size (26.6 points)            */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success.                            */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*   No.                                                               */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Set_Instance_PixelSizes( TT_Instance  ins,
+                                        TT_UShort    pixelWidth,
+                                        TT_UShort    pixelHeight,
+                                        TT_F26Dot6   pointSize )
+  {
+    /* The point size is now ignored by the driver */
+    (void)pointSize;
+    
+    return FT_Set_Pixel_Sizes( (FT_Size)ins, pixelWidth, pixelHeight );
+  }
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Get_Instance_Metrics                                  */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Returns an instance's metrics into caller space.                 */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    instance  :: handle to source instance object                    */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*    metrics   :: target instance metrics structure                   */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    The TT_Instance_Metrics structure differs slightly from the      */
+  /*    FT_Instance_Metrics one, which is why we re-implement this       */
+  /*    function, rather than call a driver method for this..            */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Instance_Metrics( TT_Instance           ins,
+                                     TT_Instance_Metrics*  metrics )
+  {
+    TT_Size  size = (TT_Size)ins;
+
+    if (!ins)
+      return TT_Err_Invalid_Instance_Handle;
+
+    metrics->x_scale      = size->root.metrics.x_scale;
+    metrics->y_scale      = size->root.metrics.y_scale;
+    metrics->x_resolution = size->root.metrics.x_resolution;
+    metrics->y_resolution = size->root.metrics.y_resolution;
+    metrics->x_ppem       = size->root.metrics.x_ppem;
+    metrics->y_ppem       = size->root.metrics.y_ppem;
+
+    metrics->pointSize    = size->root.metrics.pointSize;    
+    return TT_Err_Ok;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Set_Instance_Pointer                                  */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Each instance object contains a typeless pointer, which use is   */
+  /*    left to client applications (or the high-level library). This    */
+  /*    API is used to set this generic pointer. It is ignored by the    */
+  /*    driver.                                                          */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    instance  :: handle to the target instance object                */
+  /*    data      :: value of the generic pointer                        */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Set_Instance_Pointer( TT_Instance  ins,
+                                     void*        data )
+  {
+    if ( !ins )
+      return TT_Err_Invalid_Instance_Handle;
+    else
+      ((FT_Size)ins)->generic.data = data;
+
+    return TT_Err_Ok;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Get_Instance_Pointer                                  */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Each instance object contains a typeless pointer, which use is   */
+  /*    left to client applications (or the high-level library). This    */
+  /*    API is used to retrieve this generic pointer. It is ignored by   */
+  /*    the driver.                                                      */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    instance  :: handle to source instance object                    */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    value of generic pointer. NULL if invalid instance               */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+
+  EXPORT_FUNC
+  void*  TT_Get_Instance_Pointer( TT_Instance  instance )
+  {
+    if ( !instance )
+      return NULL;
+    else
+      return ((FT_Size)instance)->generic.data;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Done_Instance                                         */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Destroys a given instance object. All instances are destroyed    */
+  /*    automatically when their parent face object is discarded.        */
+  /*    However, this API can be used to save memory.                    */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    instance  :: handle to target instance object                    */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+
+  EXPORT_FUNC
+  TT_Error  TT_Done_Instance( TT_Instance  ins )
+  {
+    FT_Done_Size( (FT_Size)ins );
+    return TT_Err_Ok;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Set_Instance_Transform_Flags                          */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Nothing. This function has been deprecated...                    */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    instance      :: handle to target instance object                */
+  /*    rotated       :: 'rotation' flag..                               */
+  /*    stretched     :: 'stretch' flag..                                */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    Always 0.                                                        */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    This function has been deprecated !! Do not use it, it doesn't   */
+  /*    do anything now..                                                */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Set_Instance_Transform_Flags( TT_Instance  instance,
+                                             TT_Bool      rotated,
+                                             TT_Bool      stretched )
+  {
+    (void)instance;   /* the parameters are unused, the (void) prevents */
+    (void)rotated;    /* warnings from pedantic compilers..             */
+    (void)stretched;
+    
+    return TT_Err_Ok;
+  }
+
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function>                                                          */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*                                                                     */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*                                                                     */
+  /*                                                                     */
+  /*                                                                     */
+/*******************************************************************
+ *
+ *  Function    :  TT_New_Glyph
+ *
+ *  Description :  Creates a new glyph object related to a given
+ *                 face.
+ *
+ *  Input  :  face       the face handle
+ *            glyph      address of target glyph handle
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_New_Glyph( TT_Face    face,
+                          TT_Glyph*  aglyph )
+  {
+    return FT_New_GlyphSlot( (FT_Face)face, (FT_GlyphSlot*)aglyph );
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Done_Glyph
+ *
+ *  Description :  Destroys a given glyph object.
+ *
+ *  Input  :  glyph  the glyph handle
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Done_Glyph( TT_Glyph  glyph )
+  {
+    FT_Done_GlyphSlot( (FT_GlyphSlot)glyph );
+    return TT_Err_Ok;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Load_Glyph
+ *
+ *  Description :  Loads a glyph.
+ *
+ *  Input  :  instance      the instance handle
+ *            glyph         the glyph handle
+ *            glyphIndex    the glyph index
+ *            loadFlags     flags controlling how to load the glyph
+ *                          (none, scaled, hinted, both)
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Load_Glyph( TT_Instance  instance,
+                           TT_Glyph     glyph,
+                           TT_UShort    glyphIndex,
+                           TT_UShort    loadFlags   )
+  {
+    TT_Int  result, flags;
+
+    flags = 0;
+
+    /* Convert load flags */
+    if ( (loadFlags & TTLOAD_SCALE_GLYPH) == 0 )
+      flags = FT_LOAD_NO_SCALE;
+
+    else if ( (loadFlags & TTLOAD_HINT_GLYPH) == 0 )
+      flags = FT_LOAD_NO_HINTING;
+
+    else
+      flags = FT_LOAD_DEFAULT;
+
+    flags |= FT_LOAD_NO_BITMAP |   /* prevent bitmap loading for */
+             FT_LOAD_LINEAR;       /* compatibility purposes..   */
+
+    return FT_Load_Glyph( (FT_GlyphSlot)glyph,
+                          (FT_Size)instance,
+                          glyphIndex,
+                          flags,
+                          &result );
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Glyph_Outline
+ *
+ *  Description :  Returns the glyph's outline data.
+ *
+ *  Input  :  glyph     the glyph handle
+ *            outline   address where the glyph outline will be returned
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : YES!  Reads only semi-permanent data.
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Glyph_Outline( TT_Glyph     glyph,
+                                  TT_Outline*  outline )
+  {
+    FT_GlyphSlot  slot = (FT_GlyphSlot)glyph;
+
+    if (!glyph)
+      return TT_Err_Invalid_Glyph_Handle;
+
+    /* the structures TT_Outline and FT_Outline are equivalent */
+    *((FT_Outline*)outline) = slot->outline;
+    return TT_Err_Ok;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Glyph_Metrics
+ *
+ *  Description :  Extracts the glyph's horizontal metrics information.
+ *
+ *  Input  :  glyph       glyph object handle
+ *            metrics     address where metrics will be returned
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : NO!  Glyph containers can't be shared.
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Glyph_Metrics( TT_Glyph           glyph,
+                                  TT_Glyph_Metrics*  metrics )
+  {
+    FT_GlyphSlot  slot = (FT_GlyphSlot)glyph;
+
+    if (!glyph)
+      return TT_Err_Invalid_Glyph_Handle;
+
+    /* TT_Glyph_Metrics and FT_Glyph_Metrics are slightly different */
+    metrics->bbox.xMin = slot->metrics.horiBearingX;
+
+    metrics->bbox.xMax = slot->metrics.horiBearingX +
+                         slot->metrics.width;
+
+    metrics->bbox.yMax = slot->metrics.horiBearingY;
+
+    metrics->bbox.yMin = slot->metrics.horiBearingY -
+                         slot->metrics.height;
+
+    metrics->bearingX  = slot->metrics.horiBearingX;
+    metrics->bearingY  = slot->metrics.horiBearingY;
+    metrics->advance   = slot->metrics.horiAdvance;
+    
+    return TT_Err_Ok;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Big_Glyph_Metrics
+ *
+ *  Description :  Extracts the glyph's big metrics information.
+ *
+ *  Input  :  glyph       glyph object handle
+ *            metrics     address where big metrics will be returned
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : NO!  Glyph containers can't be shared.
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Glyph_Big_Metrics( TT_Glyph               glyph,
+                                      TT_Big_Glyph_Metrics*  metrics )
+  {
+    FT_GlyphSlot       slot = (FT_GlyphSlot)glyph;
+    FT_Glyph_Metrics*  met;
+    FT_Glyph_Metrics*  met2;
+
+    if (!glyph)
+      return TT_Err_Invalid_Glyph_Handle;
+
+    met  = &slot->metrics;
+    met2 = &slot->metrics2;
+
+    metrics->bbox.xMin = met->horiBearingX;
+    metrics->bbox.xMax = met->horiBearingX + met->width;
+    metrics->bbox.yMin = met->horiBearingY - met->height;
+    metrics->bbox.yMax = met->horiBearingY;
+
+    metrics->horiBearingX = met->horiBearingX;
+    metrics->horiBearingY = met->horiBearingY;
+    metrics->horiAdvance  = met->horiAdvance;
+
+    metrics->vertBearingX = met->vertBearingX;
+    metrics->vertBearingY = met->vertBearingY;
+    metrics->vertAdvance  = met->vertAdvance;
+
+    metrics->linearHoriAdvance  = met2->horiAdvance;
+    metrics->linearHoriBearingX = met2->horiBearingX;
+
+    metrics->linearVertAdvance  = met2->vertAdvance;
+    metrics->linearVertBearingY = met2->vertBearingY;
+   
+    return TT_Err_Ok;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Glyph_Bitmap
+ *
+ *  Description :  Produces a bitmap from a glyph outline.
+ *
+ *  Input  :  glyph      the glyph container's handle
+ *            map        target pixmap description block
+ *            xOffset    x offset in fractional pixels (26.6 format)
+ *            yOffset    y offset in fractional pixels (26.6 format)
+ *
+ *  Output :  Error code.
+ *
+ *  Note : Only use integer pixel offsets if you want to preserve
+ *         the fine hints applied to the outline.  This means that
+ *         xOffset and yOffset must be multiples of 64!
+ *
+ *  MT-Safe : NO!  Glyph containers can't be shared.
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Glyph_Bitmap( TT_Glyph        glyph,
+                                 TT_Raster_Map*  map,
+                                 TT_F26Dot6      xOffset,
+                                 TT_F26Dot6      yOffset )
+  {
+    FT_Library     library;
+    TT_Error       error;
+    FT_GlyphSlot   slot = (FT_GlyphSlot)glyph;
+    FT_Outline     outline;
+    FT_Raster_Map  bitmap;
+
+    if ( !glyph )
+      return TT_Err_Invalid_Glyph_Handle;
+
+    library = slot->face->resource->library;
+    outline = slot->outline;
+
+    /* XXX : For now, use only dropout mode 2    */
+    /* outline.dropout_mode = _glyph->scan_type; */
+    outline.dropout_mode = 2;
+
+    bitmap.width    = map->width;
+    bitmap.rows     = map->rows;
+    bitmap.cols     = map->cols;
+    bitmap.flow     = map->flow;
+    bitmap.pix_bits = 1;
+    bitmap.buffer   = map->bitmap;
+
+    FT_Translate_Outline( &outline, xOffset, yOffset );
+
+    error = FT_Get_Outline_Bitmap( library, &outline, &bitmap );
+
+    FT_Translate_Outline( &outline, -xOffset, -yOffset );
+
+    return error;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Glyph_Pixmap
+ *
+ *  Description :  Produces a grayscaled pixmap from a glyph
+ *                 outline.
+ *
+ *  Input  :  glyph      the glyph container's handle
+ *            map        target pixmap description block
+ *            xOffset    x offset in fractional pixels (26.6 format)
+ *            yOffset    y offset in fractional pixels (26.6 format)
+ *
+ *  Output :  Error code.
+ *
+ *  Note : Only use integer pixel offsets to preserve the fine
+ *         hinting of the glyph and the 'correct' anti-aliasing
+ *         (where vertical and horizontal stems aren't grayed).
+ *         This means that xOffset and yOffset must be multiples
+ *         of 64!
+ *
+ *         You can experiment with offsets of +32 to get 'blurred'
+ *         versions of the glyphs (a nice effect at large sizes that
+ *         some graphic designers may appreciate :)
+ *
+ *  MT-Safe : NO!  Glyph containers can't be shared.
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Glyph_Pixmap( TT_Glyph        glyph,
+                                 TT_Raster_Map*  map,
+                                 TT_F26Dot6      xOffset,
+                                 TT_F26Dot6      yOffset )
+  {
+    FT_Library     library;
+    TT_Error       error;
+    FT_GlyphSlot   slot = (FT_GlyphSlot)glyph;
+    FT_Outline     outline;
+    FT_Raster_Map  bitmap;
+
+    if ( !glyph )
+      return TT_Err_Invalid_Glyph_Handle;
+
+    library = slot->face->resource->library;
+    outline = slot->outline;
+
+    /* XXX : For now, use only dropout mode 2    */
+    /* outline.dropout_mode = _glyph->scan_type; */
+    outline.dropout_mode = 2;
+
+    bitmap.width    = map->width;
+    bitmap.rows     = map->rows;
+    bitmap.cols     = map->cols;
+    bitmap.flow     = map->flow;
+    bitmap.pix_bits = 8;
+    bitmap.buffer   = map->bitmap;
+
+    FT_Translate_Outline( &outline, xOffset, yOffset );
+
+    error = FT_Get_Outline_Bitmap( library, &outline, &bitmap );
+
+    FT_Translate_Outline( &outline, -xOffset, -yOffset );
+
+    return error;
+  }
+
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Get_Outline_Bitmap                                    */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*     Renders an outline within a bitmap. The outline's image is      */
+  /*     simply or-ed to the target bitmap.                              */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*     engine  ::   handle to the TrueType driver object               */
+  /*     outline ::   pointer to the source outline descriptor           */
+  /*     raster  ::   pointer to the target bitmap descriptor            */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*     TrueType error code. 0 means success.                           */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*     Yes.                                                            */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Outline_Bitmap( TT_Engine       engine,
+                                   TT_Outline*     outline,
+                                   TT_Raster_Map*  map )
+  {
+    FT_Library     library = (FT_Library)engine;
+    FT_Raster_Map  bitmap;
+
+    if ( !engine )
+      return TT_Err_Invalid_Engine;
+
+    if ( !outline || !map )
+      return TT_Err_Invalid_Argument;
+
+    bitmap.width    = map->width;
+    bitmap.rows     = map->rows;
+    bitmap.cols     = map->cols;
+    bitmap.flow     = map->flow;
+    bitmap.pix_bits = 1;
+    bitmap.buffer   = map->bitmap;
+
+    return FT_Get_Outline_Bitmap( library, (FT_Outline*)outline, &bitmap );
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Get_Outline_Pixmap                                    */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*     Renders an outline within a pixmap. The outline's image is      */
+  /*     simply or-ed to the target pixmap.                              */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*     engine  ::   handle to the TrueType driver object               */
+  /*     outline ::   pointer to the source outline descriptor           */
+  /*     raster  ::   pointer to the target pixmap descriptor            */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*     TrueType error code. 0 means success.                           */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*     Yes.                                                            */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Outline_Pixmap( TT_Engine       engine,
+                                   TT_Outline*     outline,
+                                   TT_Raster_Map*  map )
+  {
+    FT_Library     library = (FT_Library)engine;
+    FT_Raster_Map  bitmap;
+
+    if ( !engine )
+      return TT_Err_Invalid_Engine;
+
+    if ( !outline || !map )
+      return TT_Err_Invalid_Argument;
+
+    bitmap.width    = map->width;
+    bitmap.rows     = map->rows;
+    bitmap.cols     = map->cols;
+    bitmap.flow     = map->flow;
+    bitmap.pix_bits = 8;
+    bitmap.buffer   = map->bitmap;
+
+    return FT_Get_Outline_Bitmap( library, (FT_Outline*)outline, &bitmap );
+  }
+
+
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_New_Outline                                           */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Creates a new outline of a given size.                           */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    numPoints ::  maximum number of points within the outline        */
+  /*                                                                     */
+  /*    numContours :: maximum number of contours within the outline     */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*    outline  :: target outline descriptor.                           */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    Yes.                                                             */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    This function uses 'malloc' to allocate the outline's array,     */
+  /*    _unlike_ all other functions in the TrueType API. This means     */
+  /*    that the outline won't be destroyed when the TrueType engine     */
+  /*    is finalized..                                                   */
+  /*                                                                     */
+  /*    It is provided for backwards compatibility ONLY. Use the new     */
+  /*    FT_New_Outline function defined in "ftoutln.h" instead if you're */
+  /*    working with the FreeType 2.0 API.                               */
+  /*                                                                     */
+
+#include <stdlib.h>  /* for malloc and free */
+
+  static  TT_Outline  null_api_outline = { 0, 0, NULL, NULL, NULL, 
+                                           0, 0, 0, 0 };
+
+  EXPORT_FUNC
+  TT_Error  TT_New_Outline( TT_UShort    numPoints,
+                            TT_Short     numContours,
+                            TT_Outline*  outline )
+  {
+    if ( !outline )
+      return TT_Err_Invalid_Argument;
+
+    *outline = null_api_outline;
+
+    if ( numPoints > 0 && numContours > 0 )
+    {
+      outline->points   = (TT_Vector*)malloc( numPoints * sizeof(TT_Vector) );
+      outline->flags    = (TT_Byte*)  malloc( numPoints * sizeof(TT_Char)   );
+      outline->contours = (TT_UShort*)malloc( numPoints * sizeof(TT_UShort) );
+    
+      if ( !outline->points || !outline->flags || !outline->contours )
+        goto Fail;
+
+      outline->n_points   = numPoints;
+      outline->n_contours = numContours;
+      outline->owner      = TRUE;
+    }
+    return TT_Err_Ok;
+
+  Fail:
+    outline->owner = TRUE;
+    TT_Done_Outline( outline );
+    return TT_Err_Out_Of_Memory;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Done_Outline                                          */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    Destroys an outline created with FT_New_Outline                  */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*    outline ::                                                       */
+  /*       pointer to the outline destructor to discard. This function   */
+  /*       doesn't destroy the TT_Outline sturcture, only the data it    */
+  /*       contains/own.                                                 */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*    TrueType error code. 0 means success                             */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*    No.                                                              */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*    This function uses 'free' to discard the outline's arrays.       */
+  /*    You should only discard outline allocated with TT_New_Outline.   */
+  /*                                                                     */
+  /*    It is provided for backwards compatibility ONLY. Use the new     */
+  /*    FT_Done_Outline function defined in "ftoutln.h" instead if you're*/
+  /*    working with the FreeType 2.0 API.                               */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Done_Outline( TT_Outline*  outline )
+  {
+    if ( outline )
+    {
+      if ( outline->owner )
+      {
+        free( outline->points   );
+        free( outline->flags    );
+        free( outline->contours );
+      }
+      *outline = null_api_outline;
+      return TT_Err_Ok;
+    }
+    else
+      return TT_Err_Invalid_Argument;
+  }
+
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function> TT_Copy_Outline                                          */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*     Copy an outline into another one. Both objects must have        */
+  /*     the same sizes ( num. points & num. contours ) when this        */
+  /*     function is called..                                            */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*     source  :: handle to source outline                             */
+  /*     target  :: handle to target outline                             */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*     TrueType error code. 0 means success                            */
+  /*                                                                     */
+
+  EXPORT_FUNC
+  TT_Error  TT_Copy_Outline( TT_Outline*  source,
+                             TT_Outline*  target )
+  {
+    return FT_Copy_Outline( (FT_Outline*)source,
+                            (FT_Outline*)target );
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Transform_Outline
+ *
+ *  Description :  Applies a simple transformation to an outline.
+ *
+ *  Input  :  outline     the glyph's outline.  Can be extracted
+ *                        from a glyph container through
+ *                        TT_Get_Glyph_Outline().
+ *
+ *            matrix      simple matrix with 16.16 fixed floats
+ *
+ *  Output :  Error code (always TT_Err_Ok).
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  void  TT_Transform_Outline( TT_Outline*  outline,
+                              TT_Matrix*   matrix )
+  {
+    FT_Transform_Outline( (FT_Outline*)outline, (FT_Matrix*)matrix );
+  }  
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Transform_Vector
+ *
+ *  Description :  Apply a simple transform to a vector
+ *
+ *  Input  :  x, y        the vector.
+ *
+ *            matrix      simple matrix with 16.16 fixed floats
+ *
+ *  Output :  None.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  void  TT_Transform_Vector( TT_F26Dot6*  x,
+                             TT_F26Dot6*  y,
+                             TT_Matrix*   matrix )
+  {
+    FT_Transform_Vector( x, y, (FT_Matrix*) matrix );
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Translate_Outline
+ *
+ *  Description :  Applies a simple translation.
+ *
+ *  Input  :  outline   no comment :)
+ *            xOffset
+ *            yOffset
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  void      TT_Translate_Outline( TT_Outline*  outline,
+                                  TT_F26Dot6   xOffset,
+                                  TT_F26Dot6   yOffset )
+  {
+    FT_Translate_Outline( (FT_Outline*)outline, xOffset, yOffset );
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Outline_BBox
+ *
+ *  Description :  Returns an outline's bounding box.
+ *
+ *  Input  :  outline   no comment :)
+ *            bbox      address where the bounding box is returned
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Outline_BBox( TT_Outline*  outline,
+                                 TT_BBox*     bbox )
+  {
+    return FT_Get_Outline_CBox( (FT_Outline*)outline, (FT_BBox*)bbox );
+  }
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function>                                                          */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*                                                                     */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*                                                                     */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*                                                                     */
+  /*                                                                     */
+  /*                                                                     */
+  /* Compute A*B/C with 64 bits intermediate precision. */
+
+  EXPORT_FUNC
+  TT_Long   TT_MulDiv( TT_Long A, TT_Long B, TT_Long C )
+  {
+    return FT_MulDiv( A, B, C );
+  }
+
+  
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Function>                                                          */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Input>                                                             */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Output>                                                            */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Return>                                                            */
+  /*                                                                     */
+  /*                                                                     */
+  /* <MT-Note>                                                           */
+  /*                                                                     */
+  /*                                                                     */
+  /*                                                                     */
+  /* <Note>                                                              */
+  /*                                                                     */
+  /*                                                                     */
+  /*                                                                     */
+  /* Compute A*B/0x10000 with 64 bits intermediate precision. */
+  /* Useful to multiply by a 16.16 fixed float value.         */
+
+  EXPORT_FUNC
+  TT_Long   TT_MulFix( TT_Long A, TT_Long B )
+  {
+    return FT_MulFix( A, B );
+  }
+
+  /* ----------------- character mappings support ------------- */
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_CharMap_Count
+ *
+ *  Description :  Returns the number of charmaps in a given face.
+ *
+ *  Input  :  face   face object handle
+ *
+ *  Output :  Number of tables. -1 in case of error (bad handle).
+ *
+ *  Note   :  DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED!
+ *
+ *            It is retained for backwards compatibility only and will
+ *            fail on 16bit systems.
+ *
+ *  MT-Safe : YES !
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  int  TT_Get_CharMap_Count( TT_Face  face )
+  {
+    FT_Face  _face = (FT_Face)face;
+
+    return ( _face ? _face->num_charmaps : -1 );
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_CharMap_ID
+ *
+ *  Description :  Returns the ID of a given charmap.
+ *
+ *  Input  :  face             face object handle
+ *            charmapIndex     index of charmap in directory
+ *            platformID       address of returned platform ID
+ *            encodingID       address of returned encoding ID
+ *
+ *  Output :  error code
+ *
+ *  MT-Safe : YES !
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_CharMap_ID( TT_Face     face,
+                               TT_UShort   charmapIndex,
+                               TT_UShort*  platformID,
+                               TT_UShort*  encodingID )
+  {
+    TT_CharMap  cmap;
+
+    if ( !face )
+      return TT_Err_Invalid_Face_Handle;
+
+    if ( charmapIndex >= face->num_charmaps )
+      return TT_Err_Bad_Argument;
+
+    cmap = (TT_CharMap)face->charmaps + charmapIndex;
+
+    *platformID = cmap->root.platform_id;
+    *encodingID = cmap->root.encoding_id;
+
+    return TT_Err_Ok;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_CharMap
+ *
+ *  Description :  Looks up a charmap.
+ *
+ *  Input  :  face          face object handle
+ *            charmapIndex  index of charmap in directory
+ *            charMap       address of returned charmap handle
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_CharMap( TT_Face      face,
+                            TT_UShort    charmapIndex,
+                            TT_CharMap*  charMap )
+  {
+    if ( !face )
+      return TT_Err_Invalid_Face_Handle;
+
+    if ( charmapIndex >= face->num_charmaps )
+      return TT_Err_Bad_Argument;
+
+    *charMap = (TT_CharMap)face->charmaps + charmapIndex;
+    return TT_Err_Ok;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Char_Index
+ *
+ *  Description :  Returns the glyph index corresponding to
+ *                 a given character code defined for the 'charmap'.
+ *
+ *  Input  :  charMap    charmap handle
+ *            charcode   character code
+ *
+ *  Output :  glyph index.
+ *
+ *  Notes  :  Character code 0 is the unknown glyph, which should never
+ *            be displayed.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_UShort  TT_Char_Index( TT_CharMap  charMap,
+                            TT_UShort   charCode )
+  {
+    return tt_interface->get_char_index( (FT_CharMap)charMap, charCode );
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Name_Count
+ *
+ *  Description :  Returns the number of strings found in the
+ *                 name table.
+ *
+ *  Input  :  face   face handle
+ *
+ *  Output :  number of strings.
+ *
+ *  Notes  :  Returns -1 on error (invalid handle).
+ *
+ *            DON'T USE THIS FUNCTION! IT HAS BEEN DEPRECATED!
+ *
+ *            It is retained for backwards compatibility only and will
+ *            fail on 16bit systems.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  int  TT_Get_Name_Count( TT_Face  face )
+  {
+    if ( !face )
+      return -1;
+
+    return face->num_names;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Name_ID
+ *
+ *  Description :  Returns the IDs of the string number 'nameIndex'
+ *                 in the name table of a given face.
+ *
+ *  Input  :  face        face handle
+ *            nameIndex   index of string. First is 0
+ *            platformID  addresses of returned IDs
+ *            encodingID
+ *            languageID
+ *            nameID
+ *
+ *  Output :  Error code.
+ *
+ *  Notes  :  Some files have a corrupt or unusual name table, with some
+ *            entries having a platformID > 3.  These can usually
+ *            be ignored by a client application.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Name_ID( TT_Face     face,
+                            TT_UShort   nameIndex,
+                            TT_UShort*  platformID,
+                            TT_UShort*  encodingID,
+                            TT_UShort*  languageID,
+                            TT_UShort*  nameID )
+  {
+    TT_NameRec*  name;
+
+    if (!face)
+      return TT_Err_Invalid_Face_Handle;
+      
+    if ( nameIndex >= face->num_names )
+      return TT_Err_Bad_Argument;
+
+    name = face->name_table.names + nameIndex;
+        
+    *platformID = name->platformID;
+    *encodingID = name->encodingID;
+    *languageID = name->languageID;
+    *nameID     = name->nameID;
+
+    return TT_Err_Ok;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Name_String
+ *
+ *  Description :  Returns the address and length of a given
+ *                 string found in the name table.
+ *
+ *  Input  :  face        face handle
+ *            nameIndex   string index
+ *            stringPtr   address of returned pointer to string
+ *            length      address of returned string length
+ *
+ *  Output :  Error code.
+ *
+ *  Notes  :  If the string's platformID is invalid,
+ *            stringPtr is NULL, and length is 0.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Name_String( TT_Face      face,
+                                TT_UShort    nameIndex,
+                                TT_String**  stringPtr,
+                                TT_UShort*   length )
+  {
+    TT_NameRec* name;
+    
+    if (!face)
+      return TT_Err_Invalid_Face_Handle;
+      
+    if ( nameIndex >= face->num_names )
+      return TT_Err_Bad_Argument;
+
+    name = face->name_table.names + nameIndex;
+
+    *stringPtr = (TT_String*)name->string;
+    *length    = name->stringLength;        
+    
+    return TT_Err_Ok;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  TT_Get_Font_Data
+ *
+ *  Description :  Loads any font table in client memory.  Used by
+ *                 the TT_Get_Font_Data().
+ *
+ *  Input  :  face     Face object to look for.
+ *
+ *            tag      Tag of table to load.  Use the value 0 if you
+ *                     want to access the whole font file, else set
+ *                     this parameter to a valid TrueType table tag
+ *                     that you can forge with the MAKE_TT_TAG
+ *                     macro.
+ *
+ *            offset   Starting offset in the table (or the file
+ *                     if tag == 0).
+ *
+ *            buffer   Address of target buffer
+ *
+ *            length   Address of decision variable:
+ *
+ *                       if length == NULL:
+ *                             Load the whole table.  Returns an
+ *                             an error if 'offset' != 0.
+ *
+ *                       if *length == 0 :
+ *                             Exit immediately, returning the
+ *                             length of the given table, or of
+ *                             the font file, depending on the
+ *                             value of 'tag'.
+ *
+ *                       if *length != 0 :
+ *                             Load the next 'length' bytes of
+ *                             table or font, starting at offset
+ *                             'offset' (in table or font too).
+ *
+ *  Output :  Error code.
+ *
+ *  MT-Safe : YES!
+ *
+ ******************************************************************/
+
+  EXPORT_FUNC
+  TT_Error  TT_Get_Font_Data( TT_Face   face,
+                              TT_ULong  tag,
+                              TT_Long   offset,
+                              void*     buffer,
+                              TT_Long*  length )
+  {
+    return tt_extension->get_font_data( face, tag, offset, buffer, length );
+  }
+
+
+
+
+
+
+
+  /*******************************************************************/
+  /*                                                                 */
+  /*                                                                 */
+  /*                                                                 */
+  /*  Postscript Names extension                                     */
+  /*                                                                 */
+  /*                                                                 */
+  /*                                                                 */
+  /*******************************************************************/
+
+  /* Initialise the Postscript Names extension */
+  EXPORT_FUNC
+  TT_Error TT_Init_Post_Extension( TT_Engine  engine )
+  {
+    (void)engine;
+    return TT_Err_Ok;
+  }
+
+  /* Load the Postscript Names table - notice that the 'post' parameter */
+  /* will be ignored in 2.0.                                            */
+  EXPORT_DEF
+  TT_Error TT_Load_PS_Names( TT_Face   face,
+                             void*     post )
+  {
+    (void)post;
+    (void)face;
+
+    /* the names are now loaded on demand in 2.0 */
+    return TT_Err_Ok;
+  }
+
+
+  /* The following is directly implemented in the TrueType driver */
+#if 0
+  /* Gets the postscript name of a single glyph */
+  EXPORT_DEF
+  TT_Error TT_Get_PS_Name( TT_Face      face,
+                           TT_UShort    index,
+                           TT_String**  PSname );
+#endif
+
+
+
+
+  /*******************************************************************/
+  /*                                                                 */
+  /*                                                                 */
+  /*                                                                 */
+  /*  Embedded Bitmap (sbits) extension                              */
+  /*                                                                 */
+  /*                                                                 */
+  /*                                                                 */
+  /*******************************************************************/
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_Init_SBit_Extension                                 */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Initialise the embedded bitmaps extension for the      */
+  /*    FreeType engine.                                       */
+  /*                                                           */
+  /* <Input>                                                   */
+  /*    engine  :: handle to current FreeType library instance */
+  /*                                                           */
+  /* <Return>                                                  */
+  /*    Error code. 0 means success.                           */
+  /*                                                           */
+  EXPORT_FUNC
+  TT_Error  TT_Init_SBit_Extension( TT_Engine  engine )
+  {
+    (void)engine;
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_Get_Face_Bitmaps                                    */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Loads the "EBLC" table from a font file, if any.       */
+  /*                                                           */
+  /* <Input>                                                   */
+  /*    face :: handle to the source TrueType font/face        */
+  /*                                                           */
+  /* <Output>                                                  */
+  /*    eblc_table :: a descriptor for the EBLC table          */
+  /*                                                           */
+  /* <Return>                                                  */
+  /*    Error code. 0 means success.                           */
+  /*                                                           */
+  /* <Note>                                                    */
+  /*    This function returns TT_Err_Table_Missing when the    */
+  /*    font contains no embedded bitmaps. All fields in       */
+  /*    "eblc_table" will then be set to 0.                    */
+  /*                                                           */
+  EXPORT_FUNC
+  TT_Error  TT_Get_Face_Bitmaps( TT_Face   face,
+                                 TT_EBLC  *eblc_table )
+  {
+    if (!face)
+      return FT_Err_Invalid_Face_Handle;
+
+    eblc_table->num_strikes = face->num_sbit_strikes;
+    eblc_table->strikes     = face->sbit_strikes;
+
+    if ( face->num_sbit_strikes > 0 )
+    {
+      eblc_table->version = 0x00002000;
+      return TT_Err_Ok;
+    }
+
+    eblc_table->version = 0;
+    return TT_Err_Table_Missing;
+  }
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_New_SBit_Image                                      */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Allocates a new embedded bitmap container              */
+  /*                                                           */
+  /* <Output>                                                  */
+  /*    image :: sbit image                                    */
+  /*                                                           */
+  /* <Return>                                                  */
+  /*    Error code. 0 means success.                           */
+  /*                                                           */
+  EXPORT_DEF
+  TT_Error  TT_New_SBit_Image( TT_SBit_Image*  *image )
+  {
+    *image = (TT_SBit_Image*)malloc( sizeof(**image) );
+    if ( !*image )
+      return TT_Err_Out_Of_Memory;
+
+    MEM_Set( *image, sizeof(**image), 0 );
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_Done_SBit_Image                                     */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Releases an embedded bitmap container                  */
+  /*                                                           */
+  /* <Input>                                                   */
+  /*    image :: sbit image                                    */
+  /*                                                           */
+  EXPORT_DEF
+  void      TT_Done_SBit_Image( TT_SBit_Image*  image )
+  {
+    free( image->map.bitmap );
+    free( image );
+  }
+
+
+  /*************************************************************/
+  /*                                                           */
+  /* <Function>                                                */
+  /*    TT_Load_Glyph_Bitmap                                   */
+  /*                                                           */
+  /* <Description>                                             */
+  /*    Loads a given glyph embedded bitmap                    */
+  /*                                                           */
+  /* <Input>                                                   */
+  /*    face        :: handle to the source TrueType font/face */
+  /*    instance    :: current size/transform instance         */
+  /*    glyph_index :: index of source glyph                   */
+  /*    bitmap      :: target embedded bitmap descriptor       */
+  /*                                                           */
+  /* <Return>                                                  */
+  /*    Error code. 0 means success.                           */
+  /*                                                           */
+  /* <Note>                                                    */
+  /*    This function returns an error if there is no          */
+  /*    embedded bitmap for the glyph at the given             */
+  /*    instance.                                              */
+  /*                                                           */
+  EXPORT_FUNC
+  TT_Error  TT_Load_Glyph_Bitmap( TT_Face         face,
+                                  TT_Instance     instance,
+                                  TT_UShort       glyph_index,
+                                  TT_SBit_Image*  bitmap )
+  {
+    FT_GlyphSlot  slot;
+    TT_Error      error;
+
+    error = FT_New_GlyphSlot( (FT_Face)face, &slot );
+    if (error) goto Exit;
+
+    error = FT_Load_Glyph( slot, (FT_Size)instance, glyph_index,
+                           FT_LOAD_NO_OUTLINE, 0 );
+    if (!error)
+    {
+      /* copy bitmap */
+      bitmap->map.width  = slot->bitmap.width;
+      bitmap->map.rows   = slot->bitmap.rows;
+      bitmap->map.cols   = slot->bitmap.cols;
+      bitmap->map.flow   = slot->bitmap.flow;
+      bitmap->bit_depth  = slot->bitmap.pix_bits;
+      bitmap->map.bitmap = slot->bitmap.buffer;
+
+      /* copy metrics */
+      bitmap->metrics.bbox.xMin = slot->metrics.horiBearingX >> 6;
+      bitmap->metrics.bbox.xMax = bitmap->metrics.bbox.xMin +
+                                  (slot->metrics.width >> 6);
+      bitmap->metrics.bbox.yMax = slot->metrics.horiBearingY >> 6;
+      bitmap->metrics.bbox.yMin = bitmap->metrics.bbox.yMax -
+                                  (slot->metrics.height >> 6);
+
+      bitmap->metrics.horiBearingX = bitmap->metrics.bbox.xMin;
+      bitmap->metrics.horiBearingY = bitmap->metrics.bbox.yMax;
+      bitmap->metrics.horiAdvance  = slot->metrics.horiAdvance >> 6;
+
+      bitmap->metrics.vertBearingX = slot->metrics.vertBearingX >> 6;
+      bitmap->metrics.vertBearingY = slot->metrics.vertBearingY >> 6;
+      bitmap->metrics.vertAdvance  = slot->metrics.vertAdvance  >> 6;
+
+      slot->bitmap.buffer = 0;
+    }
+
+    FT_Done_GlyphSlot( slot );
+  Exit:
+    return error;
+  }
+
+/* END */
diff --git a/src/sfnt/rules.mk b/src/sfnt/rules.mk
new file mode 100644
index 0000000..2aa008b
--- /dev/null
+++ b/src/sfnt/rules.mk
@@ -0,0 +1,172 @@
+#****************************************************************************
+#*                                                                          *
+#*  SFNT driver Makefile                                                    *
+#*                                                                          *
+#*  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.                                         *
+#*                                                                          *
+#****************************************************************************
+
+
+#****************************************************************************
+#*                                                                          *
+#*  IMPORTANT NOTE: This Makefile is intended for GNU Make!                 *
+#*                  If you provide Makefiles for other make utilities,      *
+#*                  please place them in `freetype/lib/arch/<system>'.      *
+#*                                                                          *
+#*                                                                          *
+#*  This file is to be included by the FreeType Makefile.lib, located in    *
+#*  the `freetype/lib' directory.  Here is the list of the variables that   *
+#*  must be defined to use it:                                              *
+#*                                                                          *
+#*                                                                          *
+#*     BASE_DIR:    The location of the base layer's directory.  This is    *
+#*                  usually `freetype/lib/base'.                            *
+#*                                                                          *
+#*     ARCH_DIR:    The location of the architecture-dependent directory.   *
+#*                  This is usually `freetype/lib/arch/<system>'.           *
+#*                                                                          *
+#*     DRIVERS_DIR: The location of the font driver sub-dirs, usually       *
+#*                  `freetype/lib/drivers'.                                 *
+#*                                                                          *
+#*     OBJ_DIR:     The location where the compiled object(s) file will be  *
+#*                  placed.                                                 *
+#*                                                                          *
+#*     BASE_H:      A list of pathnames to the base layer's header files on *
+#*                  which the driver depends.                               *
+#*                                                                          *
+#*     FT_CFLAGS:   A set of flags used for compilation of object files.    *
+#*                  This contains at least the include paths of the arch    *
+#*                  and base directories + optimization + warnings + ANSI   *
+#*                  compliance.                                             *
+#*                                                                          *
+#*     FT_IFLAG:    The flag used to specify an include path on the         *
+#*                  compiler command line.  For example, with GCC, this is  *
+#*                  `-I', while some other compilers use `/i=' or `-J',     *
+#*                  etc.                                                    *
+#*                                                                          *
+#*     FT_OBJ:      The suffix of an object file for the platform; can be   *
+#*                  `o', `obj', `coff', `tco', etc. depending on the        *
+#*                  platform.                                               *
+#*                                                                          *
+#*                                                                          *
+#*  It also updates the following variables defined and used in the main    *
+#*  Makefile:                                                               *
+#*                                                                          *
+#*     DRV_OBJ_S:            The list of driver object files in             *
+#*                           single-object mode.                            *
+#*                                                                          *
+#*     DRV_OBJ_M:            The list of driver object files in             *
+#*                           multiple-objects mode.                         *
+#*                                                                          *
+#*     FTINIT_DRIVER_PATHS:  The list of include paths used to compile the  *
+#*                           `ftinit' component which registers all font    *
+#*                            drivers in the FT_Init_FreeType() function.   *
+#*                                                                          *
+#*     FTINIT_DRIVER_H:      The list of header dependencies used to        *
+#*                           compile the `ftinit' component.                *
+#*                                                                          *
+#*     FTINIT_DRIVER_MACROS: The list of macros to be defined when          *
+#*                           compiling the `ftinit' component.              *
+#*                                                                          *
+#*  `Single-object compilation' means that each font driver is compiled     *
+#*  into a single object file.  This is useful to get rid of all            *
+#*  driver-specific entries.                                                *
+#*                                                                          *
+#****************************************************************************
+
+ifndef SFNT_INCLUDE
+SFNT_INCLUDED := 1
+
+include $(SRC_)shared/rules.mk
+
+# SFNT driver directory
+#
+SFNT_DIR  := $(SRC_)sfnt
+SFNT_DIR_ := $(SFNT_DIR)$(SEP)
+
+# additional include flags used when compiling the driver
+#
+SFNT_INCLUDE := $(SHARED) $(SFNT_DIR)
+
+
+# compilation flags for the driver
+#
+SFNT_CFLAGS  := $(SFNT_INCLUDE:%=$I%)
+SFNT_COMPILE := $(FT_CC) $(SFNT_CFLAGS) 
+
+
+# TrueType driver sources (i.e., C files)
+#
+SFNT_DRV_SRC := $(SFNT_DIR_)ttload.c    \
+                $(SFNT_DIR_)ttcmap.c    \
+                $(SFNT_DIR_)ttsbit.c    \
+                $(SFNT_DIR_)ttpost.c    \
+                $(SFNT_DIR_)sfdriver.c  \
+
+
+# TrueType driver headers
+#
+SFNT_DRV_H := $(SHARED_H)               \
+              $(SFNT_DIR_)sfconfig.h    \
+              $(SFNT_DIR_)ttload.h      \
+              $(SFNT_DIR_)ttsbit.h      \
+              $(SFNT_DIR_)ttcmap.h      \
+              $(SFNT_DIR_)ttpost.h
+
+
+# driver object(s)
+#
+#   SFNT_DRV_OBJ_M is used during `debug' builds
+#   SFNT_DRV_OBJ_S is used during `release' builds
+#
+SFNT_DRV_OBJ_M := $(SFNT_DRV_SRC:$(SFNT_DIR_)%.c=$(OBJ_)%.$O)
+SFNT_DRV_OBJ_S := $(OBJ_)sfnt.$O
+
+
+# driver root source file(s)
+#
+SFNT_DRV_SRC_M := $(SFNT_DRV_SRC)
+SFNT_DRV_SRC_S := $(SFNT_DIR_)sfnt.c
+
+
+# driver - single object
+#
+#  the driver is recompiled if any of the header or source files is changed
+#  as well as any of the shared source files found in `shared/sfnt'
+#
+$(SFNT_DRV_OBJ_S): $(BASE_H) $(SHARED_H) $(SFNT_DRV_H) $(SFNT_DRV_SRC) $(SFNT_DRV_SRC_S)
+	$(SFNT_COMPILE) $T$@ $(SFNT_DRV_SRC_S)
+
+
+
+# driver - multiple objects
+#
+#   All objects are recompiled if any of the header files is changed
+#
+$(OBJ_)tt%.$O: $(SFNT_DIR_)tt%.c $(BASE_H) $(SHARED_H) $(SFNT_DRV_H)
+	$(SFNT_COMPILE) $T$@ $<
+
+$(OBJ_)sf%.$O: $(SFNT_DIR_)sf%.c $(BASE_H) $(SHARED_H) $(SFNT_DRV_H)
+	$(SFNT_COMPILE) $T$@ $<
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(SFNT_DRV_OBJ_S)
+DRV_OBJS_M += $(SFNT_DRV_OBJ_M)
+
+
+# update `ftinit' variables
+#
+FTINIT_DRIVER_PATHS  += $(SFNT_DIR) $(SHARED)
+FTINIT_DRIVER_H      += $(SFNT_DRV_H)
+FTINIT_DRIVER_MACROS += FT_SUPPORT_SFNT
+
+endif
+# END
diff --git a/src/sfnt/sfconfig.h b/src/sfnt/sfconfig.h
new file mode 100644
index 0000000..0c16b9d
--- /dev/null
+++ b/src/sfnt/sfconfig.h
@@ -0,0 +1,51 @@
+/***************************************************************************/
+/*                                                                         */
+/*  sfconfig.h                                                             */
+/*                                                                         */
+/*    the `sfnt' driver configuration file.                                */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This file is used to configure various aspects of the TrueType        */
+  /* driver.                                                               */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef SFCONFIG_H
+#define SFCONFIG_H
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support       */
+  /* embedded bitmaps in the TrueType/OpenType driver.                     */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to    */
+  /* load and enumerate the glyph Postscript names in a TrueType or        */
+  /* OpenType file.                                                        */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+
+#endif /* SFCONFIG_H */
+
+
+/* END */
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
new file mode 100644
index 0000000..0f173fa
--- /dev/null
+++ b/src/sfnt/sfdriver.c
@@ -0,0 +1,72 @@
+#include <sfdriver.h>
+#include <ttload.h>
+#include <ttsbit.h>
+#include <ttpost.h>
+#include <ttcmap.h>
+#include <sfconfig.h>
+#include <sfnt.h>
+
+  static const SFNT_Interface  sfnt_interface =
+  {
+    TT_Goto_Table,
+    
+    TT_Load_Any,
+    TT_Load_Directory,
+
+    TT_Load_Header,
+    TT_Load_Metrics_Header,
+    TT_Load_CMap,
+    TT_Load_MaxProfile,
+    TT_Load_OS2,
+    TT_Load_PostScript,
+
+    TT_Load_Names,
+    TT_Free_Names,
+
+    TT_Load_Hdmx,
+    TT_Free_Hdmx,
+
+    TT_Load_Kern,
+    TT_Load_Gasp,
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+    /* see `ttsbit.h' */
+    TT_Load_SBit_Strikes,
+    TT_Load_SBit_Image,
+    TT_Free_SBit_Strikes,
+#else
+    0,
+    0,
+    0,
+#endif  
+    
+    /* see `ttpost.h' */
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 
+    TT_Get_PS_Name,
+    TT_Free_Post_Names,    
+#else
+    0,
+    0,
+#endif 
+
+    /* see `ttcmap.h' */
+    TT_CharMap_Load,
+    TT_CharMap_Free,
+  };
+  
+
+  EXPORT_FUNC
+  const FT_DriverInterface  sfnt_driver_interface =
+  {
+    sizeof(FT_DriverRec),
+    0,
+    0,
+    0,
+
+    "sfnt",     /* driver name                         */
+    1,          /* driver version                      */
+    2,          /* driver requires FreeType 2 or above */
+
+    (void*)&sfnt_interface
+  };
+
diff --git a/src/sfnt/sfdriver.h b/src/sfnt/sfdriver.h
new file mode 100644
index 0000000..fd10d88
--- /dev/null
+++ b/src/sfnt/sfdriver.h
@@ -0,0 +1,83 @@
+/***************************************************************************/
+/*                                                                         */
+/*  sfdriver.h                                                             */
+/*                                                                         */
+/*    High-level SFNT driver interface (specification).                    */
+/*                                                                         */
+/*  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 SFDRIVER_H
+#define SFDRIVER_H
+
+#include <freetype.h>
+#include <ftdriver.h>
+
+  EXPORT_DEF
+  const FT_DriverInterface  sfnt_driver_interface;
+
+
+
+/*************************************************************************
+ *
+ *  Here is a template of the code that should appear in each
+ *  font driver's _interface_ file (the one included by "ftinit.c").
+ *
+ *  It is used to build, at compile time, a simple linked list of
+ *  the interfaces of the drivers which have been #included in 
+ *  "ftinit.c". See the source code of the latter file for details
+ *
+ *  (Note that this is only required when you want your driver included
+ *   in the set of default drivers loaded by FT_Init_FreeType. Other
+ *   drivers can still be added manually at runtime with FT_Add_Driver.
+ *
+ * {
+ *   #ifdef FTINIT_DRIVER_CHAIN
+ *
+ *   static
+ *   const FT_DriverChain  ftinit_<FORMAT>_driver_chain =
+ *   {
+ *     FT_INIT_LAST_DRIVER_CHAIN,
+ *     &<FORMAT>_driver_interface
+ *   };
+ * 
+ *   #undef  FT_INIT_LAST_DRIVER_CHAIN
+ *   #define FT_INIT_LAST_DRIVER_CHAIN   &ftinit_<FORMAT>_driver_chain
+ *
+ *   #endif 
+ * }
+ *
+ *  replace <FORMAT> with your driver's prefix
+ *
+ *************************************************************************/
+
+
+#ifdef FTINIT_DRIVER_CHAIN
+
+  static
+  const FT_DriverChain  ftinit_sfnt_driver_chain =
+  {
+    FT_INIT_LAST_DRIVER_CHAIN,
+    &sfnt_driver_interface
+  };
+
+#undef  FT_INIT_LAST_DRIVER_CHAIN
+#define FT_INIT_LAST_DRIVER_CHAIN   &ftinit_sfnt_driver_chain
+
+#endif /* FTINIT_DRIVER_CHAIN */ 
+
+
+
+#endif /* SFDRIVER_H */
+
+
+/* END */
diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c
new file mode 100644
index 0000000..d8eb06b
--- /dev/null
+++ b/src/sfnt/sfnt.c
@@ -0,0 +1,15 @@
+#include <sfconfig.h>
+#include <ttload.c>
+#include <ttcmap.c>
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#include <ttsbit.c>
+#endif
+
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+#include <ttpost.c>
+#endif
+
+#include <sfdriver.c>
+
+
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
new file mode 100644
index 0000000..1187e4e
--- /dev/null
+++ b/src/sfnt/ttcmap.c
@@ -0,0 +1,508 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttcmap.c                                                               */
+/*                                                                         */
+/*    TrueType character mapping table (cmap) support (body).              */
+/*                                                                         */
+/*  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 <ftdebug.h>
+
+#include <ttload.h>
+#include <ttcmap.h>
+#include <tterrors.h>
+
+/* required by the tracing mode */
+#undef  FT_COMPONENT
+#define FT_COMPONENT      trace_ttcmap
+
+
+  static TT_UInt  code_to_index0( TT_CMapTable*  charmap, TT_ULong  char_code );
+  static TT_UInt  code_to_index2( TT_CMapTable*  charmap, TT_ULong  char_code );
+  static TT_UInt  code_to_index4( TT_CMapTable*  charmap, TT_ULong  char_code );
+  static TT_UInt  code_to_index6( TT_CMapTable*  charmap, TT_ULong  char_code );      
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_CharMap_Load                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given TrueType character map into memory.                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the parent face object.                      */
+  /*    stream :: A handle to the current stream object.                   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    table  :: A pointer to a cmap object.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The function assumes that the stream is already in use (i.e.,      */
+  /*    opened).  In case of error, all partially allocated tables are     */
+  /*    released.                                                          */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_CharMap_Load( TT_Face        face,
+                             TT_CMapTable*  cmap,
+                             FT_Stream      stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory;
+    TT_UShort  num_SH, num_Seg, i;
+
+    TT_UShort  u, l;
+
+    TT_CMap0*  cmap0;
+    TT_CMap2*  cmap2;
+    TT_CMap4*  cmap4;
+    TT_CMap6*  cmap6;
+
+    TT_CMap2SubHeader* cmap2sub;
+    TT_CMap4Segment*   segments;
+
+
+    if ( cmap->loaded )
+      return TT_Err_Ok;
+
+    memory = stream->memory;
+
+    if ( FILE_Seek( cmap->offset ) )
+      return error;
+
+    switch ( cmap->format )
+    {
+    case 0:
+      cmap0 = &cmap->c.cmap0;
+
+      if ( ALLOC( cmap0->glyphIdArray, 256L )            ||
+           FILE_Read( (void*)cmap0->glyphIdArray, 256L ) )
+         goto Fail;
+
+      cmap->get_index = code_to_index0;
+      break;
+
+    case 2:
+      num_SH = 0;
+      cmap2  = &cmap->c.cmap2;
+
+      /* allocate subheader keys */
+
+      if ( ALLOC_ARRAY( cmap2->subHeaderKeys, 256, TT_UShort ) ||
+           ACCESS_Frame( 512L )                                )
+        goto Fail;
+
+      for ( i = 0; i < 256; i++ )
+      {
+        u = GET_UShort() / 8;
+        cmap2->subHeaderKeys[i] = u;
+
+        if ( num_SH < u )
+          num_SH = u;
+      }
+
+      FORGET_Frame();
+
+      /* load subheaders */
+
+      cmap2->numGlyphId = l =
+        ( ( cmap->length - 2L*(256+3) - num_SH*8L ) & 0xffff ) / 2;
+
+      if ( ALLOC_ARRAY( cmap2->subHeaders,
+                        num_SH + 1,
+                        TT_CMap2SubHeader )    ||
+           ACCESS_Frame( ( num_SH + 1 ) * 8L ) )
+        goto Fail;
+
+      cmap2sub = cmap2->subHeaders;
+
+      for ( i = 0; i <= num_SH; i++ )
+      {
+        cmap2sub->firstCode     = GET_UShort();
+        cmap2sub->entryCount    = GET_UShort();
+        cmap2sub->idDelta       = GET_Short();
+        /* we apply the location offset immediately */
+        cmap2sub->idRangeOffset = GET_UShort() - ( num_SH - i ) * 8 - 2;
+
+        cmap2sub++;
+      }
+
+      FORGET_Frame();
+
+      /* load glyph IDs */
+
+      if ( ALLOC_ARRAY( cmap2->glyphIdArray, l, TT_UShort ) ||
+           ACCESS_Frame( l * 2L )                           )
+        goto Fail;
+
+      for ( i = 0; i < l; i++ )
+        cmap2->glyphIdArray[i] = GET_UShort();
+
+      FORGET_Frame();
+      
+      cmap->get_index = code_to_index2;
+      break;
+
+    case 4:
+      cmap4 = &cmap->c.cmap4;
+
+      /* load header */
+
+      if ( ACCESS_Frame( 8L ) )
+        goto Fail;
+
+      cmap4->segCountX2    = GET_UShort();
+      cmap4->searchRange   = GET_UShort();
+      cmap4->entrySelector = GET_UShort();
+      cmap4->rangeShift    = GET_UShort();
+
+      num_Seg = cmap4->segCountX2 / 2;
+
+      FORGET_Frame();
+
+      /* load segments */
+
+      if ( ALLOC_ARRAY( cmap4->segments,
+                        num_Seg,
+                        TT_CMap4Segment )         ||
+           ACCESS_Frame( (num_Seg * 4 + 1) * 2L ) )
+        goto Fail;
+
+      segments = cmap4->segments;
+
+      for ( i = 0; i < num_Seg; i++ )
+        segments[i].endCount      = GET_UShort();
+
+      (void)GET_UShort();
+
+      for ( i = 0; i < num_Seg; i++ )
+        segments[i].startCount    = GET_UShort();
+
+      for ( i = 0; i < num_Seg; i++ )
+        segments[i].idDelta       = GET_Short();
+
+      for ( i = 0; i < num_Seg; i++ )
+        segments[i].idRangeOffset = GET_UShort();
+
+      FORGET_Frame();
+
+      cmap4->numGlyphId = l =
+        ( ( cmap->length - ( 16L + 8L * num_Seg ) ) & 0xFFFF ) /2;
+
+      /* load IDs */
+
+      if ( ALLOC_ARRAY( cmap4->glyphIdArray, l, TT_UShort ) ||
+           ACCESS_Frame( l*2L )                             )
+        goto Fail;
+
+      for ( i = 0; i < l; i++ )
+        cmap4->glyphIdArray[i] = GET_UShort();
+
+      FORGET_Frame();
+      
+      cmap->get_index = code_to_index4;
+      break;
+
+    case 6:
+      cmap6 = &cmap->c.cmap6;
+
+      if ( ACCESS_Frame( 4L ) )
+        goto Fail;
+
+      cmap6->firstCode  = GET_UShort();
+      cmap6->entryCount = GET_UShort();
+
+      FORGET_Frame();
+
+      l = cmap6->entryCount;
+
+      if ( ALLOC_ARRAY( cmap6->glyphIdArray,
+                        cmap6->entryCount,
+                        TT_Short )           ||
+           ACCESS_Frame( l * 2L )            )
+        goto Fail;
+
+      for ( i = 0; i < l; i++ )
+        cmap6->glyphIdArray[i] = GET_UShort();
+
+      FORGET_Frame();
+      cmap->get_index = code_to_index6;
+      break;
+
+    default:   /* corrupt character mapping table */
+      return TT_Err_Invalid_CharMap_Format;
+
+    }
+    return TT_Err_Ok;
+
+  Fail:
+    TT_CharMap_Free( face, cmap );
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_CharMap_Free                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a character mapping table.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the parent face object.                        */
+  /*    cmap :: A handle to a cmap object.                                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_CharMap_Free( TT_Face        face,
+                             TT_CMapTable*  cmap )
+  {
+    FT_Memory  memory;
+
+
+    if ( !cmap )
+      return TT_Err_Ok;
+
+    memory = face->root.driver->memory;
+
+    switch ( cmap->format )
+    {
+    case 0:
+      FREE( cmap->c.cmap0.glyphIdArray );
+      break;
+
+    case 2:
+      FREE( cmap->c.cmap2.subHeaderKeys );
+      FREE( cmap->c.cmap2.subHeaders );
+      FREE( cmap->c.cmap2.glyphIdArray );
+      break;
+
+    case 4:
+      FREE( cmap->c.cmap4.segments );
+      FREE( cmap->c.cmap4.glyphIdArray );
+      cmap->c.cmap4.segCountX2 = 0;
+      break;
+
+    case 6:
+      FREE( cmap->c.cmap6.glyphIdArray );
+      cmap->c.cmap6.entryCount = 0;
+      break;
+
+    default:
+      /* invalid table format, do nothing */
+      ;
+    }
+
+    cmap->loaded = FALSE;
+    return TT_Err_Ok;
+  }
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    code_to_index0                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Converts the character code into a glyph index.  Uses format 0.    */
+  /*    `charCode' must be in the range 0x00-0xFF (otherwise 0 is          */
+  /*    returned).                                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    charCode :: The wanted character code.                             */
+  /*    cmap0    :: A pointer to a cmap table in format 0.                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Glyph index into the glyphs array.  0 if the glyph does not        */
+  /*    exist.                                                             */
+  /*                                                                       */
+  static
+  TT_UInt code_to_index0( TT_CMapTable*  cmap,
+                          TT_ULong       charCode )
+  {
+    TT_CMap0*  cmap0 = &cmap->c.cmap0;
+    
+    return ( charCode <= 0xFF ? cmap0->glyphIdArray[charCode] : 0 );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    code_to_index2                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Converts the character code into a glyph index.  Uses format 2.    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    charCode :: The wanted character code.                             */
+  /*    cmap2    :: A pointer to a cmap table in format 2.                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Glyph index into the glyphs array.  0 if the glyph does not        */
+  /*    exist.                                                             */
+  /*                                                                       */
+  static
+  TT_UInt  code_to_index2( TT_CMapTable*  cmap,
+                           TT_ULong       charCode )
+  {
+    TT_UInt            result, index1, offset;
+    TT_UInt            char_lo;
+    TT_ULong           char_hi;
+    TT_CMap2SubHeader* sh2;
+    TT_CMap2*          cmap2;
+
+    cmap2   = &cmap->c.cmap2;
+    result  = 0;
+    char_lo = (TT_UInt)(charCode & 0xFF);
+    char_hi = charCode >> 8;
+
+    if ( char_hi == 0 )
+    {
+      /* an 8-bit character code - we use the subHeader 0 in this case */
+      /* to test wether the character code is in the charmap           */
+      if ( cmap2->subHeaderKeys[char_lo] == 0 )
+      {
+        result = cmap2->glyphIdArray[char_lo];
+      }
+    }
+    else
+    {
+      /* a 16-bit character code */
+      index1 = cmap2->subHeaderKeys[ char_hi & 0xFF ];
+      if (index1)
+      {
+        sh2      = cmap2->subHeaders + index1;
+        char_lo -= sh2->firstCode;
+
+        if (char_lo < sh2->entryCount)
+        {
+          offset = sh2->idRangeOffset/2 + char_lo;
+          if (offset < cmap2->numGlyphId)
+          {
+            result = cmap2->glyphIdArray[offset];
+            if (result)
+              result = (result + sh2->idDelta) & 0xFFFF;
+          }
+        }
+      }
+    }
+    return result;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    code_to_index4                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Converts the character code into a glyph index.  Uses format 4.    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    charCode :: The wanted character code.                             */
+  /*    cmap4    :: A pointer to a cmap table in format 4.                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Glyph index into the glyphs array.  0 if the glyph does not        */
+  /*    exist.                                                             */
+  /*                                                                       */
+  static
+  TT_UInt  code_to_index4( TT_CMapTable*  cmap,
+                           TT_ULong       charCode )
+  {
+    TT_UInt          result, index1, segCount;
+    TT_CMap4*        cmap4;
+    TT_CMap4Segment  *seg4, *limit;
+
+    cmap4    = &cmap->c.cmap4;
+    result   = 0;
+    segCount = cmap4->segCountX2 / 2;
+    seg4     = cmap4->segments;
+    limit    = seg4 + segCount;
+
+    for ( ; seg4 < limit; seg4++ )
+    {
+      if ( charCode <= seg4->endCount )
+      {
+        /* the ranges are sorted in increasing order, if we're out of  */
+        /* the range here, the char code isn't in the charmap, so exit */
+        if ( charCode < seg4->startCount )
+          break;
+
+        /* when the idRangeOffset is 0, we can compute the glyph index */
+        /* directly..                                                  */
+        if ( seg4->idRangeOffset == 0 )
+          result = (charCode + seg4->idDelta) & 0xFFFF;
+        else
+        /* otherwise, we must use the glyphIdArray to do it            */
+        {
+          index1 = seg4->idRangeOffset/2 + (charCode - seg4->startCount)
+                   - (segCount-1);
+
+          if ( index1 < cmap4->numGlyphId       &&
+               cmap4->glyphIdArray[index1] != 0 )
+          {
+            result = (cmap4->glyphIdArray[index1] + seg4->idDelta) & 0xFFFF;
+          }
+        }
+        break;
+      }
+    }
+
+    return result;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    code_to_index6                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Converts the character code into a glyph index.  Uses format 6.    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    charCode :: The wanted character code.                             */
+  /*    cmap6    :: A pointer to a cmap table in format 6.                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Glyph index into the glyphs array.  0 if the glyph does not        */
+  /*    exist.                                                             */
+  /*                                                                       */
+  static
+  TT_UInt  code_to_index6( TT_CMapTable*  cmap,
+                           TT_ULong   charCode )
+  {
+    TT_CMap6*  cmap6;
+    TT_UInt    result = 0;
+
+    cmap6     = &cmap->c.cmap6;
+    result    = 0;
+    charCode -= cmap6->firstCode;
+
+    if ( charCode < cmap6->entryCount )
+      result =  cmap6->glyphIdArray[charCode];
+
+    return result;
+  }
+
+
+/* END */
diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h
new file mode 100644
index 0000000..d5da240
--- /dev/null
+++ b/src/sfnt/ttcmap.h
@@ -0,0 +1,84 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttcmap.h                                                               */
+/*                                                                         */
+/*    TrueType character mapping table (cmap) support (specification).     */
+/*                                                                         */
+/*  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 TTCMAP_H
+#define TTCMAP_H
+
+#include <tttypes.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_CharMap_Load                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given TrueType character map into memory.                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the parent face object.                      */
+  /*    stream :: A handle to the current stream object.                   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    cmap   :: A pointer to a cmap object.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The function assumes that the stream is already in use (i.e.,      */
+  /*    opened).  In case of error, all partially allocated tables are     */
+  /*    released.                                                          */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_CharMap_Load( TT_Face        face,
+                             TT_CMapTable*  cmap,
+                             FT_Stream      input );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_CharMap_Free                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a character mapping table.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the parent face object.                        */
+  /*    cmap :: A handle to a cmap object.                                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_CharMap_Free( TT_Face        face,
+                             TT_CMapTable*  cmap );
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* TTCMAP_H */
+
+
+/* END */
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
new file mode 100644
index 0000000..dbdde79
--- /dev/null
+++ b/src/sfnt/ttload.c
@@ -0,0 +1,1477 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttload.c                                                               */
+/*                                                                         */
+/*    TrueType tables loader (body).                                       */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/*                                                                         */
+/*  WARNING: This file should not be compiled directly; it is meant to be  */
+/*           included in the source of several font drivers (i.e., the TTF */
+/*           and OTF drivers).                                             */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ftdebug.h>
+
+#include <ttload.h>
+#include <tttags.h>
+#include <ttcmap.h>
+#include <tterrors.h>
+
+/* required by the tracing mode */
+#undef  FT_COMPONENT
+#define FT_COMPONENT      trace_ttload
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_LookUp_Table                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Looks for a TrueType table by name.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A face object handle.                                      */
+  /*    tag  :: The  searched tag.                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    pointer to table directory entry. 0 if not found..                 */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Table*  TT_LookUp_Table( TT_Face   face,
+                              TT_ULong  tag  )
+  {
+    TT_Table*  entry;
+    TT_Table*  limit;
+    
+    FT_TRACE4(( "TT_LookUp_Table( %08lx, %c%c%c%c )\n",
+                  (TT_Long)face,
+                  (TT_Char)(tag >> 24),
+                  (TT_Char)(tag >> 16),
+                  (TT_Char)(tag >> 8),
+                  (TT_Char)(tag) ));
+
+    entry = face->dir_tables;
+    limit = entry + face->num_tables;
+    for ( ; entry < limit; entry++ )
+    {
+      if ( entry->Tag == tag )
+        return entry;
+    }    
+    FT_TRACE4(( "    Could not find table!\n" ));
+    return 0;
+  }
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Goto_Table                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Looks for a TrueType table by name, then seek a stream to it.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: a face object handle.                                    */
+  /*    tag    :: the  searched tag.                                       */
+  /*    stream :: the stream to seek when the table is found               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    pointer to table directory entry. 0 if not found..                 */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error   TT_Goto_Table( TT_Face    face,
+                            TT_ULong   tag,
+                            FT_Stream  stream,
+                            TT_ULong  *length )
+  {
+    TT_Table*  table;
+    TT_Error   error;
+    
+    table = TT_LookUp_Table( face, tag );
+    if (table)
+    {
+      if (length)
+        *length = table->Length;
+        
+      (void)FILE_Seek( table->Offset );
+    }
+    else
+      error = TT_Err_Table_Missing;
+      
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Directory                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the table directory into a face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face      :: A handle to the target face object.                   */
+  /*    stream    :: The input stream.                                     */
+  /*    faceIndex :: The index of the TrueType font, if we're opening a    */
+  /*                 collection.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The stream cursor must be at the font file's origin                */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Directory( TT_Face    face,
+                               FT_Stream  stream,
+                               TT_Long    faceIndex )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_TableDir  tableDir;
+    TT_ULong     tag;
+
+    TT_Table *entry, *limit;
+
+
+    FT_TRACE2(( "TT_Load_Directory( %08lx, %ld )\n",
+              (TT_Long)face, faceIndex ));
+
+    face->ttc_header.Tag      = 0;
+    face->ttc_header.version  = 0;
+    face->ttc_header.DirCount = 0;
+
+    face->num_tables = 0;
+
+    /* first of all, read the  first 4 bytes. If it's `ttcf', then the */
+    /* file is a TrueType collection, otherwise it must be a normal    */
+    /* TrueType file..                                                 */
+
+    if ( READ_ULong(tag) )
+      goto Exit;
+
+    if ( tag == TTAG_ttcf )
+    {
+      TT_Int  n;
+    
+      FT_TRACE4(( "TT_Load_Directory: file is a collection\n" ));
+      
+      /* it's a TrueType collection, i.e. a file containing several */
+      /* font files. Read the font directory now                    */
+      /*                                                            */
+      if ( ACCESS_Frame( 8 ) ) goto Exit;   
+        
+      face->ttc_header.version  = GET_Long();
+      face->ttc_header.DirCount = GET_Long();
+           
+      FORGET_Frame();
+
+      /* now read the offsets of each font in the file         */
+      /*                                                       */
+      if ( ALLOC_ARRAY( face->ttc_header.TableDirectory,
+                        face->ttc_header.DirCount,
+                        TT_ULong )                        ||
+           ACCESS_Frame( face->ttc_header.DirCount * 4L ) )
+        goto Exit;
+
+      for ( n = 0; n < face->ttc_header.DirCount; n++ )
+        face->ttc_header.TableDirectory[n] = GET_ULong();
+
+      FORGET_Frame();
+
+      /* check face index */
+      if (faceIndex >= face->ttc_header.DirCount)
+      {
+        error = TT_Err_Bad_Argument;
+        goto Exit;
+      }      
+      
+      /* if we're checking the font format, exit immediately */
+      if (faceIndex < 0)
+        goto Exit;
+        
+      /* seek to the appropriate TrueType file, then read tag */
+      if ( FILE_Skip( face->ttc_header.TableDirectory[faceIndex] - 12 ) ||
+           READ_Long( tableDir.version )                                )
+        goto Exit;
+    }
+    else
+    {
+      FT_TRACE6(( "TT_Load_Directory: file is not a collection\n" ));
+      /* the file isn't a collection, exit if we're asking for a */
+      /* collected font..                                        */
+      if (faceIndex > 0)
+      {
+        error = TT_Err_File_Is_Not_Collection;
+        goto Exit;
+      }
+      
+      tableDir.version = tag;
+    }
+
+    if ( ACCESS_Frame( 8L ) )
+      goto Exit;
+
+    tableDir.numTables = GET_UShort();
+
+    tableDir.searchRange   = GET_UShort();
+    tableDir.entrySelector = GET_UShort();
+    tableDir.rangeShift    = GET_UShort();
+
+    FORGET_Frame();
+
+    FT_TRACE2(( "-- Tables count   : %12u\n",  tableDir.numTables ));
+    FT_TRACE2(( "-- Format version : %08lx\n", tableDir.version ));
+
+    /* Check that we have a `sfnt' format there                        */
+    /* We must also be able to accept Mac/GX fonts, as well as OT ones */
+
+    if ( tableDir.version != 0x00010000 &&    /* MS fonts          */
+         tableDir.version != TTAG_true  &&    /* Mac fonts         */
+         tableDir.version != TTAG_OTTO  )    /* OT-Type2 fonts    */
+    {
+      FT_TRACE2(( "[not a valid TTF or OTF font]" ));
+      error = TT_Err_Invalid_File_Format;
+      goto Exit;
+    }
+
+    /* if we're performing a font format check, exit immediately */
+    /* with success                                              */
+    if ( faceIndex < 0 )
+      goto Exit;
+
+    face->num_tables = tableDir.numTables;
+
+    if ( ALLOC_ARRAY( face->dir_tables,
+                      face->num_tables,
+                      TT_Table ) )
+      goto Exit;
+
+    if ( ACCESS_Frame( face->num_tables * 16L ) )
+      goto Exit;
+
+    entry = face->dir_tables;
+    limit = entry + face->num_tables;
+
+    for ( ; entry < limit; entry++ )
+    {                      /* loop through the tables and get all entries */
+      entry->Tag      = GET_Tag4();
+      entry->CheckSum = GET_ULong();
+      entry->Offset   = GET_Long();
+      entry->Length   = GET_Long();
+
+      FT_TRACE2(( "  %c%c%c%c  -  %08lx  -  %08lx\n",
+                (TT_Char)(entry->Tag >> 24),
+                (TT_Char)(entry->Tag >> 16),
+                (TT_Char)(entry->Tag >> 8 ),
+                (TT_Char)(entry->Tag),
+                entry->Offset,
+                entry->Length ));
+    }
+
+    FORGET_Frame();
+
+    FT_TRACE2(( "Directory loaded\n\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Any                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads any font table into client memory.  Used by the              */
+  /*    TT_Get_Font_Data() API function.                                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: The face object to look for.                             */
+  /*                                                                       */
+  /*    tag    :: The tag of table to load.  Use the value 0 if you  want  */
+  /*              to access the whole font file, else set this parameter   */
+  /*              to a valid TrueType table tag that you can forge with    */
+  /*              the MAKE_TT_TAG macro.                                   */
+  /*                                                                       */
+  /*    offset :: The starting offset in the table (or the file if         */
+  /*              tag == 0).                                               */
+  /*                                                                       */
+  /*    length :: The address of the decision variable:                    */
+  /*                                                                       */
+  /*                If length == NULL:                                     */
+  /*                  Loads the whole table.  Returns an error if          */
+  /*                  `offset' == 0!                                       */
+  /*                                                                       */
+  /*                If *length == 0:                                       */
+  /*                  Exits immediately; returning the length of the given */
+  /*                  table or of the font file, depending on the value of */
+  /*                  `tag'.                                               */
+  /*                                                                       */
+  /*                If *length != 0:                                       */
+  /*                  Loads the next `length' bytes of table or font,      */
+  /*                  starting at offset `offset' (in table or font too).  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    buffer :: The address of target buffer.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Any( TT_Face   face,
+                         TT_ULong  tag,
+                         TT_Long   offset,
+                         void*     buffer,
+                         TT_Long*  length )
+  {
+    TT_Error   error;
+    FT_Stream  stream;
+    TT_Table*  table;
+    TT_ULong   size;
+
+    if ( tag != 0 )
+    {
+      /* look for tag in font directory */
+      table = TT_LookUp_Table( face, tag );
+      if ( !table )
+      {
+        error = TT_Err_Table_Missing;
+        goto Exit;
+      }
+
+      offset += table->Offset;
+      size    = table->Length;
+    }
+    else
+    /* tag = 0 -- the use want to access the font file directly */
+    {
+      size = face->root.stream->size;
+    }
+
+    if ( length && *length == 0 )
+    {
+      *length = size;
+      return TT_Err_Ok;
+    }
+
+    if ( length )
+      size = *length;
+
+    stream = face->root.stream;
+    (void)FILE_Read_At( offset, buffer, size );
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Header                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the TrueType font header.                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Header( TT_Face    face,
+                            FT_Stream  stream )
+  {
+    TT_Error    error;
+    TT_Header*  header;
+
+
+    FT_TRACE2(( "Load_TT_Header( %08lx )\n", (TT_Long)face ));
+
+    error = face->goto_table( face, TTAG_head, stream, 0 );
+    if ( error )
+    {
+      FT_TRACE0(( "Font Header is missing!\n" ));
+      goto Exit;
+    }
+
+    if ( ACCESS_Frame( 54L ) )
+      goto Exit;
+
+    header = &face->header;
+
+    header->Table_Version = GET_ULong();
+    header->Font_Revision = GET_ULong();
+
+    header->CheckSum_Adjust = GET_Long();
+    header->Magic_Number    = GET_Long();
+
+    header->Flags        = GET_UShort();
+    header->Units_Per_EM = GET_UShort();
+
+    header->Created [0] = GET_Long();
+    header->Created [1] = GET_Long();
+    header->Modified[0] = GET_Long();
+    header->Modified[1] = GET_Long();
+
+    header->xMin = GET_Short();
+    header->yMin = GET_Short();
+    header->xMax = GET_Short();
+    header->yMax = GET_Short();
+
+    header->Mac_Style       = GET_UShort();
+    header->Lowest_Rec_PPEM = GET_UShort();
+
+    header->Font_Direction      = GET_Short();
+    header->Index_To_Loc_Format = GET_Short();
+    header->Glyph_Data_Format   = GET_Short();
+
+    FORGET_Frame();
+
+    FT_TRACE2(( "    Units per EM : %8u\n", header->Units_Per_EM ));
+    FT_TRACE2(( "    IndexToLoc   : %8d\n", header->Index_To_Loc_Format ));
+    FT_TRACE2(( "Font Header Loaded.\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_MaxProfile                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the maximum profile into a face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_MaxProfile( TT_Face    face,
+                                FT_Stream  stream )
+  {
+    TT_Error        error;
+    TT_MaxProfile*  maxProfile = &face->max_profile;
+
+
+    FT_TRACE2(( "Load_TT_MaxProfile( %08lx )\n", (TT_Long)face ));
+
+    error = face->goto_table( face, TTAG_maxp, stream, 0 );
+    if (error) goto Exit;
+
+    if ( ACCESS_Frame( 32L ) )
+      goto Exit;
+
+    /* read frame data into face table */
+    maxProfile->version               = GET_ULong();
+    maxProfile->numGlyphs             = GET_UShort();
+
+    maxProfile->maxPoints             = GET_UShort();
+    maxProfile->maxContours           = GET_UShort();
+    maxProfile->maxCompositePoints    = GET_UShort();
+    maxProfile->maxCompositeContours  = GET_UShort();
+
+    maxProfile->maxZones              = GET_UShort();
+    maxProfile->maxTwilightPoints     = GET_UShort();
+
+    maxProfile->maxStorage            = GET_UShort();
+    maxProfile->maxFunctionDefs       = GET_UShort();
+    maxProfile->maxInstructionDefs    = GET_UShort();
+    maxProfile->maxStackElements      = GET_UShort();
+    maxProfile->maxSizeOfInstructions = GET_UShort();
+    maxProfile->maxComponentElements  = GET_UShort();
+    maxProfile->maxComponentDepth     = GET_UShort();
+
+    FORGET_Frame();
+
+    /* XXX: an adjustment that is necessary to load certain */
+    /*       broken fonts like `Keystrokes MT' :-(          */
+    /*                                                      */
+    /*   We allocate 64 function entries by default when    */
+    /*   the maxFunctionDefs field is null.                 */
+
+    if ( maxProfile->maxFunctionDefs == 0 )
+      maxProfile->maxFunctionDefs = 64;
+
+    face->root.num_glyphs = maxProfile->numGlyphs;
+
+    face->root.max_points = MAX( maxProfile->maxCompositePoints,
+                                 maxProfile->maxPoints );
+
+    face->root.max_contours = MAX( maxProfile->maxCompositeContours,
+                                   maxProfile->maxContours );
+
+    face->max_components = (TT_ULong)maxProfile->maxComponentElements +
+                           maxProfile->maxComponentDepth;
+
+    /* XXX: some fonts have maxComponents set to 0; we will */
+    /*      then use 16 of them by default.                 */
+    if ( face->max_components == 0 )
+      face->max_components = 16;
+
+    /* We also increase maxPoints and maxContours in order to support */
+    /* some broken fonts.                                             */
+    face->root.max_points   += 8;
+    face->root.max_contours += 4;
+
+    FT_TRACE2(( "MAXP loaded.\n" ));
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Metrics                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal or vertical metrics table into a face object. */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face     :: A handle to the target face object.                    */
+  /*    stream   :: The input stream.                                      */
+  /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  TT_Load_Metrics( TT_Face    face,
+                             FT_Stream  stream,
+                             TT_Bool    vertical )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_ULong   table_len;
+    TT_Long    num_shorts, num_longs, num_shorts_checked;
+
+    TT_LongMetrics**   longs;
+    TT_ShortMetrics**  shorts;
+
+    FT_TRACE2(( "TT_Load_%s_Metrics( %08lx )\n",
+              vertical ? "Vertical" : "Horizontal", (TT_Long)face ));
+
+    if ( vertical )
+    {
+      /* The table is optional, quit silently if it wasn't found       */
+      /* XXX: Some fonts have a valid vertical header with a non-null  */
+      /*      `number_of_VMetrics' fields, but no corresponding `vmtx' */
+      /*      table to get the metrics from (e.g. mingliu).            */
+      /*                                                               */
+      /*      For safety, we set the field to 0!                       */
+      /*                                                               */
+      error = face->goto_table( face, TTAG_vmtx, stream, &table_len );
+      if ( error )
+      {
+        /* Set the number_Of_VMetrics to 0! */
+        FT_TRACE2(( "  no vertical header in file.\n" ));
+        face->vertical.number_Of_VMetrics = 0;
+        error = TT_Err_Ok;
+        goto Exit;
+      }
+
+      num_longs = face->vertical.number_Of_VMetrics;
+      longs     = (TT_LongMetrics**)&face->vertical.long_metrics;
+      shorts    = (TT_ShortMetrics**)&face->vertical.short_metrics;
+    }
+    else
+    {
+      error = face->goto_table( face, TTAG_hmtx, stream, &table_len );
+      if (error)
+      {
+        FT_ERROR(( " no horizontal metrics in file!\n" ));
+        error = TT_Err_Hmtx_Table_Missing;
+        goto Exit;
+      }
+
+      num_longs = face->horizontal.number_Of_HMetrics;
+      longs     = (TT_LongMetrics**)&face->horizontal.long_metrics;
+      shorts    = (TT_ShortMetrics**)&face->horizontal.short_metrics;
+    }
+
+    /* never trust derived values */
+
+    num_shorts         = face->max_profile.numGlyphs - num_longs;
+    num_shorts_checked = ( table_len - num_longs*4L )/2;
+
+    if ( num_shorts < 0 )
+    {
+      FT_ERROR(( "!! more metrics than glyphs!\n" ));
+      error = ( vertical ? TT_Err_Invalid_Vert_Metrics
+                         : TT_Err_Invalid_Horiz_Metrics );
+      goto Exit;
+    }
+
+    if ( ALLOC_ARRAY( *longs,  num_longs,  TT_LongMetrics ) ||
+         ALLOC_ARRAY( *shorts, num_shorts, TT_ShortMetrics ) )
+      goto Exit;
+
+    if ( ACCESS_Frame( table_len ) )
+      goto Exit;
+
+    {
+      TT_LongMetrics*  cur   = *longs;
+      TT_LongMetrics*  limit = cur + num_longs;
+
+      for ( ; cur < limit; cur++ )
+      {
+        cur->advance = GET_UShort();
+        cur->bearing = GET_Short();
+      }
+    }
+
+    /* do we have an inconsistent number of metric values ? */
+    {
+      TT_ShortMetrics*  cur   = *shorts;
+      TT_ShortMetrics*  limit = cur + MIN( num_shorts, num_shorts_checked );
+
+      for ( ; cur < limit; cur++ )
+        *cur = GET_Short();
+
+      /* we fill up the missing left side bearings with the    */
+      /* last valid value. Since this will occur for buggy CJK */
+      /* fonts usually, nothing serious will happen            */
+      if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 )
+      {
+        TT_Short  val = *(shorts)[num_shorts_checked-1];
+
+        limit = *shorts + num_shorts;
+        for ( ; cur < limit; cur++ )
+          *cur = val;
+      }
+    }
+
+    FORGET_Frame();
+
+    FT_TRACE2(( "loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Metrics_Header                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal or vertical header in a face object.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face     :: A handle to the target face object.                    */
+  /*    stream   :: The input stream.                                      */
+  /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Metrics_Header( TT_Face    face,
+                                    FT_Stream  stream,
+                                    TT_Bool    vertical )
+  {
+    TT_Error        error;
+    TT_HoriHeader*  header;
+
+    FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " ));
+
+    if ( vertical )
+    {
+      face->vertical_info = 0;
+
+      /* The vertical header table is optional, so return quietly if */
+      /* we don't find it.                                           */
+      error = face->goto_table( face, TTAG_vhea, stream, 0 );
+      if (error)
+      {
+        error = TT_Err_Ok;
+        goto Exit;
+      }
+
+      face->vertical_info = 1;
+      header = (TT_HoriHeader*)&face->vertical;
+    }
+    else
+    {
+      /* The horizontal header is mandatory, return an error if we */
+      /* don't find it.                                            */
+      error = face->goto_table( face, TTAG_hhea, stream, 0 );
+      if (error)
+      {
+        error = TT_Err_Horiz_Header_Missing;
+        goto Exit;
+      }
+
+      header = &face->horizontal;
+    }
+
+    if ( ACCESS_Frame( 36L ) )
+      goto Exit;
+
+    header->Version   = GET_ULong();
+    header->Ascender  = GET_Short();
+    header->Descender = GET_Short();
+    header->Line_Gap  = GET_Short();
+
+    header->advance_Width_Max = GET_UShort();
+
+    header->min_Left_Side_Bearing  = GET_Short();
+    header->min_Right_Side_Bearing = GET_Short();
+    header->xMax_Extent            = GET_Short();
+    header->caret_Slope_Rise       = GET_Short();
+    header->caret_Slope_Run        = GET_Short();
+
+    header->Reserved[0] = GET_Short();  /* this is caret_Offset for
+                                           vertical headers */
+    header->Reserved[1] = GET_Short();
+    header->Reserved[2] = GET_Short();
+    header->Reserved[3] = GET_Short();
+    header->Reserved[4] = GET_Short();
+
+    header->metric_Data_Format = GET_Short();
+    header->number_Of_HMetrics = GET_UShort();
+
+    FORGET_Frame();
+
+    header->long_metrics  = NULL;
+    header->short_metrics = NULL;
+
+    FT_TRACE2(( "loaded\n" ));
+
+    /* Now try to load the corresponding metrics */
+
+    error = TT_Load_Metrics( face, stream, vertical );
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the name records.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Names( TT_Face  face, FT_Stream  stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_ULong   table_pos, table_len;
+    TT_ULong   storageSize;
+
+    TT_NameTable*  names;
+
+
+    FT_TRACE2(( "Names " ));
+
+    error = face->goto_table( face, TTAG_name, stream, &table_len );
+    if (error)
+    {
+      /* The name table is required so indicate failure. */
+      FT_TRACE2(( "is missing!\n" ));
+      error = TT_Err_Name_Table_Missing;
+      goto Exit;
+    }
+
+    table_pos = FILE_Pos();
+
+    if ( ACCESS_Frame( 6L ) )
+      goto Exit;
+
+    names = &face->name_table;
+
+    /* Load the initial names data. */
+    names->format         = GET_UShort();
+    names->numNameRecords = GET_UShort();
+    names->storageOffset  = GET_UShort();
+
+    FORGET_Frame();
+
+    /* Allocate the array of name records. */
+    if ( ALLOC_ARRAY( names->names,
+                      names->numNameRecords,
+                      TT_NameRec )                   ||
+         ACCESS_Frame( names->numNameRecords * 12L ) )
+      goto Exit;
+
+    /* Load the name records and determine how much storage is needed */
+    /* to hold the strings themselves.                                */
+    {
+      TT_NameRec*    cur   = names->names;
+      TT_NameRec*    limit = cur + names->numNameRecords;
+
+      storageSize = 0;
+
+      for ( ; cur < limit; cur ++ )
+      {
+        TT_ULong  upper;
+
+        cur->platformID   = GET_UShort();
+        cur->encodingID   = GET_UShort();
+        cur->languageID   = GET_UShort();
+        cur->nameID       = GET_UShort();
+        cur->stringLength = GET_UShort();
+        cur->stringOffset = GET_UShort();
+
+        upper = (TT_ULong)(cur->stringOffset + cur->stringLength);
+        if ( upper > storageSize ) storageSize = upper;
+      }
+    }
+
+    FORGET_Frame();
+
+    if (storageSize > 0)
+    {
+      /* allocate the name storage area in memory, then read it */
+      if ( ALLOC( names->storage, storageSize )  ||
+           FILE_Read_At( table_pos + names->storageOffset,
+                         (void*)names->storage, storageSize ) )
+        goto Exit;
+  
+      /* Go through and assign the string pointers to the name records. */
+      {
+        TT_NameRec*  cur   = names->names;
+        TT_NameRec*  limit = cur + names->numNameRecords;
+  
+        for ( ; cur < limit; cur++ )
+          cur->string = names->storage + cur->stringOffset;
+      }
+
+#ifdef FT_DEBUG_LEVEL_TRACE  
+      /* Print Name Record Table in case of debugging */
+      {
+        TT_NameRec*  cur   = names->names;
+        TT_NameRec*  limit = cur + names->numNameRecords;
+
+        for ( ; cur < limit; cur++ )
+        {
+          TT_UInt  j;
+    
+          FT_TRACE2(( "%d %d %x %d ",
+                       cur->platformID,
+                       cur->encodingID,
+                       cur->languageID,
+                       cur->nameID ));
+    
+          /* I know that M$ encoded strings are Unicode,            */
+          /* but this works reasonable well for debugging purposes. */
+          if ( cur->string )
+            for ( j = 0; j < cur->stringLength; j++ )
+            {
+              TT_Char  c = *(cur->string + j);
+    
+              if ( (TT_Byte)c < 128 )
+                FT_TRACE2(( "%c", c ));
+            }
+        }
+      }
+      FT_TRACE2(( "\n" ));
+#endif
+    }
+    FT_TRACE2(( "loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Frees the name records.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target face object.                        */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  TT_Free_Names( TT_Face  face )
+  {
+    FT_Memory      memory = face->root.driver->memory;
+    TT_NameTable*  names  = &face->name_table;
+
+
+    /* free strings table */
+    FREE( names->names );
+
+    /* free strings storage */
+    FREE( names->storage );
+
+    names->numNameRecords = 0;
+    names->format         = 0;
+    names->storageOffset  = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_CMap                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the cmap directory in a face object.  The cmaps itselves are */
+  /*    loaded on demand in the `ttcmap.c' module.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face    :: A handle to the target face object.                     */
+  /*    stream  :: A handle to the input stream.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*     TrueType error code.  0 means success.                            */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_CMap( TT_Face    face,
+                          FT_Stream  stream )
+  {
+    TT_Error    error;
+    FT_Memory   memory = stream->memory;
+    TT_Long     off, cur_off, table_start;
+    TT_CMapDir  cmap_dir;
+
+    FT_TRACE2(( "CMaps " ));
+
+    error = face->goto_table( face, TTAG_cmap, stream, 0 );
+    if (error)
+    {
+      error = TT_Err_CMap_Table_Missing;
+      goto Exit;
+    }
+
+    table_start = FILE_Pos();
+
+    if ( ACCESS_Frame( 4L ) )           /* 4 bytes cmap header */
+      goto Exit;
+
+    cmap_dir.tableVersionNumber = GET_UShort();
+    cmap_dir.numCMaps           = GET_UShort();
+
+    FORGET_Frame();
+
+    off = FILE_Pos();  /* save offset to cmapdir[] which follows */
+
+    /* save space in face table for cmap tables */
+    if ( ALLOC_ARRAY( face->charmaps,
+                      cmap_dir.numCMaps,
+                      TT_CharMapRec ) )
+      goto Exit;
+
+    face->num_charmaps = cmap_dir.numCMaps;
+    {
+      TT_CharMap  charmap = face->charmaps;
+      TT_CharMap  limit   = charmap + face->num_charmaps;
+
+      for ( ; charmap < limit; charmap++ )
+      {
+        TT_CMapTable*  cmap;
+
+        charmap->root.face = (FT_Face)face;
+        cmap               = &charmap->cmap;
+
+        if ( FILE_Seek( off )  ||
+             ACCESS_Frame( 8L ) )
+          goto Exit;
+
+        cmap->loaded             = FALSE;
+        cmap->platformID         = GET_UShort();
+        cmap->platformEncodingID = GET_UShort();
+
+        cur_off = GET_Long();
+
+        FORGET_Frame();
+
+        off = FILE_Pos();
+
+        if ( FILE_Seek( table_start + cur_off ) ||
+             ACCESS_Frame( 6L ) )
+          goto Exit;
+
+        cmap->format  = GET_UShort();
+        cmap->length  = GET_UShort();
+        cmap->version = GET_UShort();
+
+        FORGET_Frame();
+
+        cmap->offset = FILE_Pos();
+        charmap++;
+      }
+    }
+
+    FT_TRACE2(( "loaded\n" ));
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_OS2                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the OS2 table.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_OS2( TT_Face    face,
+                         FT_Stream  stream )
+  {
+    TT_Error  error;
+    TT_Int    j;
+    TT_OS2*   os2;
+
+
+    FT_TRACE2(( "OS/2 Table " ));
+
+    /* We now support old Mac fonts where the OS/2 table doesn't  */
+    /* exist.  Simply put, we set the `version' field to 0xFFFF   */
+    /* and test this value each time we need to access the table. */
+    error = face->goto_table( face, TTAG_OS2, stream, 0 );
+    if (error)
+    {
+      FT_TRACE2(( "is missing\n!" ));
+      face->os2.version = 0xFFFF;
+      error = TT_Err_Ok;
+      goto Exit;
+    }
+
+    if ( ACCESS_Frame( 78L ) )
+      goto Exit;
+
+    os2 = &face->os2;
+
+    os2->version             = GET_UShort();
+    os2->xAvgCharWidth       = GET_Short();
+    os2->usWeightClass       = GET_UShort();
+    os2->usWidthClass        = GET_UShort();
+    os2->fsType              = GET_Short();
+    os2->ySubscriptXSize     = GET_Short();
+    os2->ySubscriptYSize     = GET_Short();
+    os2->ySubscriptXOffset   = GET_Short();
+    os2->ySubscriptYOffset   = GET_Short();
+    os2->ySuperscriptXSize   = GET_Short();
+    os2->ySuperscriptYSize   = GET_Short();
+    os2->ySuperscriptXOffset = GET_Short();
+    os2->ySuperscriptYOffset = GET_Short();
+    os2->yStrikeoutSize      = GET_Short();
+    os2->yStrikeoutPosition  = GET_Short();
+    os2->sFamilyClass        = GET_Short();
+
+    for ( j = 0; j < 10; j++ )
+      os2->panose[j] = GET_Byte();
+
+    os2->ulUnicodeRange1     = GET_ULong();
+    os2->ulUnicodeRange2     = GET_ULong();
+    os2->ulUnicodeRange3     = GET_ULong();
+    os2->ulUnicodeRange4     = GET_ULong();
+
+    for ( j = 0; j < 4; j++ )
+      os2->achVendID[j] = GET_Byte();
+
+    os2->fsSelection         = GET_UShort();
+    os2->usFirstCharIndex    = GET_UShort();
+    os2->usLastCharIndex     = GET_UShort();
+    os2->sTypoAscender       = GET_Short();
+    os2->sTypoDescender      = GET_Short();
+    os2->sTypoLineGap        = GET_Short();
+    os2->usWinAscent         = GET_UShort();
+    os2->usWinDescent        = GET_UShort();
+
+    FORGET_Frame();
+
+    os2->ulCodePageRange1 = 0;
+    os2->ulCodePageRange2 = 0;
+
+    if ( os2->version >= 0x0001 )
+    {
+      /* only version 1 tables */
+
+      if ( ACCESS_Frame( 8L ) )  /* read into frame */
+        goto Exit;
+
+      os2->ulCodePageRange1 = GET_ULong();
+      os2->ulCodePageRange2 = GET_ULong();
+
+      FORGET_Frame();
+    }
+
+    FT_TRACE2(( "loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Postscript                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the Postscript table.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_PostScript( TT_Face    face,
+                                FT_Stream  stream )
+  {
+    TT_Error        error;
+    TT_Postscript*  post = &face->postscript;
+
+    FT_TRACE2(( "PostScript " ));
+
+    error = face->goto_table( face, TTAG_post, stream, 0 );
+    if (error)
+      return TT_Err_Post_Table_Missing;
+
+    if ( ACCESS_Frame( 32L ) )
+      return error;
+
+    /* read frame data into face table */
+
+    post->FormatType         = GET_ULong();
+    post->italicAngle        = GET_ULong();
+    post->underlinePosition  = GET_Short();
+    post->underlineThickness = GET_Short();
+    post->isFixedPitch       = GET_ULong();
+    post->minMemType42       = GET_ULong();
+    post->maxMemType42       = GET_ULong();
+    post->minMemType1        = GET_ULong();
+    post->maxMemType1        = GET_ULong();
+
+    FORGET_Frame();
+
+    /* we don't load the glyph names, we do that in another */
+    /* module (ttpost).                                     */
+    FT_TRACE2(( "loaded\n" ));
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Gasp                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the `GASP' table into a face object.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Gasp( TT_Face    face,
+                          FT_Stream  stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_UInt        j,num_ranges;
+    TT_GaspRange*  gaspranges;
+
+
+    FT_TRACE2(( "TT_Load_Gasp( %08lx )\n", (TT_Long)face ));
+
+    /* the gasp table is optional */
+    error = face->goto_table( face, TTAG_gasp, stream, 0 );
+    if (error) return TT_Err_Ok;
+
+    if ( ACCESS_Frame( 4L ) )
+      goto Exit;
+
+    face->gasp.version   = GET_UShort();
+    face->gasp.numRanges = GET_UShort();
+
+    FORGET_Frame();
+
+    num_ranges = face->gasp.numRanges;
+    FT_TRACE3(( "number of ranges = %d\n", num_ranges ));
+
+    if ( ALLOC_ARRAY( gaspranges, num_ranges, TT_GaspRange ) ||
+         ACCESS_Frame( num_ranges * 4L ) )
+      goto Exit;
+
+    face->gasp.gaspRanges = gaspranges;
+
+    for ( j = 0; j < num_ranges; j++ )
+    {
+      gaspranges[j].maxPPEM  = GET_UShort();
+      gaspranges[j].gaspFlag = GET_UShort();
+
+      FT_TRACE3(( " [max:%d flag:%d]",
+                gaspranges[j].maxPPEM,
+                gaspranges[j].gaspFlag ));
+    }
+    FT_TRACE3(( "\n" ));
+
+    FORGET_Frame();
+    FT_TRACE2(( "GASP loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Kern                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the first kerning table with format 0 in the font.  Only     */
+  /*    accepts the first horizontal kerning table.  Developers should use */
+  /*    the `ftxkern' extension to access other kerning tables in the font */
+  /*    file, if they really want to.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Kern( TT_Face    face,
+                          FT_Stream  stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_UInt    n, num_tables, version;
+
+    /* the kern table is optional. exit silently if it's missing */
+    error = face->goto_table( face, TTAG_kern, stream, 0 );
+    if ( error ) return TT_Err_Ok;
+
+    if ( ACCESS_Frame( 4L ) ) goto Exit;
+
+    version    = GET_UShort();
+    num_tables = GET_UShort();
+
+    FORGET_Frame();
+
+    for ( n = 0; n < num_tables; n++ )
+    {
+      TT_UInt  coverage;
+      TT_UInt  length;
+
+      if ( ACCESS_Frame( 6L ) ) goto Exit;
+
+      version  = GET_UShort();      /* version                 */
+      length   = GET_UShort() - 6;  /* substract header length */
+      coverage = GET_UShort();
+
+      FORGET_Frame();
+      
+      if ( coverage == 0x0001 )
+      {
+        TT_UInt          num_pairs;
+        TT_Kern_0_Pair*  pair;
+        TT_Kern_0_Pair*  limit;
+
+        /* found a horizontal format 0 kerning table ! */
+        if ( ACCESS_Frame(8L) )
+          goto Exit;
+
+        num_pairs = GET_UShort();
+        /* skip the rest */
+
+        FORGET_Frame();
+
+        /* allocate array of kerning pairs */
+        if ( ALLOC_ARRAY( face->kern_pairs, num_pairs, TT_Kern_0_Pair ) ||
+             ACCESS_Frame( 6L * num_pairs )                             )
+          goto Exit;
+
+        pair  = face->kern_pairs;
+        limit = pair + num_pairs;
+        for ( ; pair < limit; pair++ )
+        {
+          pair->left  = GET_UShort();
+          pair->right = GET_UShort();
+          pair->value = GET_UShort();
+        }
+
+        FORGET_Frame();
+
+        face->num_kern_pairs   = num_pairs;
+        face->kern_table_index = n;
+        goto Exit;
+      }
+      
+      if ( FILE_Skip( length ) )
+        goto Exit;
+    }
+
+    /* no kern table found -- doesn't matter */
+    face->kern_table_index = -1;
+    face->num_kern_pairs   = 0;
+    face->kern_pairs       = NULL;
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Hdmx                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal device metrics table.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Hdmx( TT_Face    face, 
+                          FT_Stream  stream )
+  {
+    TT_Error  error;
+    FT_Memory memory = stream->memory;
+
+    TT_Hdmx*     hdmx = &face->hdmx;
+    TT_Long      num_glyphs;
+    TT_Long      record_size;
+
+    hdmx->version     = 0;
+    hdmx->num_records = 0;
+    hdmx->records     = 0;
+
+    /* this table is optional */
+    error = face->goto_table( face, TTAG_hdmx, stream, 0 );
+    if (error) return TT_Err_Ok;
+
+    if ( ACCESS_Frame( 8L ) ) goto Exit;
+
+    hdmx->version     = GET_UShort();
+    hdmx->num_records = GET_Short();
+    record_size       = GET_Long();
+
+    FORGET_Frame();
+
+    /* Only recognize format 0 */
+    if ( hdmx->version != 0 )
+      goto Exit;
+
+    if ( ALLOC_ARRAY( hdmx->records, hdmx->num_records, TT_HdmxRec ) )
+      goto Exit;
+
+    num_glyphs   = face->root.num_glyphs;
+    record_size -= num_glyphs + 2;
+
+    {
+      TT_HdmxRec*  cur   = hdmx->records;
+      TT_HdmxRec*  limit = cur + hdmx->num_records;
+
+      for ( ; cur < limit; cur++ )
+      {
+        /* read record */
+        if ( READ_Byte( cur->ppem      ) ||
+             READ_Byte( cur->max_width ) )
+          goto Exit;
+  
+        if ( ALLOC( cur->widths, num_glyphs )  ||
+             FILE_Read( cur->widths, num_glyphs ) )
+          goto Exit;
+  
+        /* skip padding bytes */
+        if ( record_size > 0 && FILE_Skip(record_size) )
+            goto Exit;
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_Hdmx                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Frees the horizontal device metrics table.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target face object.                        */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  TT_Free_Hdmx( TT_Face  face )
+  {
+    if ( face )
+    {
+      TT_Int     n;
+      FT_Memory  memory = face->root.driver->memory;
+
+      for ( n = 0; n < face->hdmx.num_records; n++ )
+        FREE( face->hdmx.records[n].widths );
+
+      FREE( face->hdmx.records );
+      face->hdmx.num_records = 0;
+    }
+  }
+
+
+/* END */
diff --git a/src/sfnt/ttload.h b/src/sfnt/ttload.h
new file mode 100644
index 0000000..c9ea0a7
--- /dev/null
+++ b/src/sfnt/ttload.h
@@ -0,0 +1,382 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttload.h                                                               */
+/*                                                                         */
+/*    Load the basic TrueType tables, i.e., tables that can be either in   */
+/*    TTF or OTF font (specification).                                     */
+/*                                                                         */
+/*  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 TTLOAD_H
+#define TTLOAD_H
+
+
+#include <ftstream.h>
+#include <tttypes.h>
+/*
+#include <ttobjs.h>
+*/
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_LookUp_Table                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Looks for a TrueType table by name.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A face object handle.                                      */
+  /*    tag  :: The  searched tag.                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    pointer to table directory entry. 0 if not found..                 */
+  /*                                                                       */
+  EXPORT_DEF
+  TT_Table*  TT_LookUp_Table( TT_Face   face,
+                              TT_ULong  tag );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Goto_Table                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Looks for a TrueType table by name, then seek a stream to it.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: a face object handle.                                    */
+  /*    tag    :: the  searched tag.                                       */
+  /*    stream :: the stream to seek when the table is found               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    pointer to table directory entry. 0 if not found..                 */
+  /*                                                                       */
+  EXPORT_DEF
+  TT_Error   TT_Goto_Table( TT_Face    face,
+                            TT_ULong   tag,
+                            FT_Stream  stream,
+                            TT_ULong  *length );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Directory                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the table directory into a face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face      :: A handle to the target face object.                   */
+  /*    stream    :: The input stream.                                     */
+  /*    faceIndex :: The index of the TrueType font, if we're opening a    */
+  /*                 collection.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The stream cursor must be at the font file's origin                */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Directory( TT_Face    face,
+                               FT_Stream  stream,
+                               TT_Long    faceIndex );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Any                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads any font table into client memory.  Used by the              */
+  /*    TT_Get_Font_Data() API function.                                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: The face object to look for.                             */
+  /*                                                                       */
+  /*    tag    :: The tag of table to load.  Use the value 0 if you  want  */
+  /*              to access the whole font file, else set this parameter   */
+  /*              to a valid TrueType table tag that you can forge with    */
+  /*              the MAKE_TT_TAG macro.                                   */
+  /*                                                                       */
+  /*    offset :: The starting offset in the table (or the file if         */
+  /*              tag == 0).                                               */
+  /*                                                                       */
+  /*    length :: The address of the decision variable:                    */
+  /*                                                                       */
+  /*                If length == NULL:                                     */
+  /*                  Loads the whole table.  Returns an error if          */
+  /*                  `offset' == 0!                                       */
+  /*                                                                       */
+  /*                If *length == 0:                                       */
+  /*                  Exits immediately; returning the length of the given */
+  /*                  table or of the font file, depending on the value of */
+  /*                  `tag'.                                               */
+  /*                                                                       */
+  /*                If *length != 0:                                       */
+  /*                  Loads the next `length' bytes of table or font,      */
+  /*                  starting at offset `offset' (in table or font too).  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    buffer :: The address of target buffer.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Any( TT_Face   face,
+                         TT_ULong  tag,
+                         TT_Long   offset,
+                         void*     buffer,
+                         TT_Long*  length );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Header                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the TrueType font header.                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Header( TT_Face    face,
+                            FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Metrics_Header                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal or vertical header in a face object.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face     :: A handle to the target face object.                    */
+  /*    stream   :: The input stream.                                      */
+  /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Metrics_Header( TT_Face    face,
+                                    FT_Stream  stream,
+                                    TT_Bool    vertical );
+
+
+  LOCAL_DEF
+  TT_Error  TT_Load_CMap( TT_Face    face,
+                          FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_MaxProfile                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the maximum profile into a face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_MaxProfile( TT_Face    face,
+                                FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the name records.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Names( TT_Face    face,
+                           FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_OS2                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the OS2 table.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_OS2( TT_Face    face,
+                         FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Postscript                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the Postscript table.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_PostScript( TT_Face    face,
+                                FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Hdmx                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal device metrics table.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Hdmx( TT_Face    face,
+                          FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Frees the name records.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target face object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Free_Names( TT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_Hdmx                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Frees the horizontal device metrics table.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target face object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Free_Hdmx ( TT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Kern                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the first kerning table with format 0 in the font.  Only     */
+  /*    accepts the first horizontal kerning table.  Developers should use */
+  /*    the `ftxkern' extension to access other kerning tables in the font */
+  /*    file, if they really want to.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Kern( TT_Face    face,
+                          FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Gasp                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the `GASP' table into a face object.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Gasp( TT_Face    face,
+                          FT_Stream  stream );
+
+
+#endif /* TTLOAD_H */
+
+
+/* END */
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
new file mode 100644
index 0000000..953118f
--- /dev/null
+++ b/src/sfnt/ttpost.c
@@ -0,0 +1,700 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttpost.c                                                               */
+/*                                                                         */
+/*    Postscript names table processing (body).                            */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The post table is not completely loaded by the core engine.  This     */
+  /* file loads the missing PS glyph names and implements an API to access */
+  /* them.                                                                 */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include <ttpost.h>
+#include <ftstream.h>
+#include <tterrors.h>
+#include <ttload.h>
+#include <tttags.h>
+
+  /* the 258 default Mac PS glyph names */
+
+  const TT_String*  TT_Mac_Postscript_Names[258] =
+  {
+    /*   0 */
+    ".notdef",
+    ".null",
+    "CR",
+    "space",
+    "exclam",
+    "quotedbl",
+    "numbersign",
+    "dollar",
+    "percent",
+    "ampersand",
+
+    /*  10 */
+    "quotesingle",
+    "parenleft",
+    "parenright",
+    "asterisk",
+    "plus",
+    "comma",
+    "hyphen",
+    "period",
+    "slash",
+    "zero",
+
+    /*  20 */
+    "one",
+    "two",
+    "three",
+    "four",
+    "five",
+    "six",
+    "seven",
+    "eight",
+    "nine",
+    "colon",
+
+    /*  30 */
+    "semicolon",
+    "less",
+    "equal",
+    "greater", "question",
+    "at",
+    "A",
+    "B",
+    "C",
+    "D",
+
+    /*  40 */
+    "E",
+    "F",
+    "G",
+    "H",
+    "I",
+    "J",
+    "K",
+    "L",
+    "M",
+    "N",
+
+    /*  50 */
+    "O",
+    "P",
+    "Q",
+    "R",
+    "S",
+    "T",
+    "U",
+    "V",
+    "W",
+    "X",
+
+    /*  60 */
+    "Y",
+    "Z",
+    "bracketleft",
+    "backslash",
+    "bracketright",
+    "asciicircum",
+    "underscore",
+    "grave",
+    "a",
+    "b",
+
+    /*  70 */
+    "c",
+    "d",
+    "e",
+    "f",
+    "g",
+    "h",
+    "i",
+    "j",
+    "k",
+    "l",
+
+    /*  80 */
+    "m",
+    "n",
+    "o",
+    "p",
+    "q",
+    "r",
+    "s",
+    "t",
+    "u",
+    "v",
+
+    /*  90 */
+    "w",
+    "x",
+    "y",
+    "z",
+    "braceleft",
+    "bar",
+    "braceright",
+    "asciitilde",
+    "Adieresis",
+    "Aring",
+
+    /* 100 */
+    "Ccedilla",
+    "Eacute",
+    "Ntilde",
+    "Odieresis",
+    "Udieresis",
+    "aacute",
+    "agrave",
+    "acircumflex",
+    "adieresis",
+    "atilde",
+
+    /* 110 */
+    "aring",
+    "ccedilla",
+    "eacute",
+    "egrave",
+    "ecircumflex",
+    "edieresis",
+    "iacute",
+    "igrave",
+    "icircumflex",
+    "idieresis",
+
+    /* 120 */
+    "ntilde",
+    "oacute",
+    "ograve",
+    "ocircumflex",
+    "odieresis",
+    "otilde",
+    "uacute",
+    "ugrave",
+    "ucircumflex",
+    "udieresis",
+
+    /* 130 */
+    "dagger",
+    "degree",
+    "cent",
+    "sterling",
+    "section",
+    "bullet",
+    "paragraph",
+    "germandbls",
+    "registered",
+    "copyright",
+
+    /* 140 */
+    "trademark",
+    "acute",
+    "dieresis",
+    "notequal",
+    "AE",
+    "Oslash",
+    "infinity",
+    "plusminus",
+    "lessequal",
+    "greaterequal",
+
+    /* 150 */
+    "yen",
+    "mu",
+    "partialdiff",
+    "summation",
+    "product",
+    "pi",
+    "integral",
+    "ordfeminine",
+    "ordmasculine",
+    "Omega",
+
+    /* 160 */
+    "ae",
+    "oslash",
+    "questiondown",
+    "exclamdown",
+    "logicalnot",
+    "radical",
+    "florin",
+    "approxequal",
+    "Delta",
+    "guillemotleft",
+
+    /* 170 */
+    "guillemotright",
+    "ellipsis",
+    "nbspace",
+    "Agrave",
+    "Atilde",
+    "Otilde",
+    "OE",
+    "oe",
+    "endash",
+    "emdash",
+
+    /* 180 */
+    "quotedblleft",
+    "quotedblright",
+    "quoteleft",
+    "quoteright",
+    "divide",
+    "lozenge",
+    "ydieresis",
+    "Ydieresis",
+    "fraction",
+    "currency",
+
+    /* 190 */
+    "guilsinglleft",
+    "guilsinglright",
+    "fi",
+    "fl",
+    "daggerdbl",
+    "periodcentered",
+    "quotesinglbase",
+    "quotedblbase",
+    "perthousand",
+    "Acircumflex",
+
+    /* 200 */
+    "Ecircumflex",
+    "Aacute",
+    "Edieresis",
+    "Egrave",
+    "Iacute",
+    "Icircumflex",
+    "Idieresis",
+    "Igrave",
+    "Oacute",
+    "Ocircumflex",
+
+    /* 210 */
+    "apple",
+    "Ograve",
+    "Uacute",
+    "Ucircumflex",
+    "Ugrave",
+    "dotlessi",
+    "circumflex",
+     "tilde",
+     "macron",
+     "breve",
+
+    /* 220 */
+    "dotaccent",
+    "ring",
+    "cedilla",
+    "hungarumlaut",
+    "ogonek",
+    "caron",
+    "Lslash",
+    "lslash",
+    "Scaron",
+    "scaron",
+
+    /* 230 */
+    "Zcaron",
+    "zcaron",
+    "brokenbar",
+    "Eth",
+    "eth",
+    "Yacute",
+    "yacute",
+    "Thorn",
+    "thorn",
+    "minus",
+
+    /* 240 */
+    "multiply",
+    "onesuperior",
+    "twosuperior",
+    "threesuperior",
+    "onehalf",
+    "onequarter",
+    "threequarters",
+    "franc",
+    "Gbreve",
+    "gbreve",
+
+    /* 250 */
+    "Idot",
+    "Scedilla",
+    "scedilla",
+    "Cacute",
+    "cacute",
+    "Ccaron",
+    "ccaron",
+    "dmacron",
+  };
+
+
+  static
+  TT_Error  Load_Format_20( TT_Face    face,
+                            FT_Stream  stream )
+  {
+    FT_Memory  memory = stream->memory;
+    TT_Error   error;
+
+    TT_Int     num_glyphs;
+    TT_Int     num_names;
+
+    TT_UShort* glyph_indices = 0;
+    TT_Char**  name_strings  = 0;
+
+
+    if ( READ_UShort( num_glyphs ) )
+      goto Exit;
+
+    /* UNDOCUMENTED!  The number of glyphs in this table can be smaller */
+    /* than the value in the maxp table (cf. cyberbit.ttf).             */
+
+    /* There already exist fonts which have more than 32768 glyph names */
+    /* in this table, so the test for this threshold has been dropped.  */
+
+    if ( num_glyphs > face->root.num_glyphs )
+    {
+      error = TT_Err_Invalid_File_Format;
+      goto Exit;
+    }
+
+    /* load the indices */
+    {
+      TT_Int  n;
+
+      if ( ALLOC_ARRAY ( glyph_indices, num_glyphs, TT_UShort ) ||
+           ACCESS_Frame( num_glyphs * 2L )                      )
+        goto Fail;
+
+      for ( n = 0; n < num_glyphs; n++ )
+        glyph_indices[n] = GET_UShort();
+
+      FORGET_Frame();
+    }
+
+    /* compute number of names stored in table */
+    {
+      TT_Int  n;
+
+      num_names = 0;
+
+      for ( n = 0; n < num_glyphs; n++ )
+      {
+        TT_Int  index;
+
+        index = glyph_indices[n];
+        if ( index >= 258 )
+        {
+          index -= 257;
+          if ( index > num_names )
+            num_names = index;
+        }
+      }
+    }
+
+    /* now load the name strings */
+    {
+      TT_Int  n;
+
+      if ( ALLOC_ARRAY( name_strings, num_names, TT_Char* ) )
+        goto Fail;
+
+      for ( n = 0; n < num_names; n++ )
+      {
+        TT_UInt  len;
+
+        if ( READ_Byte  ( len )                             ||
+             ALLOC_ARRAY( name_strings[n], len+1, TT_Char ) ||
+             FILE_Read  ( name_strings[n], len )            )
+          goto Fail1;
+
+        name_strings[n][len] = '\0';
+      }
+    }
+
+    /* all right, set table fields and exit successfuly */
+    {
+      TT_Post_20*  table = &face->postscript_names.names.format_20;
+
+      table->num_glyphs    = num_glyphs;
+      table->num_names     = num_names;
+      table->glyph_indices = glyph_indices;
+      table->glyph_names   = name_strings;
+    }
+    return TT_Err_Ok;
+
+
+  Fail1:
+    {
+      TT_Int  n;
+
+      for ( n = 0; n < num_names; n++ )
+        FREE( name_strings[n] );
+    }
+
+  Fail:
+    FREE( name_strings );
+    FREE( glyph_indices );
+
+  Exit:
+    return error;
+  }
+
+
+  static
+  TT_Error  Load_Format_25( TT_Face    face,
+                            FT_Stream  stream )
+  {
+    FT_Memory  memory = stream->memory;
+    TT_Error   error;
+
+    TT_Int     num_glyphs;
+    TT_Char*   offset_table = 0;
+
+
+    /* UNDOCUMENTED!  This value appears only in the Apple TT specs. */
+    if ( READ_UShort( num_glyphs ) )
+      goto Exit;
+
+    /* check the number of glyphs */
+    if ( num_glyphs > face->root.num_glyphs || num_glyphs > 258 )
+    {
+      error = TT_Err_Invalid_File_Format;
+      goto Exit;
+    }
+
+    if ( ALLOC    ( offset_table, num_glyphs ) ||
+         FILE_Read( offset_table, num_glyphs ) )
+      goto Fail;
+
+    /* now check the offset table */
+    {
+      TT_Int  n;
+
+
+      for ( n = 0; n < num_glyphs; n++ )
+      {
+        TT_Long  index = (TT_Long)n + offset_table[n];
+
+
+        if ( index < 0 || index > num_glyphs )
+        {
+          error = TT_Err_Invalid_File_Format;
+          goto Fail;
+        }
+      }
+    }
+
+    /* OK, set table fields and exit successfuly */
+    {
+      TT_Post_25*  table = &face->postscript_names.names.format_25;
+
+
+      table->num_glyphs = num_glyphs;
+      table->offsets    = offset_table;
+    }
+
+    return TT_Err_Ok;
+
+  Fail:
+    FREE( offset_table );
+
+  Exit:
+    return error;
+  }
+
+
+  static
+  TT_Error  Load_Post_Names( TT_Face  face )
+  {
+    FT_Stream   stream;
+    TT_Error    error;
+
+    /* get a stream for the face's resource */
+    stream = face->root.stream;
+
+    /* seek to the beginning of the PS names table */
+    error = face->goto_table( face, TTAG_post, stream, 0 );
+    if (error) goto Exit;
+
+    /* now read postscript table */
+    switch ( face->postscript.FormatType )
+    {
+    case 0x00020000:
+      error = Load_Format_20( face, stream );
+      break;
+
+    case 0x00028000:
+      error = Load_Format_25( face, stream );
+      break;
+
+    default:
+      error = TT_Err_Invalid_File_Format;
+    }
+
+    face->postscript_names.loaded = 1;
+
+  Exit:
+    return error;
+  }
+
+
+  LOCAL_FUNC
+  void  TT_Free_Post_Names( TT_Face  face )
+  {
+    FT_Memory       memory = face->root.memory;
+    TT_Post_Names*  names  = &face->postscript_names;
+
+
+    if ( names->loaded )
+    {
+      switch ( face->postscript.FormatType )
+      {
+      case 0x00020000:
+        {
+          TT_Post_20*  table = &names->names.format_20;
+          TT_UInt      n;
+
+
+          FREE( table->glyph_indices );
+          table->num_glyphs = 0;
+
+          for ( n = 0; n < table->num_names; n++ )
+            FREE( table->glyph_names[n] );
+
+          FREE( table->glyph_names );
+          table->num_names = 0;
+        }
+        break;
+
+      case 0x00028000:
+        {
+          TT_Post_25*  table = &names->names.format_25;
+
+
+          FREE( table->offsets );
+          table->num_glyphs = 0;
+        }
+        break;
+      }
+    }
+    names->loaded = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Get_PS_Name                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Gets the PostScript glyph name of a glyph.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    index  :: The glyph index.                                         */
+  /*                                                                       */
+  /*    PSname :: The address of a string pointer.  Will be NULL in case   */
+  /*              of error, otherwise it is a pointer to the glyph name.   */
+  /*                                                                       */
+  /*              You must not modify the returned string!                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error  TT_Get_PS_Name( TT_Face      face,
+                            TT_UInt      index,
+                            TT_String**  PSname )
+  {
+    TT_Error        error;
+    TT_Post_Names*  names;
+
+    if ( !face )
+      return TT_Err_Invalid_Face_Handle;
+
+    if ( index >= (TT_UInt)face->root.num_glyphs )
+      return TT_Err_Invalid_Glyph_Index;
+
+    names   = &face->postscript_names;
+
+    /* `.notdef' by default */
+    *PSname = (TT_String*)TT_Mac_Postscript_Names[0];
+
+    switch ( face->postscript.FormatType )
+    {
+    case 0x00010000:
+      if ( index < 258 )                    /* paranoid checking */
+        *PSname = (TT_String*)TT_Mac_Postscript_Names[index];
+      break;
+
+    case 0x00020000:
+      {
+        TT_Post_20*  table = &names->names.format_20;
+
+
+        if ( !names->loaded )
+        {
+          error = Load_Post_Names( face );
+          if ( error )
+            break;
+        }
+
+        if ( index < table->num_glyphs )
+        {
+          TT_UShort  name_index = table->glyph_indices[index];
+
+
+          if ( name_index < 258 )
+            *PSname = (TT_String*)TT_Mac_Postscript_Names[name_index];
+          else
+            *PSname = (TT_String*)table->glyph_names[name_index - 258];
+        }
+      }
+      break;
+
+    case 0x00028000:
+      {
+        TT_Post_25*  table = &names->names.format_25;
+
+
+        if ( !names->loaded )
+        {
+          error = Load_Post_Names( face );
+          if ( error )
+            break;
+        }
+
+        if ( index < table->num_glyphs )    /* paranoid checking */
+        {
+          index  += table->offsets[index];
+          *PSname = (TT_String*)TT_Mac_Postscript_Names[index];
+        }
+      }
+      break;
+
+    case 0x00030000:
+      break;                                /* nothing to do */
+    }
+
+    return TT_Err_Ok;
+  }
+
+
+/* END */
diff --git a/src/sfnt/ttpost.h b/src/sfnt/ttpost.h
new file mode 100644
index 0000000..eeb0bf1
--- /dev/null
+++ b/src/sfnt/ttpost.h
@@ -0,0 +1,87 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttpost.h                                                               */
+/*                                                                         */
+/*    Postcript name table processing for TrueType and OpenType fonts      */
+/*    (specification).                                                     */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The post table is not completely loaded by the core engine.  This     */
+  /* file loads the missing PS glyph names and implements an API to access */
+  /* them.                                                                 */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef TTPOST_H
+#define TTPOST_H
+
+#include <ftconfig.h>
+#include <tttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define TT_Err_Invalid_Post_Table_Format  0x0B00
+#define TT_Err_Invalid_Post_Table         0x0B01
+
+#if 0
+  /* the 258 standard Mac glyph names, used for format 1.0 and 2.5 */
+  LOCAL_DEF
+  const TT_String*  TT_Mac_Postscript_Names[];
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Get_PS_Name                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Gets the PostScript glyph name of a glyph.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    index  :: The glyph index.                                         */
+  /*                                                                       */
+  /*    PSname :: The address of a string pointer.  Will be NULL in case   */
+  /*              of error, otherwise it is a pointer to the glyph name.   */
+  /*                                                                       */
+  /*              You must not modify the returned string!                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_DEF
+  TT_Error TT_Get_PS_Name( TT_Face      face,
+                           TT_UInt      index,
+                           TT_String**  PSname );
+
+
+  LOCAL_DEF
+  void  TT_Free_Post_Names( TT_Face  face );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* TTPOST_H */
+
+
+/* END */
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
new file mode 100644
index 0000000..b7020bb
--- /dev/null
+++ b/src/sfnt/ttsbit.c
@@ -0,0 +1,1437 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttsbit.c                                                               */
+/*                                                                         */
+/*    TrueType and OpenType embedded bitmap support (body).                */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/*                                                                         */
+/*  WARNING: This file should not be compiled directly, it is meant to be  */
+/*           included in the source of several font drivers (i.e., the TTF */
+/*           and OTF drivers).                                             */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ftdebug.h>
+
+#include <ttsbit.h>
+#include <tttags.h>
+#include <tterrors.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    blit_sbit                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Blits a bitmap from an input stream into a given target.  Supports */
+  /*    x and y offsets as well as byte padded lines.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    target      :: The target bitmap/pixmap.                           */
+  /*                                                                       */
+  /*    source      :: The input packed bitmap data.                       */
+  /*                                                                       */
+  /*    line_bits   :: The number of bits per line.                        */
+  /*                                                                       */
+  /*    byte_padded :: A flag which is true if lines are byte-padded.      */
+  /*                                                                       */
+  /*    x_offset    :: The horizontal offset.                              */
+  /*                                                                       */
+  /*    y_offset    :: The vertical offset.                                */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    IMPORTANT: The x and y offsets are relative to the top corner of   */
+  /*               the target bitmap (unlike the normal TrueType           */
+  /*               convention).  A positive y offset indicates a downwards */
+  /*               direction!                                              */
+  /*                                                                       */
+  static
+  void  blit_sbit( FT_Bitmap*  target,
+                   char*       source,
+                   FT_Int      line_bits,
+                   FT_Bool     byte_padded,
+                   FT_Int      x_offset,
+                   FT_Int      y_offset )
+  {
+    FT_Byte*   line_buff;
+    FT_Int     line_incr;
+    FT_Int     height;
+
+    FT_UShort  acc;
+    FT_Byte    loaded;
+
+
+    /* first of all, compute starting write position */
+    line_incr = target->pitch;
+    line_buff = target->buffer;
+    
+    if (line_incr < 0)
+      line_buff -= line_incr*(target->rows-1);
+
+    line_buff += (x_offset >> 3) + y_offset * line_incr;
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* We use the extra-classic `accumulator' trick to extract the bits    */
+    /* from the source byte stream.                                        */
+    /*                                                                     */
+    /* Namely, the variable `acc' is a 16-bit accumulator containing the   */
+    /* last `loaded' bits from the input stream.  The bits are shifted to  */
+    /* the upmost position in `acc'.                                       */
+    /*                                                                     */
+    /***********************************************************************/
+
+    acc    = 0;  /* clear accumulator   */
+    loaded = 0;  /* no bits were loaded */
+
+    for ( height = target->rows; height > 0; height-- )
+    {
+      FT_Byte*  cur   = line_buff;    /* current write cursor          */
+      FT_Int    count = line_bits;    /* # of bits to extract per line */
+      FT_Byte   shift = x_offset & 7; /* current write shift           */
+      FT_Byte   space = 8 - shift;
+
+
+      /* first of all, read individual source bytes */
+      if ( count >= 8 )
+      {
+        count -= 8;
+        {
+          do
+          {
+            FT_Byte  val;
+
+            /* ensure that there are at least 8 bits in the accumulator */
+            if ( loaded < 8 )
+            {
+              acc    |= ((FT_UShort)*source++) << (8 - loaded);
+              loaded += 8;
+            }
+
+            /* now write one byte */
+            val     = (FT_Byte)(acc >> 8);
+            if (shift)
+            {
+              cur[0] |= val >> shift;
+              cur[1] |= val << space;
+            }
+            else
+              cur[0] = val;
+
+            cur++;
+            acc   <<= 8;  /* remove bits from accumulator */
+            loaded -= 8;
+            count  -= 8;
+          }
+          while ( count >= 0 );
+        }
+
+        /* restore `count' to correct value */
+        count += 8;
+      }
+
+      /* now write remaining bits (count < 8) */
+      if ( count > 0 )
+      {
+        FT_Byte  val;
+
+
+        /* ensure that there are at least `count' bits in the accumulator */
+        if ( loaded < count )
+        {
+          acc    |= ((FT_UShort)*source++) << (8 - loaded);
+          loaded += 8;
+        }
+
+        /* now write remaining bits */
+        val     = ((FT_Byte)(acc >> 8)) & ~(0xFF >> count);
+        cur[0] |= val >> shift;
+
+        if ( count > space )
+          cur[1] |= val << space;
+
+        acc   <<= count;
+        loaded -= count;
+      }
+
+      /* now, skip to next line */
+      if ( byte_padded )
+        acc = loaded = 0;   /* clear accumulator on byte-padded lines */
+
+      line_buff += line_incr;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Small_SBit_Metrics                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a small bitmap metrics record.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream  :: The input stream.                                       */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    metrics :: A small metrics structure.                              */
+  /*                                                                       */
+  static
+  void  TT_Load_Small_SBit_Metrics( TT_SBit_Small_Metrics*  metrics,
+                                    FT_Stream               stream )
+  {
+    metrics->height   = GET_Byte();
+    metrics->width    = GET_Byte();
+    metrics->bearingX = GET_Char();
+    metrics->bearingY = GET_Char();
+    metrics->advance  = GET_Byte();
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Metrics                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a bitmap metrics record.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream  :: The input stream.                                       */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    metrics :: A metrics structure.                                    */
+  /*                                                                       */
+  static
+  void  TT_Load_SBit_Metrics( TT_SBit_Metrics*  metrics,
+                              FT_Stream         stream )
+  {
+    metrics->height       = GET_Byte();
+    metrics->width        = GET_Byte();
+
+    metrics->horiBearingX = GET_Char();
+    metrics->horiBearingY = GET_Char();
+    metrics->horiAdvance  = GET_Byte();
+
+    metrics->vertBearingX = GET_Char();
+    metrics->vertBearingY = GET_Char();
+    metrics->vertAdvance  = GET_Byte();
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Line_Metrics                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a bitmap line metrics record.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream  :: The input stream.                                       */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    metrics :: A line metrics structure.                               */
+  /*                                                                       */
+  static
+  void  TT_Load_SBit_Line_Metrics( TT_SBit_Line_Metrics*  metrics,
+                                   FT_Stream              stream )
+  {
+    metrics->ascender  = GET_Char();
+    metrics->descender = GET_Char();
+    metrics->max_width = GET_Byte();
+
+    metrics->caret_slope_numerator   = GET_Char();
+    metrics->caret_slope_denominator = GET_Char();
+    metrics->caret_offset            = GET_Char();
+
+    metrics->min_origin_SB  = GET_Char();
+    metrics->min_advance_SB = GET_Char();
+    metrics->max_before_BL  = GET_Char();
+    metrics->min_after_BL   = GET_Char();
+    metrics->pads[0]        = GET_Char();
+    metrics->pads[1]        = GET_Char();
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Const_Metrics                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the metrics for `EBLC' index tables format 2 and 5.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range  :: The target range.                                        */
+  /*                                                                       */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Load_SBit_Const_Metrics( TT_SBit_Range*  range,
+                                     FT_Stream       stream )
+  {
+    TT_Error  error;
+
+    if ( !ACCESS_Frame( 12L ) )
+    {
+      range->image_size = GET_ULong();
+      TT_Load_SBit_Metrics( &range->metrics, stream );
+
+      FORGET_Frame();
+    }
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Range_Codes                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the range codes for `EBLC' index tables format 4 and 5.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range        :: The target range.                                  */
+  /*                                                                       */
+  /*    stream       :: The input stream.                                  */
+  /*                                                                       */
+  /*    load_offsets :: A flag whether to load the glyph offset table.     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Load_SBit_Range_Codes( TT_SBit_Range*  range,
+                                   FT_Stream       stream,
+                                   TT_Bool         load_offsets )
+  {
+    TT_Error   error;
+    TT_ULong   count, n, size;
+    FT_Memory  memory = stream->memory;
+
+
+    if ( READ_ULong( count ) )
+      goto Exit;
+
+    range->num_glyphs = count;
+
+    /* Allocate glyph offsets table if needed */
+    if ( load_offsets )
+    {
+      if ( ALLOC_ARRAY( range->glyph_offsets, count, TT_ULong ) )
+        goto Exit;
+
+      size = count * 4L;
+    }
+    else
+      size = count * 2L;
+
+    /* Allocate glyph codes table and access frame */
+    if ( ALLOC_ARRAY ( range->glyph_codes, count, TT_UShort ) ||
+         ACCESS_Frame( size )                                 )
+      goto Exit;
+
+    for ( n = 0; n < count; n++ )
+    {
+      range->glyph_codes[n] = GET_UShort();
+
+      if (load_offsets)
+        range->glyph_offsets[n] = (TT_ULong)range->image_offset + 
+                                  GET_UShort();
+    }
+
+    FORGET_Frame();
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Range                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given `EBLC' index/range table.                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range  :: The target range.                                        */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Load_SBit_Range( TT_SBit_Range*  range,
+                             FT_Stream       stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+
+    switch( range->index_format )
+    {
+    case 1:   /* variable metrics with 4-byte offsets */
+    case 3:   /* variable metrics with 2-byte offsets */
+      {
+        TT_ULong  num_glyphs, n;
+        TT_Int    size_elem;
+        TT_Bool   large = (range->index_format == 1);
+
+
+        num_glyphs        = range->last_glyph - range->first_glyph + 1L;
+        range->num_glyphs = num_glyphs;
+        num_glyphs++;    /* XXX : BEWARE - see spec */
+
+        size_elem  = ( large ? 4 : 2 );
+
+        if ( ALLOC_ARRAY( range->glyph_offsets,
+                          num_glyphs, TT_ULong )    ||
+
+             ACCESS_Frame( num_glyphs * size_elem ) )
+          goto Exit;
+
+        for ( n = 0; n < num_glyphs; n++ )
+          range->glyph_offsets[n] = (TT_ULong)( range->image_offset +
+                                     (large ? GET_ULong() : GET_UShort()) );
+        FORGET_Frame();
+      }
+      break;
+
+    case 2:   /* all glyphs have identical metrics */
+      error = Load_SBit_Const_Metrics( range, stream );
+      break;
+
+    case 4:
+      error = Load_SBit_Range_Codes( range, stream, 1 );
+      break;
+
+    case 5:
+      error = Load_SBit_Const_Metrics( range, stream ) ||
+              Load_SBit_Range_Codes( range, stream, 0 );
+      break;
+
+    default:
+      error = TT_Err_Invalid_File_Format;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Strikes                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the table of embedded bitmap sizes for this face.            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: The target face object.                                  */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_SBit_Strikes( TT_Face    face,
+                                  FT_Stream  stream )
+  {
+    TT_Error   error  = 0;
+    FT_Memory  memory = stream->memory;
+    TT_Fixed   version;
+    TT_ULong   num_strikes;
+    TT_ULong   table_base;
+
+
+    /* this table is optional */
+    error = face->goto_table( face, TTAG_EBLC, stream, 0 );
+    {
+      error = 0;
+      goto Exit;
+    }
+
+    table_base = FILE_Pos();
+    if ( ACCESS_Frame( 8L ) )
+      goto Exit;
+
+    version     = GET_Long();
+    num_strikes = GET_ULong();
+
+    FORGET_Frame();
+
+    /* check version number and strike count */
+    if ( version     != 0x00020000 ||
+         num_strikes >= 0x10000    )
+    {
+      FT_ERROR(( "TT_Load_SBit_Strikes: invalid table version!\n" ));
+      error = TT_Err_Invalid_File_Format;
+
+      goto Exit;
+    }
+
+    /* allocate the strikes table */
+    if ( ALLOC_ARRAY( face->sbit_strikes, num_strikes, TT_SBit_Strike ) )
+      goto Exit;
+
+    face->num_sbit_strikes = num_strikes;
+
+    /* now read each strike table separately */
+    {
+      TT_SBit_Strike*  strike = face->sbit_strikes;
+      TT_ULong         count  = num_strikes;
+
+      if ( ACCESS_Frame( 48L * num_strikes ) )
+        goto Exit;
+
+      while ( count > 0 )
+      {
+        TT_ULong  indexTablesSize;
+
+
+        strike->ranges_offset    = GET_ULong();
+        indexTablesSize          = GET_ULong();  /* don't save */
+
+        strike->num_ranges       = GET_ULong();
+        strike->color_ref        = GET_ULong();
+
+        TT_Load_SBit_Line_Metrics( &strike->hori, stream );
+        TT_Load_SBit_Line_Metrics( &strike->vert, stream );
+
+        strike->start_glyph      = GET_UShort();
+        strike->end_glyph        = GET_UShort();
+        strike->x_ppem           = GET_Byte();
+        strike->y_ppem           = GET_Byte();
+        strike->bit_depth        = GET_Byte();
+        strike->flags            = GET_Char();
+
+        count--;
+        strike++;
+      }
+
+      FORGET_Frame();
+    }
+
+    /* allocate the index ranges for each strike table */
+    {
+      TT_SBit_Strike*  strike = face->sbit_strikes;
+      TT_ULong         count  = num_strikes;
+
+
+      while ( count > 0 )
+      {
+        TT_SBit_Range* range;
+        TT_ULong       count2 = strike->num_ranges;
+
+
+        if ( ALLOC_ARRAY( strike->sbit_ranges,
+                          strike->num_ranges,
+                          TT_SBit_Range ) )
+          goto Exit;
+
+        /* read each range */
+        if ( FILE_Seek( table_base + strike->ranges_offset ) ||
+             ACCESS_Frame( strike->num_ranges * 8L )         )
+          goto Exit;
+
+        range = strike->sbit_ranges;
+        while ( count2 > 0 )
+        {
+          range->first_glyph  = GET_UShort();
+          range->last_glyph   = GET_UShort();
+          range->table_offset = table_base + strike->ranges_offset
+                                 + GET_ULong();
+          count2--;
+          range++;
+        }
+
+        FORGET_Frame();
+
+        /* Now, read each index table */
+        count2 = strike->num_ranges;
+        range  = strike->sbit_ranges;
+        while ( count2 > 0 )
+        {
+          /* Read the header */
+          if ( FILE_Seek( range->table_offset ) ||
+               ACCESS_Frame( 8L )               )
+            goto Exit;
+
+          range->index_format = GET_UShort();
+          range->image_format = GET_UShort();
+          range->image_offset = GET_ULong();
+
+          FORGET_Frame();
+
+          error = Load_SBit_Range( range, stream );
+          if ( error )
+            goto Exit;
+
+          count2--;
+          range++;
+        }
+
+        count--;
+        strike++;
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_SBit_Strikes                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases the embedded bitmap tables.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: The target face object.                                    */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  TT_Free_SBit_Strikes( TT_Face  face )
+  {
+    FT_Memory        memory       = face->root.memory;
+    TT_SBit_Strike*  strike       = face->sbit_strikes;
+    TT_SBit_Strike*  strike_limit = strike + face->num_sbit_strikes;
+
+
+    if ( strike )
+    {
+      for ( ; strike < strike_limit; strike++ )
+      {
+        TT_SBit_Range*  range       = strike->sbit_ranges;
+        TT_SBit_Range*  range_limit = range + strike->num_ranges;
+
+        if ( range )
+        {
+          for ( ; range < range_limit; range++ )
+          {
+            /* release the glyph offsets and codes tables */
+            /* where appropriate                          */
+            FREE( range->glyph_offsets );
+            FREE( range->glyph_codes );
+          }
+        }
+        FREE( strike->sbit_ranges );
+        strike->num_ranges = 0;
+      }
+      FREE( face->sbit_strikes );
+    }
+    face->num_sbit_strikes = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Find_SBit_Range                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Scans a given strike's ranges and return, for a given glyph        */
+  /*    index, the corresponding sbit range, and `EBDT' offset.            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    glyph_index   :: The glyph index.                                  */
+  /*    strike        :: The source/current sbit strike.                   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    arange        :: The sbit range containing the glyph index.        */
+  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means the glyph index was found.           */
+  /*                                                                       */
+  static
+  TT_Error  Find_SBit_Range( TT_UInt          glyph_index,
+                             TT_SBit_Strike*  strike,
+                             TT_SBit_Range**  arange,
+                             TT_ULong*        aglyph_offset )
+  {
+    TT_SBit_Range  *range, *range_limit;
+
+
+    /* check whether the glyph index is within this strike's */
+    /* glyph range                                           */
+    if ( glyph_index < strike->start_glyph ||
+         glyph_index > strike->end_glyph   )
+      goto Fail;
+
+    /* scan all ranges in strike */
+    range       = strike->sbit_ranges;
+    range_limit = range + strike->num_ranges;
+    if ( !range )
+      goto Fail;
+
+    for ( ; range < range_limit; range++ )
+    {
+      if ( glyph_index >= range->first_glyph &&
+           glyph_index <= range->last_glyph  )
+      {
+        TT_UShort  delta = glyph_index - range->first_glyph;
+
+
+        switch ( range->index_format )
+        {
+        case 1:
+        case 3:
+          *aglyph_offset = range->glyph_offsets[delta];
+          break;
+
+        case 2:
+          *aglyph_offset = range->image_offset +
+                           range->image_size * delta;
+          break;
+
+        case 4:
+        case 5:
+          {
+            TT_ULong  n;
+
+
+            for ( n = 0; n < range->num_glyphs; n++ )
+            {
+              if ( range->glyph_codes[n] == glyph_index )
+              {
+                if ( range->index_format == 4 )
+                  *aglyph_offset = range->glyph_offsets[n];
+                else
+                  *aglyph_offset = range->image_offset +
+                                   n * range->image_size;
+                break;
+              }
+            }
+          }
+
+          /* fall-through */
+          default:
+            goto Fail;
+        }
+
+        /* return successfully! */
+        *arange  = range;
+
+        return 0;
+      }
+    }
+
+  Fail:
+    *arange        = 0;
+    *aglyph_offset = 0;
+
+    return TT_Err_Invalid_Argument;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Find_SBit_Image                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Checks whether an embedded bitmap (an `sbit') exists for a given   */
+  /*    glyph, at given x and y ppems.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face          :: The target face object.                           */
+  /*    glyph_index   :: The glyph index.                                  */
+  /*    x_ppem        :: The horizontal resolution in points per EM.       */
+  /*    y_ppem        :: The vertical resolution in points per EM.         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    arange        :: The SBit range containing the glyph index.        */
+  /*    astrike       :: The SBit strike containing the glyph index.       */
+  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.  Returns                    */
+  /*    TT_Err_Invalid_Argument if no sbit exist for the requested glyph.  */
+  /*                                                                       */
+  static
+  TT_Error  Find_SBit_Image( TT_Face           face,
+                             TT_UInt           glyph_index,
+                             TT_Int            x_ppem,
+                             TT_Int            y_ppem,
+
+                             TT_SBit_Range**   arange,
+                             TT_SBit_Strike**  astrike,
+                             TT_ULong*         aglyph_offset )
+  {
+    TT_SBit_Strike*  strike = face->sbit_strikes;
+    TT_SBit_Strike*  strike_limit = strike + face->num_sbit_strikes;
+
+
+    if ( !strike)
+      goto Fail;
+
+    for ( ; strike < strike_limit; strike++ )
+    {
+      if ( strike->x_ppem == x_ppem && strike->y_ppem == y_ppem )
+      {
+        TT_Error  error;
+
+
+        error = Find_SBit_Range( glyph_index, strike, arange, aglyph_offset );
+        if ( error )
+          goto Fail;
+
+        *astrike = strike;
+
+        return TT_Err_Ok;
+      }
+    }
+
+  Fail:
+    /* no embedded bitmap for this glyph in face */
+    *arange        = 0;
+    *astrike       = 0;
+    *aglyph_offset = 0;
+
+    return TT_Err_Invalid_Argument;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Load_SBit_Metrics                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Gets the big metrics for a given SBit.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream      :: The input stream.                                   */
+  /*    range       :: The SBit range containing the glyph.                */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    big_metrics :: A big SBit metrics structure for the glyph.         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The stream cursor must be positioned at the glyph's offset within  */
+  /*    the `EBDT' table before the call.                                  */
+  /*                                                                       */
+  /*    If the image format uses variable metrics, the stream cursor is    */
+  /*    positioned just after the metrics header in the `EBDT' table on    */
+  /*    function exit.                                                     */
+  /*                                                                       */
+  static
+  TT_Error  Load_SBit_Metrics( FT_Stream         stream,
+                               TT_SBit_Range*    range,
+                               TT_SBit_Metrics*  metrics )
+  {
+    TT_Error  error = TT_Err_Ok;
+
+
+    switch ( range->index_format )
+    {
+    case 1:  /* variable metrics */
+    case 3:
+    case 4:
+      {
+        switch ( range->image_format )
+        {
+        case 1:  /* small metrics */
+        case 2:
+        case 8:
+          {
+            TT_SBit_Small_Metrics  smetrics;
+
+
+            /* read small metrics */
+            if ( ACCESS_Frame( 5L ) )
+              goto Exit;
+            TT_Load_Small_SBit_Metrics( &smetrics, stream );
+            FORGET_Frame();
+
+            /* convert it to a big metrics */
+            metrics->height       = smetrics.height;
+            metrics->width        = smetrics.width;
+            metrics->horiBearingX = smetrics.bearingX;
+            metrics->horiBearingY = smetrics.bearingY;
+            metrics->horiAdvance  = smetrics.advance;
+
+            /* these metrics are made up at a higher level when */
+            /* needed.                                          */
+            metrics->vertBearingX = 0;
+            metrics->vertBearingY = 0;
+            metrics->vertAdvance  = 0;
+          }
+          break;
+
+        default:  /* big metrics */
+          if ( ACCESS_Frame( 8L ) )
+            goto Exit;
+          TT_Load_SBit_Metrics( metrics, stream );
+          FORGET_Frame();
+        }
+      }
+      break;
+
+    default:  /* constant metrics */
+      *metrics = range->metrics;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Crop_Bitmap                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Crops a bitmap to its tightest bounding box, and adjusts its       */
+  /*    metrics.                                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    image   :: The input glyph slot.                                   */
+  /*                                                                       */
+  /*    metrics :: The corresponding metrics structure.                    */
+  /*                                                                       */
+  static
+  void  Crop_Bitmap( FT_Bitmap*        map,
+                     TT_SBit_Metrics*  metrics )
+  {
+    /***********************************************************************/
+    /*                                                                     */
+    /* In this situation, some bounding boxes of embedded bitmaps are too  */
+    /* large.  We need to crop it to a reasonable size.                    */
+    /*                                                                     */
+    /*      ---------                                                      */
+    /*      |       |                -----                                 */
+    /*      |  ***  |                |***|                                 */
+    /*      |   *   |                | * |                                 */
+    /*      |   *   |    ------>     | * |                                 */
+    /*      |   *   |                | * |                                 */
+    /*      |   *   |                | * |                                 */
+    /*      |  ***  |                |***|                                 */
+    /*      ---------                -----                                 */
+    /*                                                                     */
+    /***********************************************************************/
+
+    TT_Int    rows, count;
+    TT_Long   line_len;
+    TT_Byte*  line;
+
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* first of all, checks the top-most lines of the bitmap, and removes  */
+    /* them if they're empty.                                              */
+    /*                                                                     */
+    {
+      line     = (TT_Byte*)map->buffer;
+      rows     = map->rows;
+      line_len = map->pitch;
+
+
+      for ( count = 0; count < rows; count++ )
+      {
+        TT_Byte*  cur   = line;
+        TT_Byte*  limit = line + line_len;
+
+
+        for ( ; cur < limit; cur++ )
+          if ( cur[0] )
+            goto Found_Top;
+
+        /* the current line was empty - skip to next one */
+        line  = limit;
+      }
+
+    Found_Top:
+      /* check that we have at least one filled line */
+      if ( count >= rows )
+        goto Empty_Bitmap;
+
+      /* now, crop the empty upper lines */
+      if ( count > 0 )
+      {
+        line = (TT_Byte*)map->buffer;
+
+        MEM_Move( line, line + count * line_len, (rows - count) * line_len );
+
+        metrics->height       -= count;
+        metrics->horiBearingY -= count;
+        metrics->vertBearingY -= count;
+
+        map->rows -= count;
+        rows      -= count;
+      }
+    }
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* second, crop the lower lines                                        */
+    /*                                                                     */
+    {
+      line = (TT_Byte*)map->buffer + (rows - 1) * line_len;
+
+      for ( count = 0; count < rows; count++ )
+      {
+        TT_Byte*  cur   = line;
+        TT_Byte*  limit = line + line_len;
+
+
+        for ( ; cur < limit; cur++ )
+          if ( cur[0] )
+            goto Found_Bottom;
+
+        /* the current line was empty - skip to previous one */
+        line -= line_len;
+      }
+
+    Found_Bottom:
+      if ( count > 0 )
+      {
+        metrics->height -= count;
+        rows            -= count;
+        map->rows       -= count;
+      }
+    }
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* third, get rid of the space on the left side of the glyph           */
+    /*                                                                     */
+    do
+    {
+      TT_Byte*  limit;
+
+
+      line  = (TT_Byte*)map->buffer;
+      limit = line + rows * line_len;
+
+      for ( ; line < limit; line += line_len )
+        if ( line[0] & 0x80 )
+          goto Found_Left;
+
+      /* shift the whole glyph one pixel to the left */
+      line  = (TT_Byte*)map->buffer;
+      limit = line + rows * line_len;
+
+      for ( ; line < limit; line += line_len )
+      {
+        TT_Int    n, width = map->width;
+        TT_Byte   old;
+        TT_Byte*  cur = line;
+
+
+        old = cur[0] << 1;
+        for ( n = 8; n < width; n += 8 )
+        {
+          TT_Byte  val;
+
+
+          val    = cur[1];
+          cur[0] = old | (val >> 7);
+          old    = val << 1;
+          cur++;
+        }
+        cur[0] = old;
+      }
+
+      map->width--;
+      metrics->horiBearingX++;
+      metrics->vertBearingX++;
+      metrics->width--;
+    } while ( map->width > 0 );
+
+  Found_Left:
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* finally, crop the bitmap width to get rid of the space on the right */
+    /* side of the glyph.                                                  */
+    /*                                                                     */
+    do
+    {
+      TT_Int    right = map->width-1;
+      TT_Byte*  limit;
+      TT_Byte   mask;
+
+
+      line  = (TT_Byte*)map->buffer + (right >> 3);
+      limit = line + rows*line_len;
+      mask  = 0x80 >> (right & 7);
+
+      for ( ; line < limit; line += line_len )
+        if ( line[0] & mask )
+          goto Found_Right;
+
+      /* crop the whole glyph to the right */
+      map->width--;
+      metrics->width--;
+    } while ( map->width > 0 );
+
+  Found_Right:
+    /* all right, the bitmap was cropped */
+    return;
+
+  Empty_Bitmap:
+    map->width      = 0;
+    map->rows       = 0;
+    map->pitch      = 0;
+    map->pixel_mode = ft_pixel_mode_mono;
+  }
+
+
+  static
+  TT_Error Load_SBit_Single( FT_Bitmap*        map,
+                             TT_Int            x_offset,
+                             TT_Int            y_offset,
+                             TT_Int            pix_bits,
+                             TT_UShort         image_format,
+                             TT_SBit_Metrics*  metrics,
+                             FT_Stream         stream )
+  {
+    TT_Error  error;
+
+
+    /* check that the source bitmap fits into the target pixmap */
+    if ( x_offset < 0 || x_offset + metrics->width  > map->width ||
+         y_offset < 0 || y_offset + metrics->height > map->rows  )
+    {
+      error = TT_Err_Invalid_Argument;
+
+      goto Exit;
+    }
+
+    {
+      TT_Int  glyph_width  = metrics->width;
+      TT_Int  glyph_height = metrics->height;
+      TT_Int  glyph_size;
+      TT_Int  line_bits    = pix_bits * glyph_width;
+      TT_Bool pad_bytes    = 0;
+
+
+      /* compute size of glyph image */
+      switch ( image_format )
+      {
+      case 1:  /* byte-padded formats */
+      case 6:
+        {
+          TT_Int  line_length;
+
+
+          switch ( pix_bits )
+          {
+          case 1:  line_length = (glyph_width+7) >> 3;   break;
+          case 2:  line_length = (glyph_width+3) >> 2;   break;
+          case 4:  line_length = (glyph_width+1) >> 1;   break;
+          default: line_length =  glyph_width;
+          }
+
+          glyph_size = glyph_height * line_length;
+          pad_bytes  = 1;
+        }
+        break;
+
+      case 2:
+      case 5:
+      case 7:
+        line_bits  =  glyph_width * pix_bits;
+        glyph_size = (glyph_height * line_bits + 7) >> 3;
+        break;
+
+      default:  /* invalid format */
+        return TT_Err_Invalid_File_Format;
+      }
+
+      /* Now read data and draw glyph into target pixmap       */
+      if ( ACCESS_Frame( glyph_size ) )
+        goto Exit;
+
+      /* don't forget to multiply `x_offset' by `map->pix_bits' as */
+      /* the sbit blitter doesn't make a difference between pixmap */
+      /* depths.                                                   */
+      blit_sbit( map, stream->cursor, line_bits, pad_bytes,
+                 x_offset * pix_bits, y_offset );
+
+      FORGET_Frame();
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  static
+  TT_Error Load_SBit_Image( TT_SBit_Strike*   strike,
+                            TT_SBit_Range*    range,
+                            TT_ULong          ebdt_pos,
+                            TT_ULong          glyph_offset,
+                            FT_Bitmap*        map,
+                            TT_Int            x_offset,
+                            TT_Int            y_offset,
+                            FT_Stream         stream,
+                            TT_SBit_Metrics*  metrics )
+  {
+    FT_Memory            memory = stream->memory;
+    TT_Error             error;
+
+
+    /* place stream at beginning of glyph data and read metrics */
+    if ( FILE_Seek( ebdt_pos + glyph_offset ) )
+      goto Exit;
+
+    error = Load_SBit_Metrics( stream, range, metrics );
+    if ( error )
+      goto Exit;
+
+    /* this function is recursive.  At the top-level call, the */
+    /* field map.buffer is NULL.  We thus begin by finding the */
+    /* dimensions of the higher-level glyph to allocate the    */
+    /* final pixmap buffer                                     */
+    if ( map->buffer == 0 )
+    {
+      TT_Long  size;
+
+
+      map->width    = metrics->width;
+      map->rows     = metrics->height;
+
+      switch ( strike->bit_depth )
+      {
+      case 1:
+        map->pixel_mode = ft_pixel_mode_mono; 
+        map->pitch      = (map->width+7) >> 3;
+        break;
+      case 2:
+        map->pixel_mode = ft_pixel_mode_pal2; 
+        map->pitch      = (map->width+3) >> 2;
+        break;
+      case 4:
+        map->pixel_mode = ft_pixel_mode_pal4; 
+        map->pitch      = (map->width+1) >> 1;
+        break;
+      case 8:
+        map->pixel_mode = ft_pixel_mode_grays; 
+        map->pitch      = map->width;
+        break;
+
+      default:
+        return TT_Err_Invalid_File_Format;
+      }
+
+      size = map->rows * map->pitch;
+
+      /* check that there is no empty image */
+      if ( size == 0 )
+        goto Exit;     /* exit successfully! */
+
+      if ( ALLOC( map->buffer, size ) )
+        goto Exit;
+    }
+
+    switch ( range->image_format )
+    {
+    case 1:  /* single sbit image - load it */
+    case 2:
+    case 5:
+    case 6:
+    case 7:
+      return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
+                               range->image_format, metrics, stream );
+
+    case 8:  /* compound format */
+    case 9:
+      break;
+
+    default: /* invalid image format */
+      return TT_Err_Invalid_File_Format;
+    }
+
+    /* All right, we're in a compound format.  First of all, read */
+    /* the array of elements                                      */
+    {
+      TT_SBit_Component*  components;
+      TT_SBit_Component*  comp;
+      TT_UShort           num_components, count;
+
+
+      if ( READ_UShort( num_components )                                ||
+           ALLOC_ARRAY( components, num_components, TT_SBit_Component ) )
+        goto Exit;
+
+      count = num_components;
+
+      if ( ACCESS_Frame( 4L * num_components ) )
+        goto Fail_Memory;
+
+      for ( comp = components; count > 0; count--, comp++ )
+      {
+        comp->glyph_code = GET_UShort();
+        comp->x_offset   = GET_Char();
+        comp->y_offset   = GET_Char();
+      }
+
+      FORGET_Frame();
+
+      /* Now recursively load each element glyph */
+      count = num_components;
+      comp  = components;
+      for ( ; count > 0; count--, comp++ )
+      {
+        TT_SBit_Range*   elem_range;
+        TT_SBit_Metrics  elem_metrics;
+        TT_ULong         elem_offset;
+
+
+        /* find the range for this element */
+        error = Find_SBit_Range( comp->glyph_code,
+                                 strike,
+                                 &elem_range,
+                                 &elem_offset );
+        if ( error )
+          goto Fail_Memory;
+
+        /* now load the element, recursively */
+        error = Load_SBit_Image( strike,
+                                 elem_range,
+                                 ebdt_pos,
+                                 elem_offset,
+                                 map,
+                                 x_offset + comp->x_offset,
+                                 y_offset + comp->y_offset,
+                                 stream,
+                                 &elem_metrics );
+        if ( error )
+          goto Fail_Memory;
+      }
+
+    Fail_Memory:
+      FREE( components );
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Image                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given glyph sbit image from the font resource.  This also  */
+  /*    returns its metrics.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: The target face object.                             */
+  /*                                                                       */
+  /*    x_ppem      :: The horizontal resolution in points per EM.         */
+  /*                                                                       */
+  /*    y_ppem      :: The vertical resolution in points per EM.           */
+  /*                                                                       */
+  /*    glyph_index :: The current glyph index.                            */
+  /*                                                                       */
+  /*    stream      :: The input stream.                                   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    map         :: The target pixmap.                                  */
+  /*    metrics     :: A big sbit metrics structure for the glyph image.   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.  Returns an error if no     */
+  /*    glyph sbit exists for the index.                                   */
+  /*                                                                       */
+  /*  <Note>                                                               */
+  /*    The `map.buffer' field is always freed before the glyph is loaded. */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_SBit_Image( TT_Face           face,
+                                TT_Int            x_ppem,
+                                TT_Int            y_ppem,
+                                TT_UInt           glyph_index,
+                                FT_Stream         stream,
+                                FT_Bitmap*        map,
+                                TT_SBit_Metrics*  metrics )
+  {
+    TT_Error         error;
+    FT_Memory        memory = stream->memory;
+    TT_ULong         ebdt_pos, glyph_offset;
+
+    TT_SBit_Strike*  strike;
+    TT_SBit_Range*   range;
+
+
+    /* Check whether there is a glyph sbit for the current index */
+    error = Find_SBit_Image( face, glyph_index, x_ppem, y_ppem,
+                             &range, &strike, &glyph_offset );
+    if ( error )
+      goto Exit;
+
+    /* now, find the location of the `EBDT' table in */
+    /* the font file                                 */
+    error = face->goto_table( face, TTAG_EBDT, stream, 0 );
+    if (error) goto Exit;
+    
+    ebdt_pos = FILE_Pos();
+
+    /* clear the bitmap & load the bitmap */
+    FREE( map->buffer );
+    map->rows = map->pitch = map->width = 0;
+
+    error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
+                             map, 0, 0, stream, metrics );
+    if ( error )
+      goto Exit;
+
+    /* setup vertical metrics if needed */
+    if ( strike->flags & 1 )
+    {
+      /* in case of a horizontal strike only */
+      FT_Int  advance;
+      FT_Int  top;
+
+
+      advance = strike->hori.ascender - strike->hori.descender;
+      top     = advance / 10;
+
+      metrics->vertBearingX = -metrics->width / 2;
+      metrics->vertBearingY =  advance / 10;
+      metrics->vertAdvance  =  advance * 12 / 10;
+    }
+
+    /* Crop the bitmap now */
+    Crop_Bitmap( map, metrics );
+
+  Exit:
+    return error;
+  }
+
+
+/* END */
diff --git a/src/sfnt/ttsbit.h b/src/sfnt/ttsbit.h
new file mode 100644
index 0000000..414ceae
--- /dev/null
+++ b/src/sfnt/ttsbit.h
@@ -0,0 +1,104 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttsbit.h                                                               */
+/*                                                                         */
+/*    TrueType and OpenType embedded bitmap support (specification).       */
+/*                                                                         */
+/*  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 TTSBIT_H
+#define TTSBIT_H
+
+#include <ttload.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Strikes                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the table of embedded bitmap sizes for this face.            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: The target face object.                                  */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_SBit_Strikes( TT_Face    face,
+                                  FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_SBit_Strikes                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases the embedded bitmap tables.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: The target face object.                                    */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Free_SBit_Strikes( TT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Image                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given glyph sbit image from the font resource.  This also  */
+  /*    returns its metrics.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: The target face object.                             */
+  /*                                                                       */
+  /*    x_ppem      :: The horizontal resolution in points per EM.         */
+  /*                                                                       */
+  /*    y_ppem      :: The vertical resolution in points per EM.           */
+  /*                                                                       */
+  /*    glyph_index :: The current glyph index.                            */
+  /*                                                                       */
+  /*    stream      :: The input stream.                                   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    map         :: The target pixmap.                                  */
+  /*    metrics     :: A big sbit metrics structure for the glyph image.   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.  Returns an error if no     */
+  /*    glyph sbit exists for the index.                                   */
+  /*                                                                       */
+  /*  <Note>                                                               */
+  /*    The `map.buffer' field is always freed before the glyph is loaded. */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_SBit_Image( TT_Face           face,
+                                TT_Int            x_ppem,
+                                TT_Int            y_ppem,
+                                TT_UInt           glyph_index,
+                                FT_Stream         stream,
+                                FT_Bitmap*        map,
+                                TT_SBit_Metrics*  metrics );
+
+
+#endif /* TTSBIT_H */
+
+
+/* END */
diff --git a/src/shared/otlayout/otlayout.h b/src/shared/otlayout/otlayout.h
new file mode 100644
index 0000000..e606cfb
--- /dev/null
+++ b/src/shared/otlayout/otlayout.h
@@ -0,0 +1,372 @@
+/***************************************************************************/
+/*                                                                         */
+/*  otlayout.h                                                             */
+/*                                                                         */
+/*    OpenType layout type definitions (specification only).               */
+/*                                                                         */
+/*  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 OTLAYOUT_H
+#define OTLAYOUT_H
+
+#include <tttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_LangSys                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL LangSys record.                                             */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    lang_tag            :: The language tag.                           */
+  /*    lang_offset         :: The offset of the langsys data in the
+  /*                           resource.                                   */
+  /*                                                                       */
+  /*    lookup_order        :: Always 0 for OTL 1.0.                       */
+  /*    req_feature_index   :: The `required feature' index.               */
+  /*    num_feature_indices :: The number of feature indices.              */
+  /*    feature_indices     :: An array of feature indices.                */
+  /*                                                                       */
+  typedef struct  OTL_LangSys_
+  {
+    TT_ULong    lang_tag;
+    TT_ULong    lang_offset;
+
+    TT_UShort   lookup_order;           /* always 0 for TT Open 1.0  */
+    TT_UShort   req_feature_index;      /* required FeatureIndex     */
+    TT_UShort   num_feature_indices;    /* number of Feature indices */
+    TT_UShort*  feature_indices;        /* array of Feature indices  */
+
+  } OTL_LangSys;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_Script                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL Script record.                                              */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    script_tag      :: The script tag.                                 */
+  /*    script_offset   :: The offset of the script data in the resource.  */
+  /*                                                                       */
+  /*    num_langsys     :: The number of langsys records.                  */
+  /*    langsys         :: An array of langsys records.                    */
+  /*    langsys_default :: A pointer to the default langsys table for this */
+  /*                       script.                                         */
+  /*                                                                       */
+  typedef struct  OTL_Script_
+  {
+    TT_ULong      script_tag;
+    TT_ULong      script_offset;
+
+    TT_UShort     num_langsys;
+    OTL_LangSys*  langsys;
+    OTL_LangSys*  langsys_default;
+
+  } OTL_Script;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_Script_List                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL Script List record.                                         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    num_scripts :: The number of scripts records.                      */
+  /*    scripts     :: An array of script records.                         */
+  /*                                                                       */
+  typedef struct  OTL_Script_List_
+  {
+    TT_UShort    num_scripts;
+    OTL_Script*  scripts;
+
+  } OTL_Script_List;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_Feature                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL Feature record.                                             */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    feature_tag    :: The feature tag.                                 */
+  /*    feature_offset :: The offset of the feature data in the resource.  */
+  /*                                                                       */
+  /*    feature_params :: Always 0 for OpenType Layout 1.0.                */
+  /*    num_lookups    :: The number of lookup indices.                    */
+  /*    lookups        :: An array of lookup indices.                      */
+  /*                                                                       */
+  typedef struct  OTL_Feature_
+  {
+    TT_ULong    feature_tag;
+    TT_ULong    feature_offset;
+
+    TT_UShort   feature_params;    /* always 0 for OpenType Layout 1.0 */
+    TT_UShort   num_lookups;
+    TT_UShort*  lookups;
+
+  } OTL_Feature;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_Feature_List                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL Feature List record.                                        */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    num_features :: The number of features.                            */
+  /*    features     :: An array of features.                              */
+  /*                                                                       */
+  typedef struct  OTL_Feature_List_
+  {
+    TT_UShort     num_features;
+    OTL_Feature*  features;
+
+  } OTL_Feature_List;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_Lookup                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL Lookup record.                                              */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    lookup_offset    :: The offset of the lookup data in the resource. */
+  /*    lookup_type      :: The lookup type.                               */
+  /*    lookup_flag      :: The lookup bit flags.                          */
+  /*                                                                       */
+  /*    num_subtables    :: The number of subtables.                       */
+  /*    subtable_offsets :: An array of offsets to the subtables.          */
+  /*    subtables        :: An array of pointers to the subtable records.  */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The format of each lookup sub-table is determined by the parent    */
+  /*    OpenType table, and cannot be known here.                          */
+  /*                                                                       */
+  /*    The `subtable_offsets' array is filled when the lookup table is    */
+  /*    loaded the first time.  It is up to OT table handlers to read the  */
+  /*    corresponding sub-table records and store them in the `subtables'  */
+  /*    array.                                                             */
+  /*                                                                       */
+  typedef struct  OTL_Lookup_
+  {
+    TT_ULong   lookup_offset;
+    TT_UShort  lookup_type;
+    TT_UShort  lookup_flag;
+
+    TT_UShort  num_subtables;
+    TT_ULong*  subtable_offsets;
+    void**     subtables;
+
+  } OTL_Lookup;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_Lookup_List                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL Lookup List record.                                         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    num_lookups :: The number of lookups.                              */
+  /*    lookups     :: An array of lookups.                                */
+  /*                                                                       */
+  typedef struct  OTL_Lookup_List_
+  {
+    TT_UShort    num_lookups;
+    OTL_Lookup*  lookups;
+
+  } OTL_Lookup_List;
+
+
+#define OTL_LOOKUP_FLAG_RIGHT_TO_LEFT       1
+#define OTL_LOOKUP_FLAG_IGNORE_BASE_GLYPHS  2
+#define OTL_LOOKUP_FLAG_IGNORE_LIGATURES    4
+#define OTL_LOOKUP_FLAG_IGNORE_MARKS        8
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_SubTable1                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The first generic OTL sub-table format.                            */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    num_indices :: The number of indices.                              */
+  /*    indices     :: An array of indices.                                */
+  /*    data        :: A generic value.                                    */
+  /*                                                                       */
+  typedef struct  OTL_SubTable1_
+  {
+    TT_UShort   num_indices;
+    TT_UShort*  indices;
+    TT_UShort   data;
+
+  } OTL_SubTable1;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_SubTable2_Rec                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A record for the second generic OTL sub-table format.              */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    start :: The first element in the range.                           */
+  /*    end   :: The last element in the range.                            */
+  /*    data  :: A generic value.                                          */
+  /*                                                                       */
+  typedef struct  OTL_SubTable2_Rec_
+  {
+    TT_UShort  start;
+    TT_UShort  end;
+    TT_UShort  data;
+
+  } OTL_SubTable2_Rec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_SubTable2                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The second generic OTL sub-table format.                           */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    num_ranges :: The number of ranges.                                */
+  /*    ranges     :: An array of ranges.                                  */
+  /*                                                                       */
+  typedef struct  OTL_SubTable2_
+  {
+    TT_UShort           num_ranges;
+    OTL_SubTable2_Rec*  ranges;
+
+  } OTL_SubTable2;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_SubTable                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A generic OTL sub-table which is a union of two possible formats   */
+  /*    just defined.                                                      */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    format :: The format of the sub-table.                             */
+  /*    set    :: A union of `format1' and `format2', representing         */
+  /*              sub-tables.                                              */
+  /*                                                                       */
+  typedef struct  OTL_SubTable_
+  {
+    TT_UShort  format;
+
+    union
+    {
+      OTL_SubTable1  format1;
+      OTL_SubTable2  format2;
+
+    } set;
+
+  } OTL_SubTable;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_Coverage                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL Coverage sub-table.                                         */
+  /*                                                                       */
+  typedef OTL_SubTable       OTL_Coverage;
+  typedef OTL_SubTable1      OTL_Coverage1;
+  typedef OTL_SubTable2      OTL_Coverage2;
+  typedef OTL_SubTable2_Rec  OTL_Coverage2_Rec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_Class_Def                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL Class Definition sub-table.                                 */
+  /*                                                                       */
+  typedef OTL_SubTable       OTL_Class_Def;
+  typedef OTL_SubTable1      OTL_Class_Def1;
+  typedef OTL_SubTable2      OTL_Class_Def2;
+  typedef OTL_SubTable2_Rec  OTL_Class_Def2_Rec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    OTL_Device                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An OTL Device sub-table                                            */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    start_size   :: The smallest size to correct.                      */
+  /*    end_size     :: The largest size to correct.                       */
+  /*    delta_format :: The format of the `delta_values' array.            */
+  /*    delta_values :: An array of compressed delta values.               */
+  typedef struct  OTL_Device_
+  {
+    TT_UShort   start_size;
+    TT_UShort   end_size;
+    TT_UShort   delta_format;
+    TT_UShort*  delta_values;
+
+  } OTL_Device;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OTLAYOUT_H */
+
+
+/* END */
diff --git a/src/shared/otlayout/otload.c b/src/shared/otlayout/otload.c
new file mode 100644
index 0000000..786beb3
--- /dev/null
+++ b/src/shared/otlayout/otload.c
@@ -0,0 +1,890 @@
+/***************************************************************************/
+/*                                                                         */
+/*  otload.c                                                               */
+/*                                                                         */
+/*    OpenType Layout loader (body).                                       */
+/*                                                                         */
+/*  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 <otlayout.h>
+#include <otload.h>
+
+#include <tterrors.h>
+
+
+  /***************************
+   * Script related functions
+   ***************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Script_List                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Script list.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target script list.                                  */
+  /*    system :: The current system object.                               */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  OTL_Free_Script_List( OTL_Script_List*  list,
+                              FT_System         system )
+  {
+    if ( list )
+    {
+      if ( list->scripts )
+      {
+        OTL_Script*  script       = list->scripts;
+        OTL_Script*  script_limit = script + list->num_scripts;
+
+
+        for ( ; script < script_limit; script++ )
+        {
+          if ( script->langsys )
+          {
+            OTL_LangSys*  langsys       = script->langsys;
+            OTL_LangSys*  langsys_limit = langsys + script->num_langsys;
+
+
+            for ( ; langsys < langsys_limit; langsys++ )
+            {
+              FREE( langsys->feature_indices );
+              langsys->num_feature_indices = 0;
+            }
+            FREE( script->langsys );
+          }
+          script->langsys_default = NULL;
+          script->num_langsys     = 0;
+        }
+        FREE( list->scripts );
+      }
+      list->num_scripts = 0;
+    }
+  }
+
+
+  static
+  TT_Error  Load_OTL_LangSys_List( OTL_Script*  script,
+                                   FT_Stream    stream,
+                                   TT_ULong     default_offset )
+  {
+    FT_System  system = stream->system;
+    TT_Error   error;
+
+    TT_UShort     n, count;
+    OTL_LangSys*  langsys;
+
+
+    /* read the langsys tags and offsets */
+    {
+      count   = script->num_langsys;
+      langsys = script->langsys;
+
+      if ( ACCESS_Frame( 6L * count ) )
+        goto Exit;
+
+      for ( n = 0; n < count; n++, langsys++ )
+      {
+        TT_ULong  offset;
+
+
+        langsys->lang_tag = GET_ULong();
+        offset            = GET_UShort();
+
+        if ( langsys->lang_offset == default_offset )
+          script->langsys_default = langsys;
+
+        langsys->lang_offset = offset + script->script_offset;
+      }
+
+      FORGET_Frame();
+    }
+
+    /* now read each langsys record */
+    {
+      count   = script->num_langsys;
+      langsys = script->langsys;
+
+      for ( n = 0; n < count; n++, langsys++ )
+      {
+        TT_UShort  num_feature_indices, i;
+
+
+        if ( FILE_Seek( langsys->lang_offset ) ||
+             ACCESS_Frame( 8L )                )
+          goto Exit;
+
+        langsys->lookup_order        = GET_ULong();
+        langsys->req_feature_index   = GET_UShort();
+        langsys->num_feature_indices = GET_UShort();
+
+        FORGET_Frame();
+
+        num_feature_indices = langsys->num_feature_indices;
+
+        if ( ALLOC_ARRAY ( langsys->feature_indices,
+                           num_feature_indices, TT_UShort ) ||
+             ACCESS_Frame( num_feature_indices * 2L )       )
+          goto Exit;
+
+        for ( i = 0; i < num_feature_indices; i++ )
+          langsys->feature_indices[i] = GET_UShort();
+
+        FORGET_Frame();
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Script_List                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Script List from a font resource.                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target script list.                                  */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  OTL_Load_Script_List( OTL_Script_List*  list,
+                                  FT_Stream         stream )
+  {
+    FT_System  system = stream->system;
+    TT_Error   error;
+
+    TT_ULong     start_pos;
+    TT_UShort    num_scripts;
+    OTL_Script*  scripts;
+
+
+    start_pos = FILE_Pos();
+
+    if ( READ_UShort( list->num_scripts ) )
+      goto Exit;
+
+    num_scripts = list->num_scripts;
+
+    /* Allocate the scripts table, read their tags and offsets */
+    {
+      TT_UShort  n;
+
+
+      if ( ALLOC_ARRAY( list->scripts, num_scripts, OTL_Script ) ||
+           ACCESS_Frame( num_scripts * 6L )                      )
+        goto Exit;
+
+      scripts = list->scripts;
+
+      for ( n = 0; n < num_scripts; n++ )
+      {
+        scripts[n].script_tag    = GET_ULong();
+        scripts[n].script_offset = GET_UShort() + start_pos;
+      }
+
+      FORGET_Frame();
+    }
+
+    /* now read each script in the table */
+    {
+      TT_UShort    n;
+      OTL_Script*  script = scripts;
+
+
+      for ( n = num_scripts; n > 0; n--, script++ )
+      {
+        TT_ULong  default_langsys_offset;
+
+
+        if ( FILE_Seek  ( script->script_offset )            ||
+             READ_ULong ( default_langsys_offset )           ||
+             READ_UShort( script->num_langsys )              ||
+             ALLOC_ARRAY( script->langsys,
+                          script->num_langsys, OTL_LangSys ) )
+          goto Exit;
+
+        /* read the corresponding langsys list */
+        error = Load_OTL_LangSys_List(
+                     script,
+                     stream,
+                     default_langsys_offset + script->script_offset );
+        if ( error )
+          goto Exit;
+      }
+    }
+
+  Exit:
+    if ( error )
+      OTL_Free_Script_List( list, system );
+
+    return error;
+  }
+
+
+  /*********************************
+   * Feature List related functions
+   *********************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Features_List                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Features list.                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target feature list.                                 */
+  /*    system :: The current system object.                               */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  OTL_Free_Features_List( OTL_Feature_List*  list,
+                                FT_System          system )
+  {
+    if ( list )
+    {
+      if ( list->features )
+      {
+        OTL_Feature*  feature       = list->features;
+        OTL_Feature*  feature_limit = feature + list->num_features;
+
+
+        for ( ; feature < feature_limit; feature++ )
+        {
+          FREE( feature->lookups );
+          feature->num_lookups = 0;
+        }
+
+        FREE( list->features );
+      }
+      list->num_features = 0;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Feature_List                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Feature List from a font resource.               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target feature list.                                 */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  OTL_Load_Feature_List( OTL_Feature_List*  list,
+                                   FT_Stream          stream )
+  {
+    FT_System  system = stream->system;
+    TT_Error   error;
+    TT_ULong   start_pos;
+    TT_UShort  num_features, n;
+
+
+    start_pos = FILE_Pos();
+
+    if ( READ_UShort( num_features ) )
+      goto Exit;
+
+    /* allocate the features array and read their tag and offset */
+    {
+      OTL_Feature*  feature;
+      OTL_Feature*  feature_limit;
+
+
+      if ( ALLOC_ARRAY ( list->features, num_features, OTL_Feature ) ||
+           ACCESS_Frame( num_features * 6L )                         )
+        goto Exit;
+
+      list->num_features = num_features;
+      feature            = list->features;
+      feature_limit      = feature + num_features;
+
+      for ( ; feature < feature_limit; feature++ )
+      {
+        feature->feature_tag    = GET_ULong();
+        feature->feature_offset = GET_UShort() + start_pos;
+      }
+
+      FORGET_Frame();
+    }
+
+    /* now read each feature */
+    {
+      OTL_Feature*  feature;
+      OTL_Feature*  feature_limit;
+
+
+      feature            = list->features;
+      feature_limit      = feature + num_features;
+
+      for ( ; feature < feature_limit; feature++ )
+      {
+        TT_UShort   num_lookups;
+        TT_UShort*  lookup;
+        TT_UShort*  lookup_limit;
+
+
+        if ( FILE_Seek   ( feature->feature_offset  ) ||
+             READ_ULong  ( feature->feature_params )  ||
+             READ_UShort ( num_lookups )              ||
+             ALLOC_ARRAY ( feature->lookups,
+                           num_lookups, TT_UShort )   ||
+             ACCESS_Frame( num_lookups * 2L )         )
+          goto Exit;
+
+        feature->num_lookups = num_lookups;
+        lookup               = feature->lookups;
+        lookup_limit         = lookup + num_lookups;
+
+        for ( ; lookup < lookup_limit; lookup++ )
+          lookup[0] = GET_UShort();
+
+        FORGET_Frame();
+      }
+    }
+
+  Exit:
+    if ( error )
+      OTL_Free_Feature_List( list, system );
+
+    return error;
+  }
+
+
+  /********************************
+   * Lookup List related functions
+   ********************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Iterate_Lookup_List                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Scans an OpenType Lookup List.  This can be used to load the       */
+  /*    Lookup sub-tables in a GSUB or GPOS loader.                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list     :: The source list.                                       */
+  /*    iterator :: The iterator -- a function which is called on each     */
+  /*                element of the list.                                   */
+  /*    closure  :: User-specified data which is passed to each iterator   */
+  /*                with the lookup element pointer.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    If one iterator call returns a non-zero `result', the list parsing */
+  /*    is aborted and the value is returned to the caller.  Otherwise,    */
+  /*    the function returns 0 when the list has been parsed completely.   */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  OTL_Iterate_Lookup_List( OTL_Lookup_List*     list,
+                                     OTL_Lookup_Iterator  iterator,
+                                     void*                closure )
+  {
+    int  result = 0;
+
+
+    if ( list->lookups )
+    {
+      OTL_Lookup*  lookup = list->lookups;
+      OTL_Lookup*  limit  = lookup + list->num_lookups;
+
+
+      for ( ; lookup < limit; lookup++ )
+      {
+        result = iterator( lookup, closure );
+        if ( result )
+          break;
+      }
+    }
+
+    return 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Lookup_List                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Lookup list.  Uses a destructor called   */
+  /*    to destroy the Lookup sub-tables.                                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list       :: The target lookup list.                              */
+  /*    system     :: The current system object.                           */
+  /*    destructor :: A destructor function called on each lookup element. */
+  /*                  Can be used to destroy sub-tables.  Ignored if NULL. */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  OTL_Free_Lookup_List( OTL_Lookup_List*       list,
+                              FT_System              system,
+                              OTL_Lookup_Destructor  destroy )
+  {
+    if ( list )
+    {
+      if ( list->lookups )
+      {
+        OTL_Lookup*  lookup = list->lookups;
+        OTL_Lookup*  limit  = lookup + list->num_lookups;
+
+
+        for ( ; lookup < limit; lookup++ )
+        {
+          if ( destroy )
+            destroy( lookup, system );
+
+          FREE( lookup->subtable_offsets );
+          lookup->num_subtables = 0;
+        }
+
+        FREE( list->lookups );
+      }
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Lookup_List                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Lookup List from a font resource.                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target lookup list.                                  */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function does NOT load the lookup sub-tables.  Instead, it    */
+  /*    stores the file offsets of the particular table in each lookup     */
+  /*    element.  It is up to the caller to load these sub-tables.  This   */
+  /*    can be done more easily with OTL_Iterate_Lookup_List().            */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  OTL_Load_Lookup_List( OTL_Lookup_List*  list,
+                                  FT_Stream         stream )
+  {
+    FT_System  system = stream->system;
+    TT_Error   error;
+
+    TT_UShort  num_lookups;
+    TT_ULong   start_pos;
+
+
+    start_pos = GET_ULong();
+
+    if ( READ_UShort( num_lookups ) )
+      goto Exit;
+
+    /* allocate the lookups array and read their tags and offset */
+    {
+      TT_UShort  n;
+
+
+      if ( ALLOC_ARRAY ( list->lookups, num_lookups, OTL_Lookup ) ||
+           ACCESS_Frame( num_lookups * 2L )                       )
+        goto Exit;
+
+      list->num_lookups = num_lookups;
+      for ( n = 0; n < num_lookups; n++ )
+        list->lookups[n].lookup_offset = start_pos + GET_UShort();
+
+      FORGET_Frame();
+    }
+
+    /* now read each lookup table                               */
+    /* NOTE that we don't load the sub-tables here, but simply  */
+    /* store their file offsets in the `subtable_offsets' array */
+    {
+      OTL_Lookup*  lookup       = list->lookups;
+      OTL_Lookup*  lookup_limit = lookup + num_lookups;
+
+
+      for ( ; lookup < lookup_limit; lookup++ )
+      {
+        TT_UShort   n, num_subtables;
+        TT_ULong*  offsets;
+
+
+        if ( FILE_Seek   ( lookup->lookup_offset ) ||
+             ACCESS_Frame( 6L )                    )
+          goto Exit;
+
+        lookup->lookup_type   = GET_UShort();
+        lookup->lookup_flag   = GET_UShort();
+        lookup->num_subtables = GET_UShort();
+
+        num_subtables = lookup->num_subtables;
+
+        FORGET_Frame();
+
+        if ( ALLOC_ARRAY ( lookup->subtable_offsets,
+                           num_subtables, TT_ULong ) ||
+             ACCESS_Frame( num_subtables * 2L )      )
+          goto Exit;
+
+        offsets = lookup->subtable_offsets;
+        for ( n = 0; n < num_subtables; n++ )
+          offsets[n] = lookup->lookup_offset + GET_UShort();
+
+        FORGET_Frame();
+      }
+    }
+
+  Exit:
+    if ( error )
+      OTL_Free_Lookup_List( list, system, 0 );
+
+    return error;
+  }
+
+
+  /* generic sub-table freeing and loading */
+
+  static
+  void  Free_SubTable( OTL_SubTable*  subtable,
+                       FT_System      system )
+  {
+    if ( subtable )
+    {
+      switch ( subtable->format )
+      {
+      case 1:
+        {
+          OTL_SubTable1*  st = &subtable->set.format1;
+
+
+          FREE( st->indices );
+          st->num_indices = 0;
+          FREE( st );
+        }
+        break;
+
+      case 2:
+        {
+          OTL_SubTable2*  st = &subtable->set.format2;
+
+
+          FREE( st->ranges );
+          st->num_ranges = 0;
+          FREE( st );
+        }
+        break;
+
+      default:
+        break;
+      }
+
+      FREE( subtable );
+    }
+  }
+
+
+  static
+  TT_Error  Load_SubTable( OTL_SubTable*  subtable,
+                           FT_Stream      stream )
+  {
+    FT_System  system = stream->system;
+    TT_Error   error;
+
+
+    if ( READ_UShort( subtable->format ) )
+      goto Exit;
+
+    switch ( subtable->format )
+    {
+    case 1:
+      {
+        OTL_SubTable1*  st = &subtable->set.format1;
+        TT_UShort       num_indices, n;
+
+
+        if ( READ_UShort ( num_indices )                         ||
+             ALLOC_ARRAY ( st->indices, num_indices, TT_UShort ) ||
+             ACCESS_Frame( num_indices * 2L )                    )
+          goto Exit;
+
+        st->num_indices = num_indices;
+        for ( n = 0; n < num_indices; n++ )
+          st->indices[n] = GET_UShort();
+
+        FORGET_Frame();
+      }
+
+    case 2:
+      {
+        OTL_SubTable2*      st = &subtable->set.format2;
+        TT_UShort           num_ranges, n;
+        OTL_SubTable2_Rec*  range;
+
+
+        if ( READ_UShort( num_ranges )                                ||
+             ALLOC_ARRAY( st->ranges, num_ranges, OTL_SubTable2_Rec ) ||
+             ACCESS_Frame( num_ranges * 6L )                          )
+          goto Exit;
+
+        st->num_ranges = num_ranges;
+        range          = st->ranges;
+        for ( ; num_ranges > 0; num_ranges--, range++ )
+        {
+          range->start = GET_UShort();
+          range->end   = GET_UShort();
+          range->data  = GET_UShort();
+        }
+
+        FORGET_Frame();
+      }
+      break;
+
+    default:
+      error = TT_Err_Invalid_File_Format;
+    }
+
+  Exit:
+    if ( error )
+      Free_SubTable( subtable, system );
+
+    return error;
+  }
+
+
+  /*****************************
+   * Coverage related functions
+   *****************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Coverage                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Coverage table.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    coverage :: The target coverage.                                   */
+  /*    system   :: The current system object.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  OTL_Free_Coverage( OTL_Coverage*  coverage,
+                           FT_System      system )
+  {
+    Free_SubTable( (OTL_SubTable*)coverage, system );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Coverage                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Coverage table from a font resource.             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    coverage :: The target coverage.                                   */
+  /*    stream   :: The input stream.                                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  OTL_Load_Coverage( OTL_Coverage*  coverage,
+                               FT_Stream      stream )
+  {
+    return Load_SubTable( (OTL_SubTable*)coverage, stream );
+  }
+
+
+  /*************************************
+   * Class Definition related functions
+   *************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Class_Def                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Class Definition table.                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    class_def :: The target class definition.                          */
+  /*    system    :: The current system object.                            */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  OTL_Free_Class_Def( OTL_Class_Def*  class_def,
+                            FT_System       system )
+  {
+    Free_SubTable( (OTL_SubTable*)class_def, system );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Class_Def                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Class Definition table from a resource.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    class_def :: The target class definition.                          */
+  /*    stream    :: The input stream.                                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  OTL_Load_Class_Def( OTL_Class_Def*  class_def,
+                                FT_Stream       stream )
+  {
+    return OTL_Load_SubTable( (OTL_SubTable*)class_def, stream );
+  }
+
+
+  /*************************************
+   * Device related functions
+   *************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Device                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Layout Device table.                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    device  :: The target device table.                                */
+  /*    system  :: The current system object.                              */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  OTL_Free_Device( OTL_Device*  device,
+                         FT_System    system )
+  {
+    if ( device )
+    {
+      FREE( device->delta_values );
+      FREE( device );
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Device                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Device table from a font resource.               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    device :: The target device table.                                 */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  OTL_Load_Device( OTL_Device*  device,
+                             FT_Stream    stream )
+  {
+    FT_System   system = stream->system;
+    TT_Error    error;
+    TT_UShort*  deltas;
+    TT_UShort   num_deltas, num_values;
+
+
+    if ( ACCESS_Frame( 6L ) )
+      goto Exit;
+
+    device->start_size   = GET_UShort();
+    device->end_size     = GET_UShort();
+    device->delta_format = GET_UShort();
+
+    FORGET_Frame();
+
+    num_deltas = device->end_size - device->start_size + 1;
+
+    switch ( device->delta_format )
+    {
+    case 1:
+      num_values = ( num_deltas + 7 ) >> 3;
+      break;
+
+    case 2:
+      num_values = ( num_deltas + 3 ) >> 2;
+      break;
+
+    case 3:
+      num_values = ( num_deltas + 1 ) >> 1;
+      break;
+
+    default:
+      error = TT_Err_Invalid_File_Format;
+      goto Exit;
+    }
+
+    if ( ALLOC_ARRAY( deltas, num_values, TT_UShort ) )
+      goto Exit;
+
+    if ( !ACCESS_Frame( num_values * 2L ) )
+    {
+      TT_UShort  n;
+
+
+      for ( n = 0; n < num_values; n++ )
+        deltas[n] = GET_UShort();
+
+      FORGET_Frame();
+
+      device->delta_values = deltas;
+    }
+    else
+      FREE( deltas );
+
+  Exit:
+    return error;
+  }
+
+
+/* END */
diff --git a/src/shared/otlayout/otload.h b/src/shared/otlayout/otload.h
new file mode 100644
index 0000000..477bba3
--- /dev/null
+++ b/src/shared/otlayout/otload.h
@@ -0,0 +1,297 @@
+/***************************************************************************/
+/*                                                                         */
+/*  otload.h                                                               */
+/*                                                                         */
+/*    OpenType layout loader functions (specification).                    */
+/*                                                                         */
+/*  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 OTLOAD_H
+#define OTLOAD_H
+
+#include <otlayout.h>
+#include <ftstream.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Script_List                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Script List from a font resource.                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target script list.                                  */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  OTL_Load_Script_List( OTL_Script_List*  list,
+                                  FT_Stream         stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Feature_List                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Feature List from a font resource.               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target feature list.                                 */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  OTL_Load_Feature_List( OTL_Feature_List*  list,
+                                   FT_Stream          stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Lookup_List                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Lookup List from a font resource.                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target lookup list.                                  */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function does NOT load the lookup sub-tables.  Instead, it    */
+  /*    stores the file offsets of the particular table in each lookup     */
+  /*    element.  It is up to the caller to load these sub-tables.  This   */
+  /*    can be done more easily with OTL_Iterate_Lookup_List().            */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  OTL_Load_Lookup_List( OTL_Lookup_List*  list,
+                                  FT_Stream         stream );
+
+
+  typedef int  OTL_Lookup_Iterator( OTL_Lookup*  lookup,
+                                    void*        closure );
+
+
+  typedef void  OTL_Lookup_Destructor( OTL_Lookup*  lookup,
+                                       FT_System    system );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Iterate_Lookup_List                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Scans an OpenType Lookup List.  This can be used to load the       */
+  /*    Lookup sub-tables in a GSUB or GPOS loader.                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list     :: The source list.                                       */
+  /*    iterator :: The iterator -- a function which is called on each     */
+  /*                element of the list.                                   */
+  /*    closure  :: User-specified data which is passed to each iterator   */
+  /*                with the lookup element pointer.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    If one iterator call returns a non-zero `result', the list parsing */
+  /*    is aborted and the value is returned to the caller.  Otherwise,    */
+  /*    the function returns 0 when the list has been parsed completely.   */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  OTL_Iterate_Lookup_List( OTL_Lookup_List*     list,
+                                     OTL_Lookup_Iterator  iterator,
+                                     void*                closure );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Coverage                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Coverage table from a font resource.             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    coverage :: The target coverage.                                   */
+  /*    stream   :: The input stream.                                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  OTL_Load_Coverage( OTL_Coverage*  coverage,
+                               FT_Stream      stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Class_Def                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Class Definition table from a resource.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    class_def :: The target class definition.                          */
+  /*    stream    :: The input stream.                                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  OTL_Load_Class_Def( OTL_Class_Def*  class_def,
+                                FT_Stream       stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Load_Device                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads an OpenType Device table from a font resource.               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    device :: The target device table.                                 */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  OTL_Load_Device( OTL_Device*  device,
+                             FT_Stream    stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Script_List                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Script list.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target script list.                                  */
+  /*    system :: The current system object.                               */
+  /*                                                                       */
+  LOCAL_DEF
+  void  OTL_Free_Script_List( OTL_Script_List*  list,
+                              FT_System         system );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Features_List                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Features list.                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list   :: The target feature list.                                 */
+  /*    system :: The current system object.                               */
+  /*                                                                       */
+  LOCAL_DEF
+  void  OTL_Free_Features_List( OTL_Feature_List*  list,
+                                FT_System          system );
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Lookup_List                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Lookup list.  Uses a destructor called   */
+  /*    to destroy the Lookup sub-tables.                                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    list       :: The target lookup list.                              */
+  /*    system     :: The current system object.                           */
+  /*    destructor :: A destructor function called on each lookup element. */
+  /*                  Can be used to destroy sub-tables.  Ignored if NULL. */
+  /*                                                                       */
+  LOCAL_DEF
+  void  OTL_Free_Lookup_List( OTL_Lookup_List*       list,
+                              FT_System              system,
+                              OTL_Lookup_Destructor  destroy );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Coverage                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Coverage table.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    coverage :: The target coverage.                                   */
+  /*    system   :: The current system object.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  void  OTL_Free_Coverage( OTL_Coverage*  coverage,
+                           FT_System      system );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Class_Def                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Class Definition table.                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    class_def :: The target class definition.                          */
+  /*    system    :: The current system object.                            */
+  /*                                                                       */
+  LOCAL_DEF
+  void  OTL_Free_Class_Def( OTL_Class_Def*  class_def,
+                            FT_System       system );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    OTL_Free_Device                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases a given OpenType Layout Device table.                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    device  :: The target device table.                                */
+  /*    system  :: The current system object.                              */
+  /*                                                                       */
+  LOCAL_DEF
+  void  OTL_Free_Device( OTL_Device*  device,
+                         FT_System    system );
+
+
+#endif /* OTLOAD_H */
+
+
+/* END */
diff --git a/src/shared/readme.txt b/src/shared/readme.txt
new file mode 100644
index 0000000..b48163a
--- /dev/null
+++ b/src/shared/readme.txt
@@ -0,0 +1,6 @@
+WARNING:
+
+The files in these subdirectories are shared by several font drivers.
+
+All C source files are included by at least one of the drivers, and
+thus should _never_ be compiled directly.
diff --git a/src/shared/rules.mk b/src/shared/rules.mk
new file mode 100644
index 0000000..e83466b
--- /dev/null
+++ b/src/shared/rules.mk
@@ -0,0 +1,95 @@
+#****************************************************************************
+#*                                                                          *
+#*  shared files Makefile                                                   *
+#*                                                                          *
+#*  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.                                         *
+#*                                                                          *
+#****************************************************************************
+
+
+#****************************************************************************
+#*                                                                          *
+#*  IMPORTANT NOTE: This Makefile is intended for GNU Make!                 *
+#*                  If you provide Makefiles for other make utilities,      *
+#*                  please place them in `freetype/lib/arch/<system>'.      *
+#*                                                                          *
+#*                                                                          *
+#*  This file is to be included by the FreeType Makefile.lib, located in    *
+#*  the `freetype/lib' directory.  Here is the list of the variables that   *
+#*  must be defined to use it:                                              *
+#*                                                                          *
+#*                                                                          *
+#*     BASE_DIR:    The location of the base layer's directory.  This is    *
+#*                  usually `freetype/lib/base'.                            *
+#*                                                                          *
+#*     ARCH_DIR:    The location of the architecture-dependent directory.   *
+#*                  This is usually `freetype/lib/arch/<system>'.           *
+#*                                                                          *
+#*     DRIVERS_DIR: The location of the font driver sub-dirs, usually       *
+#*                  `freetype/lib/drivers'.                                 *
+#*                                                                          *
+#*     OBJ_DIR:     The location where the compiled object(s) file will be  *
+#*                  placed.                                                 *
+#*                                                                          *
+#*     BASE_H:      A list of pathnames to the base layer's header files on *
+#*                  which the driver depends.                               *
+#*                                                                          *
+#*     FT_CFLAGS:   A set of flags used for compilation of object files.    *
+#*                  This contains at least the include paths of the arch    *
+#*                  and base directories + optimization + warnings + ANSI   *
+#*                  compliance.                                             *
+#*                                                                          *
+#*     FT_IFLAG:    The flag used to specify an include path on the         *
+#*                  compiler command line.  For example, with GCC, this is  *
+#*                  `-I', while some other compilers use `/i=' or `-J',     *
+#*                  etc.                                                    *
+#*                                                                          *
+#*     FT_OBJ:      The suffix of an object file for the platform; can be   *
+#*                  `o', `obj', `coff', `tco', etc. depending on the        *
+#*                  platform.                                               *
+#*                                                                          *
+#*                                                                          *
+#*  It also updates the following variables defined and used in the main    *
+#*  Makefile:                                                               *
+#*                                                                          *
+#*     DRV_OBJ_S:            The list of driver object files in             *
+#*                           single-object mode.                            *
+#*                                                                          *
+#*     DRV_OBJ_M:            The list of driver object files in             *
+#*                           multiple-objects mode.                         *
+#*                                                                          *
+#*     FTINIT_DRIVER_PATHS:  The list of include paths used to compile the  *
+#*                           `ftinit' component which registers all font    *
+#*                            drivers in the FT_Init_FreeType() function.   *
+#*                                                                          *
+#*     FTINIT_DRIVER_H:      The list of header dependencies used to        *
+#*                           compile the `ftinit' component.                *
+#*                                                                          *
+#*     FTINIT_DRIVER_MACROS: The list of macros to be defined when          *
+#*                           compiling the `ftinit' component.              *
+#*                                                                          *
+#*  `Single-object compilation' means that each font driver is compiled     *
+#*  into a single object file.  This is useful to get rid of all            *
+#*  driver-specific entries.                                                *
+#*                                                                          *
+#****************************************************************************
+
+ifndef SHARED_RULES
+SHARED_RULES := 1
+
+SHARED  := $(SRC_)shared
+SHARED_ := $(SHARED)$(SEP)
+
+SHARED_H   := $(wildcard $(SHARED_)*.h)
+SHARED_SRC := $(wildcard $(SHARED_)*.c) 
+
+endif
+
+# END
diff --git a/src/shared/sfnt.h b/src/shared/sfnt.h
new file mode 100644
index 0000000..5549479
--- /dev/null
+++ b/src/shared/sfnt.h
@@ -0,0 +1,347 @@
+/***************************************************************************/
+/*                                                                         */
+/*  sfnt.h                                                                 */
+/*                                                                         */
+/*    High-level `sfnt' driver interface (specification).                  */
+/*                                                                         */
+/*  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 SFNT_H
+#define SFNT_H
+
+#include <freetype.h>
+#include <tttypes.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_Load_Directory_Func                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the table directory into a face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face      :: A handle to the target face object.                   */
+  /*    stream    :: The input stream.                                     */
+  /*    faceIndex :: The index of the TrueType font, if we're opening a    */
+  /*                 collection.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The stream cursor must be at the font file's origin                */
+  /*                                                                       */
+  typedef
+  TT_Error  (*TT_Load_Directory_Func)( TT_Face    face,
+                                       FT_Stream  stream,
+                                       TT_Long    faceIndex );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_Load_Any_Func                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads any font table into client memory.  Used by the              */
+  /*    TT_Get_Font_Data() API function.                                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: The face object to look for.                             */
+  /*                                                                       */
+  /*    tag    :: The tag of table to load.  Use the value 0 if you  want  */
+  /*              to access the whole font file, else set this parameter   */
+  /*              to a valid TrueType table tag that you can forge with    */
+  /*              the MAKE_TT_TAG macro.                                   */
+  /*                                                                       */
+  /*    offset :: The starting offset in the table (or the file if         */
+  /*              tag == 0).                                               */
+  /*                                                                       */
+  /*    length :: The address of the decision variable:                    */
+  /*                                                                       */
+  /*                If length == NULL:                                     */
+  /*                  Loads the whole table.  Returns an error if          */
+  /*                  `offset' == 0!                                       */
+  /*                                                                       */
+  /*                If *length == 0:                                       */
+  /*                  Exits immediately; returning the length of the given */
+  /*                  table or of the font file, depending on the value of */
+  /*                  `tag'.                                               */
+  /*                                                                       */
+  /*                If *length != 0:                                       */
+  /*                  Loads the next `length' bytes of table or font,      */
+  /*                  starting at offset `offset' (in table or font too).  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    buffer :: The address of target buffer.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef
+  TT_Error  (*TT_Load_Any_Func)( TT_Face   face,
+                                 TT_ULong  tag,
+                                 TT_Long   offset,
+                                 void*     buffer,
+                                 TT_Long*  length );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_Load_SBit_Image_Func                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given glyph sbit image from the font resource.  This also  */
+  /*    returns its metrics.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: The target face object.                             */
+  /*                                                                       */
+  /*    x_ppem      :: The horizontal resolution in points per EM.         */
+  /*                                                                       */
+  /*    y_ppem      :: The vertical resolution in points per EM.           */
+  /*                                                                       */
+  /*    glyph_index :: The current glyph index.                            */
+  /*                                                                       */
+  /*    stream      :: The input stream.                                   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    map         :: The target pixmap.                                  */
+  /*    metrics     :: A big sbit metrics structure for the glyph image.   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.  Returns an error if no     */
+  /*    glyph sbit exists for the index.                                   */
+  /*                                                                       */
+  /*  <Note>                                                               */
+  /*    The `map.buffer' field is always freed before the glyph is loaded. */
+  /*                                                                       */
+  typedef  
+  TT_Error  (*TT_Load_SBit_Image_Func)( TT_Face           face,
+                                        TT_Int            x_ppem,
+                                        TT_Int            y_ppem,
+                                        TT_UInt           glyph_index,
+                                        FT_Stream         stream,
+                                        FT_Bitmap*        map,
+                                        TT_SBit_Metrics*  metrics );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_Get_PS_Name_Func                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Gets the PostScript glyph name of a glyph.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    index  :: The glyph index.                                         */
+  /*                                                                       */
+  /*    PSname :: The address of a string pointer.  Will be NULL in case   */
+  /*              of error, otherwise it is a pointer to the glyph name.   */
+  /*                                                                       */
+  /*              You must not modify the returned string!                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef
+  TT_Error (*TT_Get_PS_Name_Func)( TT_Face      face,
+                                   TT_UInt      index,
+                                   TT_String**  PSname );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_Load_Metrics                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal or vertical header in a face object.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face     :: A handle to the target face object.                    */
+  /*    stream   :: The input stream.                                      */
+  /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef
+  TT_Error  (*TT_Load_Metrics_Func)( TT_Face    face,
+                                     FT_Stream  stream,
+                                     TT_Bool    vertical );
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_CharMap_Load_Func                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given TrueType character map into memory.                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the parent face object.                      */
+  /*    stream :: A handle to the current stream object.                   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    cmap   :: A pointer to a cmap object.                              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The function assumes that the stream is already in use (i.e.,      */
+  /*    opened).  In case of error, all partially allocated tables are     */
+  /*    released.                                                          */
+  /*                                                                       */
+  typedef
+  TT_Error  (*TT_CharMap_Load_Func)( TT_Face        face,
+                                     TT_CMapTable*  cmap,
+                                     FT_Stream      input );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_CharMap_Free_Func                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a character mapping table.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the parent face object.                        */
+  /*    cmap :: A handle to a cmap object.                                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  typedef
+  TT_Error  (*TT_CharMap_Free_Func)( TT_Face        face,
+                                     TT_CMapTable*  cmap );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_Load_Table                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given TrueType table.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The function will use `face->goto_table' to seek the stream to     */
+  /*    the start of the table                                             */
+  /*                                                                       */
+  typedef
+  TT_Error  (*TT_Load_Table_Func)( TT_Face    face,
+                                   FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_Load_Table                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given TrueType table.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The function will use `face->goto_table' to seek the stream to     */
+  /*    the start of the table                                             */
+  /*                                                                       */
+  typedef
+  void  (*TT_Free_Table_Func)( TT_Face  face );
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    SFNT_Interface                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    this structure holds pointers to the functions used to load and    */
+  /*    free the basic tables that are required in a `sfnt' font file.     */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*                                                                       */
+  /*                                                                       */
+  /*                                                                       */
+  /*                                                                       */
+  /*                                                                       */
+  /*                                                                       */
+  /*                                                                       */
+  /*                                                                       */
+  typedef struct  SFNT_Interface_
+  {
+    TT_Goto_Table_Func      goto_table;
+  
+    TT_Load_Any_Func        load_any;
+    TT_Load_Directory_Func  load_directory;
+
+    TT_Load_Table_Func      load_header;
+    TT_Load_Metrics_Func    load_metrics;
+    TT_Load_Table_Func      load_charmaps;
+    TT_Load_Table_Func      load_max_profile;
+    TT_Load_Table_Func      load_os2;
+    TT_Load_Table_Func      load_psnames;
+
+    TT_Load_Table_Func      load_names;
+    TT_Free_Table_Func      free_names;
+
+    /* optional tables */
+    TT_Load_Table_Func      load_hdmx;
+    TT_Free_Table_Func      free_hdmx;
+
+    TT_Load_Table_Func      load_kerning;
+    TT_Load_Table_Func      load_gasp;
+
+
+    /* see `ttsbit.h' */
+    TT_Load_Table_Func      load_sbits;
+    TT_Load_SBit_Image_Func load_sbit_image;
+    TT_Free_Table_Func      free_sbits;
+    
+    /* see `ttpost.h' */
+    TT_Get_PS_Name_Func     get_psname;
+    TT_Free_Table_Func      free_psnames;
+
+    /* see `ttcmap.h' */
+    TT_CharMap_Load_Func    load_charmap;
+    TT_CharMap_Free_Func    free_charmap;
+    
+  } SFNT_Interface;
+
+#endif /* SFNT_H */
+
+
+/* END */
diff --git a/src/shared/sfnt/rules.mk b/src/shared/sfnt/rules.mk
new file mode 100644
index 0000000..e8ab1f7
--- /dev/null
+++ b/src/shared/sfnt/rules.mk
@@ -0,0 +1,58 @@
+#****************************************************************************
+#*                                                                          *
+#*  SFNT/TrueType Makefile                                                  *
+#*                                                                          *
+#*  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.                                         *
+#*                                                                          *
+#****************************************************************************
+
+
+#****************************************************************************
+#*                                                                          *
+#*  IMPORTANT NOTE: This Makefile is intended for GNU Make!                 *
+#*                  If you provide Makefiles for other make utilities,      *
+#*                  please place them in `freetype/lib/arch/<system>'.      *
+#*                                                                          *
+#*                                                                          *
+#*  This file is to be included by the Makefiles of each driver that uses   *
+#*  the shared source code in `freetype2/lib/drivers/sfnt'.  This code      *
+#*  contains type definitions as well as interface which are common to all  *
+#*  `sfnt' font formats (i.e., TrueType, OpenType-TTF, and OpenType-CFF).   *
+#*                                                                          *
+#*                                                                          *
+#*  The purpose of this Makefile is to define two make variables that are   *
+#*  used directly by the parent Makefile.                                   *
+#*                                                                          *
+#****************************************************************************
+
+
+# SFNT_DIR is the directory to the `sfnt' sources
+#
+SFNT_DIR  := $(SRC)$(SEP)shared$(SEP)sfnt
+SFNT_DIR_ := $(SFNT_DIR)$(SEP)
+
+
+# SFNT_H is the list of all header files on which the client drivers depend
+#
+SFNT_H := $(SFNT_DIR_)tttypes.h  \
+          $(SFNT_DIR_)ttload.h   \
+          $(SFNT_DIR_)ttsbit.h   \
+          $(SFNT_DIR_)ttpost.h   \
+          $(SFNT_DIR_)sfnt.h
+
+# SFNT_SRC is the list of all shared source files that are included by any
+# client driver
+#
+SFNT_SRC := $(SFNT_DIR_)ttload.c  \
+            $(SFNT_DIR_)ttsbit.c  \
+            $(SFNT_DIR_)ttpost.c
+
+
+# END
diff --git a/src/shared/sfnt/sfnt.h b/src/shared/sfnt/sfnt.h
new file mode 100644
index 0000000..f1bc9c5
--- /dev/null
+++ b/src/shared/sfnt/sfnt.h
@@ -0,0 +1,50 @@
+/***************************************************************************/
+/*                                                                         */
+/*  sfnt.h                                                                 */
+/*                                                                         */
+/*    Defines the function interface used to access SFNT files, i.e.,      */
+/*    TrueType, OpenType-TT, and OpenType-T2 files (specification only).   */
+/*                                                                         */
+/*  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 SFNT_H
+#define SFNT_H
+
+#include <tttypes.h>
+
+
+  typedef TT_Long  (*SFNT_LookUp_Table)( TT_Face   face,
+                                         TT_ULong  tag );
+
+
+  typedef TT_Error  (*SFNT_Load_Table)( TT_Face    face,
+                                        TT_ULong   tag,
+                                        TT_Long    offset,
+                                        void*      buffer,
+                                        TT_Long*   length );
+
+  typedef TT_Error  (*SFNT_Get_PS_Name)( TT_Face      face,
+                                         TT_UShort    index,
+                                         TT_String*  *ps_name );
+
+  typedef struct  SFNT_Interface_
+  {
+    SFNT_LookUp_Table   lookup_table;
+    SFNT_Load_Table     load_table;
+
+  } SFNT_Interface;
+
+
+#endif /* SFNT_H */
+
+
+/* END */
diff --git a/src/shared/sfnt/ttload.c b/src/shared/sfnt/ttload.c
new file mode 100644
index 0000000..e18b52b
--- /dev/null
+++ b/src/shared/sfnt/ttload.c
@@ -0,0 +1,1488 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttload.c                                                               */
+/*                                                                         */
+/*    TrueType tables loader (body).                                       */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/*                                                                         */
+/*  WARNING: This file should not be compiled directly; it is meant to be  */
+/*           included in the source of several font drivers (i.e., the TTF */
+/*           and OTF drivers).                                             */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ftdebug.h>
+
+#include <ttload.h>
+#include <tttags.h>
+#include <ttcmap.h>
+
+
+/* required by the tracing mode */
+#undef  FT_COMPONENT
+#define FT_COMPONENT      trace_ttload
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_LookUp_Table                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Looks for a TrueType table by name.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A face object handle.                                      */
+  /*    tag  :: The  searched tag.                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Index of table if found, -1 otherwise.                             */
+  /*                                                                       */
+  EXPORT_FUNC
+  FT_Long  TT_LookUp_Table( TT_Face   face,
+                            TT_ULong  tag  )
+  {
+    TT_Long  i, found;
+
+
+    FT_TRACE4(( "TT_LookUp_Table( %08lx, %c%c%c%c )\n",
+                  (TT_Long)face,
+                  (TT_Char)(tag >> 24),
+                  (TT_Char)(tag >> 16),
+                  (TT_Char)(tag >> 8),
+                  (TT_Char)(tag) ));
+
+    found = -1;
+    for ( i = 0; i < face->num_tables; i++ )
+      if ( face->dir_tables[i].Tag == tag )
+      {
+        found = i;
+        break;
+      }
+
+    if ( found == -1 )
+    {
+      FT_TRACE4(( "    Could not find table!\n" ));
+    }
+
+    return found;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Collection                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the TTC table directory into face table.                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A face object handle.                                    */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  TT_Load_Collection( TT_Face    face,
+                                FT_Stream  stream )
+  {
+    TT_Long    n;
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+
+    FT_TRACE3(( "TT_Load_Collection( %08lx )\n", (TT_Long)face ));
+
+    if ( FILE_Seek   ( 0L )  ||
+         ACCESS_Frame( 12L ) )
+      goto Exit;
+
+    face->ttc_header.Tag      = GET_Tag4();
+    face->ttc_header.version  = GET_Long();
+    face->ttc_header.DirCount = GET_Long(); /* see comment in tttypes.h */
+
+    FORGET_Frame();
+
+    if ( face->ttc_header.Tag != TTAG_ttcf )
+    {
+      face->ttc_header.Tag      = 0;
+      face->ttc_header.version  = 0;
+      face->ttc_header.DirCount = 0;
+
+      face->ttc_header.TableDirectory = NULL;
+
+      FT_TRACE3(( "skipped.\n" ));
+
+      error = TT_Err_File_Is_Not_Collection;
+      goto Exit;
+    }
+
+    if ( ALLOC_ARRAY( face->ttc_header.TableDirectory,
+                      face->ttc_header.DirCount,
+                      TT_ULong )                        ||
+         ACCESS_Frame( face->ttc_header.DirCount * 4L ) )
+      goto Exit;
+
+    for ( n = 0; n < face->ttc_header.DirCount; n++ )
+      face->ttc_header.TableDirectory[n] = GET_ULong();
+
+    FORGET_Frame();
+
+    FT_TRACE3(( "collections directory loaded.\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Directory                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the table directory into a face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face      :: A handle to the target face object.                   */
+  /*    stream    :: The input stream.                                     */
+  /*    faceIndex :: The index of the TrueType font, if we're opening a    */
+  /*                 collection.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Directory( TT_Face    face,
+                               FT_Stream  stream,
+                               TT_Long    faceIndex )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_UShort    n, limit;
+    TT_TableDir  tableDir;
+
+    TT_TableDirEntry*  entry;
+
+
+    FT_TRACE2(( "TT_Load_Directory( %08lx, %ld )\n",
+              (TT_Long)face, faceIndex ));
+
+    error = TT_Load_Collection( face, stream );
+    if ( error )
+    {
+      /* if this is a `traditional' error, exit now */
+      if ( error != TT_Err_File_Is_Not_Collection )
+        goto Exit;
+
+      /* the file isn't a collection, exit if we're asking */
+      /* for a collected font                              */
+
+      /* Note that we don't exit during font format checking (i.e., */
+      /* faceIndex is -1)                                           */
+      if ( faceIndex > 0 )
+        goto Exit;
+
+      /* Now skip to the beginning of the file */
+      if ( FILE_Seek( 0 ) )
+        goto Exit;
+    }
+    else
+    {
+      /* The file is a collection. Check the font index */
+      if ( faceIndex >= face->ttc_header.DirCount )
+      {
+        error = TT_Err_Bad_Argument;
+        goto Exit;
+      }
+
+      /* if we're checking the font format, exit immediately */
+      if ( faceIndex < 0 )
+        goto Exit;
+
+      /* select a TrueType font in the ttc file   */
+      if ( FILE_Seek( face->ttc_header.TableDirectory[faceIndex] ) )
+        goto Exit;
+    }
+
+    if ( ACCESS_Frame( 12L ) )
+      goto Exit;
+
+    tableDir.version   = GET_Long();
+    tableDir.numTables = GET_UShort();
+
+    tableDir.searchRange   = GET_UShort();
+    tableDir.entrySelector = GET_UShort();
+    tableDir.rangeShift    = GET_UShort();
+
+    FORGET_Frame();
+
+    FT_TRACE2(( "-- Tables count   : %12u\n",  tableDir.numTables ));
+    FT_TRACE2(( "-- Format version : %08lx\n", tableDir.version ));
+
+    /* Check that we have a `sfnt' format there                        */
+    /* We must also be able to accept Mac/GX fonts, as well as OT ones */
+
+    if ( tableDir.version != 0x00010000 &&
+         tableDir.version != TTAG_true  &&
+         tableDir.version != TTAG_OTTO  )
+    {
+      FT_TRACE2(( "[not a valid TTF or OTF font]" ));
+      error = TT_Err_Invalid_File_Format;
+      goto Exit;
+    }
+
+    /* if we're performing a font format check, exit immediately */
+    /* with success                                              */
+    if ( faceIndex < 0 )
+      goto Exit;
+
+    face->num_tables = tableDir.numTables;
+
+    if ( ALLOC_ARRAY( face->dir_tables,
+                      face->num_tables,
+                      TT_TableDirEntry ) )
+      goto Exit;
+
+    if ( ACCESS_Frame( face->num_tables * 16L ) )
+      goto Exit;
+
+    limit = face->num_tables;
+    entry = face->dir_tables;
+
+    for ( n = 0; n < limit; n++ )
+    {                      /* loop through the tables and get all entries */
+      entry->Tag      = GET_Tag4();
+      entry->CheckSum = GET_ULong();
+      entry->Offset   = GET_Long();
+      entry->Length   = GET_Long();
+
+      FT_TRACE2(( "  %c%c%c%c  -  %08lx  -  %08lx\n",
+                (TT_Char)(entry->Tag >> 24),
+                (TT_Char)(entry->Tag >> 16),
+                (TT_Char)(entry->Tag >> 8 ),
+                (TT_Char)(entry->Tag),
+                entry->Offset,
+                entry->Length ));
+      entry++;
+    }
+
+    FORGET_Frame();
+
+    FT_TRACE2(( "Directory loaded\n\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Any                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads any font table into client memory.  Used by the              */
+  /*    TT_Get_Font_Data() API function.                                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: The face object to look for.                             */
+  /*                                                                       */
+  /*    tag    :: The tag of table to load.  Use the value 0 if you  want  */
+  /*              to access the whole font file, else set this parameter   */
+  /*              to a valid TrueType table tag that you can forge with    */
+  /*              the MAKE_TT_TAG macro.                                   */
+  /*                                                                       */
+  /*    offset :: The starting offset in the table (or the file if         */
+  /*              tag == 0).                                               */
+  /*                                                                       */
+  /*    length :: The address of the decision variable:                    */
+  /*                                                                       */
+  /*                If length == NULL:                                     */
+  /*                  Loads the whole table.  Returns an error if          */
+  /*                  `offset' == 0!                                       */
+  /*                                                                       */
+  /*                If *length == 0:                                       */
+  /*                  Exits immediately; returning the length of the given */
+  /*                  table or of the font file, depending on the value of */
+  /*                  `tag'.                                               */
+  /*                                                                       */
+  /*                If *length != 0:                                       */
+  /*                  Loads the next `length' bytes of table or font,      */
+  /*                  starting at offset `offset' (in table or font too).  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    buffer :: The address of target buffer.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Any( TT_Face   face,
+                         TT_ULong  tag,
+                         TT_Long   offset,
+                         void*     buffer,
+                         TT_Long*  length )
+  {
+    TT_Error   error;
+    FT_Stream  stream;
+    TT_Long    table;
+    TT_ULong   size;
+
+
+    if ( tag != 0 )
+    {
+      /* look for tag in font directory */
+      table = TT_LookUp_Table( face, tag );
+      if ( table < 0 )
+      {
+        error = TT_Err_Table_Missing;
+        goto Exit;
+      }
+
+      offset += face->dir_tables[table].Offset;
+      size    = face->dir_tables[table].Length;
+    }
+    else
+    /* tag = 0 -- the use want to access the font file directly */
+    {
+      size = face->root.stream->size;
+    }
+
+    if ( length && *length == 0 )
+    {
+      *length = size;
+
+      return TT_Err_Ok;
+    }
+
+    if ( length )
+      size = *length;
+
+    stream = face->root.stream;
+    (void)FILE_Read_At( offset, buffer, size );
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Header                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the TrueType font header.                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Header( TT_Face    face,
+                            FT_Stream  stream )
+  {
+    TT_Error  error;
+
+    TT_Long     table;
+    TT_Header*  header;
+
+
+    FT_TRACE2(( "Load_TT_Header( %08lx )\n", (TT_Long)face ));
+
+    if ( ( table = TT_LookUp_Table( face, TTAG_head ) ) < 0 )
+    {
+      FT_TRACE0(( "Font Header is missing!\n" ));
+      error = TT_Err_Header_Table_Missing;
+
+      goto Exit;
+    }
+
+    if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+         ACCESS_Frame( 54L ) )
+      goto Exit;
+
+    header = &face->header;
+
+    header->Table_Version = GET_ULong();
+    header->Font_Revision = GET_ULong();
+
+    header->CheckSum_Adjust = GET_Long();
+    header->Magic_Number    = GET_Long();
+
+    header->Flags        = GET_UShort();
+    header->Units_Per_EM = GET_UShort();
+
+    header->Created [0] = GET_Long();
+    header->Created [1] = GET_Long();
+    header->Modified[0] = GET_Long();
+    header->Modified[1] = GET_Long();
+
+    header->xMin = GET_Short();
+    header->yMin = GET_Short();
+    header->xMax = GET_Short();
+    header->yMax = GET_Short();
+
+    header->Mac_Style       = GET_UShort();
+    header->Lowest_Rec_PPEM = GET_UShort();
+
+    header->Font_Direction      = GET_Short();
+    header->Index_To_Loc_Format = GET_Short();
+    header->Glyph_Data_Format   = GET_Short();
+
+    FORGET_Frame();
+
+    FT_TRACE2(( "    Units per EM : %8u\n", header->Units_Per_EM ));
+    FT_TRACE2(( "    IndexToLoc   : %8d\n", header->Index_To_Loc_Format ));
+    FT_TRACE2(( "Font Header Loaded.\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_MaxProfile                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the maximum profile into a face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_MaxProfile( TT_Face    face,
+                                FT_Stream  stream )
+  {
+    TT_Error  error;
+
+    TT_Long         i;
+    TT_MaxProfile*  maxProfile = &face->max_profile;
+
+
+    FT_TRACE2(( "Load_TT_MaxProfile( %08lx )\n", (TT_Long)face ));
+
+    if ( ( i = TT_LookUp_Table( face, TTAG_maxp ) ) < 0 )
+    {
+      error = TT_Err_Max_Profile_Missing;
+
+      goto Exit;
+    }
+
+    if ( FILE_Seek( face->dir_tables[i].Offset ) ||
+         ACCESS_Frame( 32L )                    )
+      goto Exit;
+
+    /* read frame data into face table */
+    maxProfile->version               = GET_ULong();
+    maxProfile->numGlyphs             = GET_UShort();
+
+    maxProfile->maxPoints             = GET_UShort();
+    maxProfile->maxContours           = GET_UShort();
+    maxProfile->maxCompositePoints    = GET_UShort();
+    maxProfile->maxCompositeContours  = GET_UShort();
+
+    maxProfile->maxZones              = GET_UShort();
+    maxProfile->maxTwilightPoints     = GET_UShort();
+
+    maxProfile->maxStorage            = GET_UShort();
+    maxProfile->maxFunctionDefs       = GET_UShort();
+    maxProfile->maxInstructionDefs    = GET_UShort();
+    maxProfile->maxStackElements      = GET_UShort();
+    maxProfile->maxSizeOfInstructions = GET_UShort();
+    maxProfile->maxComponentElements  = GET_UShort();
+    maxProfile->maxComponentDepth     = GET_UShort();
+
+    FORGET_Frame();
+
+    /* XXX: an adjustment that is necessary to load certain */
+    /*       broken fonts like `Keystrokes MT' :-(          */
+    /*                                                      */
+    /*   We allocate 64 function entries by default when    */
+    /*   the maxFunctionDefs field is null.                 */
+
+    if ( maxProfile->maxFunctionDefs == 0 )
+      maxProfile->maxFunctionDefs = 64;
+
+    face->root.num_glyphs = maxProfile->numGlyphs;
+
+    face->root.max_points = MAX( maxProfile->maxCompositePoints,
+                                 maxProfile->maxPoints );
+
+    face->root.max_contours = MAX( maxProfile->maxCompositeContours,
+                                   maxProfile->maxContours );
+
+    face->max_components = (TT_ULong)maxProfile->maxComponentElements +
+                           maxProfile->maxComponentDepth;
+
+    FT_TRACE2(( "GASP loaded.\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Metrics                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal or vertical metrics table into a face object. */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face     :: A handle to the target face object.                    */
+  /*    stream   :: The input stream.                                      */
+  /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  TT_Load_Metrics( TT_Face    face,
+                             FT_Stream  stream,
+                             TT_Bool    vertical )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_UShort          n, num_shorts, num_longs;
+    TT_Long            table;
+
+    TT_LongMetrics**   longs;
+    TT_ShortMetrics**  shorts;
+
+    TT_LongMetrics*    long_metric;
+
+    FT_TRACE2(( "TT_Load_%s_Metrics( %08lx )\n",
+              vertical ? "Vertical" : "Horizontal", (TT_Long)face ));
+
+    if ( vertical )
+    {
+      /* The table is optional, quit silently if it wasn't found       */
+      /* XXX: Some fonts have a valid vertical header with a non-null  */
+      /*      `number_of_VMetrics' fields, but no corresponding `vmtx' */
+      /*      table to get the metrics from (e.g. mingliu).            */
+      /*                                                               */
+      /*      For safety, we set the field to 0!                       */
+      /*                                                               */
+      table = TT_LookUp_Table( face, TTAG_vmtx );
+      if ( table < 0 )
+      {
+        /* Set the number_Of_VMetrics to 0! */
+        FT_TRACE2(( "  no vertical header in file.\n" ));
+        face->vertical.number_Of_VMetrics = 0;
+        error = TT_Err_Ok;
+
+        goto Exit;
+      }
+
+      num_longs = face->vertical.number_Of_VMetrics;
+      longs     = (TT_LongMetrics**)&face->vertical.long_metrics;
+      shorts    = (TT_ShortMetrics**)&face->vertical.short_metrics;
+    }
+    else
+    {
+      if ( ( table = TT_LookUp_Table( face, TTAG_hmtx ) ) < 0 )
+      {
+        FT_ERROR(( " no horizontal metrics in file!\n" ));
+        error = TT_Err_Hmtx_Table_Missing;
+
+        goto Exit;
+      }
+
+      num_longs = face->horizontal.number_Of_HMetrics;
+      longs     = (TT_LongMetrics**)&face->horizontal.long_metrics;
+      shorts    = (TT_ShortMetrics**)&face->horizontal.short_metrics;
+    }
+
+    num_shorts = face->max_profile.numGlyphs - num_longs;
+
+    if ( num_longs > face->max_profile.numGlyphs )  /* sanity check */
+    {
+      FT_ERROR(( " more metrics than glyphs!\n" ));
+      error = TT_Err_Invalid_Horiz_Metrics;
+
+      goto Exit;
+    }
+
+    if ( ALLOC_ARRAY( *longs,  num_longs,  TT_LongMetrics ) ||
+         ALLOC_ARRAY( *shorts, num_shorts, TT_ShortMetrics ) )
+      goto Exit;
+
+    if ( FILE_Seek( face->dir_tables[table].Offset )   ||
+         ACCESS_Frame( face->dir_tables[table].Length ) )
+      goto Exit;
+
+    long_metric = *longs;
+    for ( n = 0; n < num_longs; n++ )
+    {
+      long_metric->advance = GET_UShort();
+      long_metric->bearing = GET_Short();
+      long_metric++;
+    }
+
+    for ( n = 0; n < num_shorts; n++ )
+      (*shorts)[n] = GET_Short();
+
+    FORGET_Frame();
+
+    FT_TRACE2(( "loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Metrics_Header                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal or vertical header in a face object.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face     :: A handle to the target face object.                    */
+  /*    stream   :: The input stream.                                      */
+  /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Metrics_Header( TT_Face    face,
+                                    FT_Stream  stream,
+                                    TT_Bool    vertical )
+  {
+    TT_Error  error;
+
+    TT_Long         table;
+    TT_HoriHeader*  header;
+
+
+    FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " ));
+
+    if ( vertical )
+    {
+      face->vertical_info = 0;
+
+      /* The vertical header table is optional, so return quietly if */
+      /* we don't find it.                                           */
+      if ( ( table = TT_LookUp_Table( face, TTAG_vhea ) ) < 0 )
+      {
+        error = TT_Err_Ok;
+
+        goto Exit;
+      }
+
+      face->vertical_info = 1;
+      header = (TT_HoriHeader*)&face->vertical;
+    }
+    else
+    {
+      /* The horizontal header is mandatory, return an error if we */
+      /* don't find it.                                            */
+      if ( ( table = TT_LookUp_Table( face, TTAG_hhea ) ) < 0 )
+      {
+        error = TT_Err_Horiz_Header_Missing;
+
+        goto Exit;
+      }
+
+      header = &face->horizontal;
+    }
+
+    if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+         ACCESS_Frame( 36L ) )
+      goto Exit;
+
+    header->Version   = GET_ULong();
+    header->Ascender  = GET_Short();
+    header->Descender = GET_Short();
+    header->Line_Gap  = GET_Short();
+
+    header->advance_Width_Max = GET_UShort();
+
+    header->min_Left_Side_Bearing  = GET_Short();
+    header->min_Right_Side_Bearing = GET_Short();
+    header->xMax_Extent            = GET_Short();
+    header->caret_Slope_Rise       = GET_Short();
+    header->caret_Slope_Run        = GET_Short();
+
+    header->Reserved[0] = GET_Short();
+    header->Reserved[1] = GET_Short();
+    header->Reserved[2] = GET_Short();
+    header->Reserved[3] = GET_Short();
+    header->Reserved[4] = GET_Short();
+
+    header->metric_Data_Format = GET_Short();
+    header->number_Of_HMetrics = GET_UShort();
+
+    FORGET_Frame();
+
+    header->long_metrics  = NULL;
+    header->short_metrics = NULL;
+
+    FT_TRACE2(( "loaded\n" ));
+
+    /* Now try to load the corresponding metrics */
+
+    error = TT_Load_Metrics( face, stream, vertical );
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the name records.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Names( TT_Face  face, FT_Stream  stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_UShort  i;
+    TT_Long    table;
+    TT_Long    storageSize;
+
+    TT_NameTable*  names;
+    TT_NameRec*    namerec;
+
+
+    FT_TRACE2(( "Names " ));
+
+    if ( ( table = TT_LookUp_Table( face, TTAG_name ) ) < 0 )
+    {
+      /* The name table is required so indicate failure. */
+      FT_TRACE2(( "is missing!\n" ));
+      error = TT_Err_Name_Table_Missing;
+
+      goto Exit;
+    }
+
+    /* Seek to the beginning of the table and check the frame access. */
+    /* The names table has a 6 byte header.                           */
+    if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+         ACCESS_Frame( 6L ) )
+      goto Exit;
+
+    names = &face->name_table;
+
+    /* Load the initial names data. */
+    names->format         = GET_UShort();
+    names->numNameRecords = GET_UShort();
+    names->storageOffset  = GET_UShort();
+
+    FORGET_Frame();
+
+    /* Allocate the array of name records. */
+    if ( ALLOC_ARRAY( names->names,
+                      names->numNameRecords,
+                      TT_NameRec )                   ||
+         ACCESS_Frame( names->numNameRecords * 12L ) )
+      goto Exit;
+
+    /* Load the name records and determine how much storage is needed */
+    /* to hold the strings themselves.                                */
+    namerec     = names->names;
+    storageSize = 0;
+
+    for ( i = 0; i < names->numNameRecords; i++, namerec++ )
+    {
+      TT_Long  upper;
+
+
+      namerec->platformID   = GET_UShort();
+      namerec->encodingID   = GET_UShort();
+      namerec->languageID   = GET_UShort();
+      namerec->nameID       = GET_UShort();
+      namerec->stringLength = GET_UShort();
+      namerec->stringOffset = GET_UShort();
+
+      upper = namerec->stringOffset + namerec->stringLength;
+      if ( upper > storageSize ) storageSize = upper;
+    }
+
+    FORGET_Frame();
+
+    if ( ALLOC( names->storage, storageSize )  ||
+         FILE_Read_At( face->dir_tables[table].Offset + names->storageOffset,
+                       (void*)names->storage, storageSize ) )
+      goto Exit;
+
+    /* Go through and assign the string pointers to the name records. */
+    namerec = names->names;
+    for ( i = 0; i < names->numNameRecords; i++, namerec++ )
+      namerec->string = names->storage + namerec->stringOffset;
+
+    /* Print Name Record Table in case of debugging */
+#if 0
+    namerec = names->names;
+    for ( i = 0; i < names->numNameRecords; i++, namerec++ )
+    {
+      TT_UShort  j;
+
+
+      FT_TRACE2(( "%d %d %x %d ",
+                   namerec->platformID,
+                   namerec->encodingID,
+                   namerec->languageID,
+                   namerec->nameID ));
+
+      /* I know that M$ encoded strings are Unicode,            */
+      /* but this works reasonable well for debugging purposes. */
+      if ( namerec->string )
+        for ( j = 0; j < namerec->stringLength; j++ )
+        {
+          TT_Char  c = *(namerec->string + j);
+
+          if ( (TT_Byte)c < 128 )
+            FT_TRACE2(( "%c", c ));
+        }
+    }
+    FT_TRACE2(( "\n" ));
+#endif
+
+    FT_TRACE2(( "loaded\n" ));
+
+  Exit:
+    return error;
+
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Frees the name records.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target face object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Free_Names( TT_Face  face )
+  {
+    FT_Memory      memory = face->root.driver->memory;
+    TT_NameTable*  names  = &face->name_table;
+
+
+    /* free strings table */
+    FREE( names->names );
+
+    /* free strings storage */
+    FREE( names->storage );
+
+    names->numNameRecords = 0;
+    names->format         = 0;
+    names->storageOffset  = 0;
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_CMap                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the cmap directory in a face object.  The cmaps itselves are */
+  /*    loaded on demand in the `ttcmap.c' module.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face    :: A handle to the target face object.                     */
+  /*    stream  :: A handle to the input stream.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*     TrueType error code.  0 means success.                            */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_CMap( TT_Face    face,
+                          FT_Stream  stream )
+  {
+    TT_Error  error;
+    FT_Memory memory = stream->memory;
+
+    TT_Long    i, off, cur_off, table_start;
+    TT_UShort  n, limit;
+
+    TT_CMapDir        cmap_dir;
+    TT_CharMap        charmap;
+    TT_CMapTable*     cmap;
+
+
+    FT_TRACE2(( "CMaps " ));
+
+    if ( ( i = TT_LookUp_Table( face, TTAG_cmap ) ) < 0 )
+    {
+      error = TT_Err_CMap_Table_Missing;
+
+      goto Exit;
+    }
+
+    table_start = face->dir_tables[i].Offset;
+
+    if ( ( FILE_Seek( table_start ) ) ||
+         ( ACCESS_Frame( 4L ) ) )           /* 4 bytes cmap header */
+      goto Exit;
+
+    cmap_dir.tableVersionNumber = GET_UShort();
+    cmap_dir.numCMaps           = GET_UShort();
+
+    FORGET_Frame();
+
+    off = FILE_Pos();  /* save offset to cmapdir[] which follows */
+
+    /* save space in face table for cmap tables */
+    if ( ALLOC_ARRAY( face->charmaps,
+                      cmap_dir.numCMaps,
+                      TT_CharMapRec ) )
+      goto Exit;
+
+    face->num_charmaps = cmap_dir.numCMaps;
+
+    limit   = face->num_charmaps;
+    charmap = face->charmaps;
+
+    for ( n = 0; n < limit; n++ )
+    {
+      charmap->root.face = (FT_Face)face;
+      cmap               = &charmap->cmap;
+
+      if ( FILE_Seek( off )  ||
+           ACCESS_Frame( 8L ) )
+        goto Exit;
+
+      cmap->loaded             = FALSE;
+      cmap->platformID         = GET_UShort();
+      cmap->platformEncodingID = GET_UShort();
+
+      cur_off = GET_Long();
+
+      FORGET_Frame();
+
+      off = FILE_Pos();
+
+      if ( FILE_Seek( table_start + cur_off ) ||
+           ACCESS_Frame( 6L ) )
+        goto Exit;
+
+      cmap->format  = GET_UShort();
+      cmap->length  = GET_UShort();
+      cmap->version = GET_UShort();
+
+      FORGET_Frame();
+
+      cmap->offset = FILE_Pos();
+
+      charmap++;
+    }
+
+    FT_TRACE2(( "loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_OS2                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the OS2 table.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_OS2( TT_Face    face,
+                         FT_Stream  stream )
+  {
+    TT_Error  error;
+
+    TT_Long   i;
+    TT_Int    j;
+    TT_OS2*   os2;
+
+
+    FT_TRACE2(( "OS/2 Table " ));
+
+    /* We now support old Mac fonts where the OS/2 table doesn't  */
+    /* exist.  Simply put, we set the `version' field to 0xFFFF   */
+    /* and test this value each time we need to access the table. */
+    if ( ( i = TT_LookUp_Table( face, TTAG_OS2 ) ) < 0 )
+    {
+      FT_TRACE2(( "is missing\n!" ));
+        face->os2.version = 0xFFFF;
+      error = TT_Err_Ok;
+
+      goto Exit;
+    }
+
+    if ( FILE_Seek( face->dir_tables[i].Offset ) ||
+         ACCESS_Frame( 78L ) )
+      goto Exit;
+
+    os2 = &face->os2;
+
+    os2->version             = GET_UShort();
+    os2->xAvgCharWidth       = GET_Short();
+    os2->usWeightClass       = GET_UShort();
+    os2->usWidthClass        = GET_UShort();
+    os2->fsType              = GET_Short();
+    os2->ySubscriptXSize     = GET_Short();
+    os2->ySubscriptYSize     = GET_Short();
+    os2->ySubscriptXOffset   = GET_Short();
+    os2->ySubscriptYOffset   = GET_Short();
+    os2->ySuperscriptXSize   = GET_Short();
+    os2->ySuperscriptYSize   = GET_Short();
+    os2->ySuperscriptXOffset = GET_Short();
+    os2->ySuperscriptYOffset = GET_Short();
+    os2->yStrikeoutSize      = GET_Short();
+    os2->yStrikeoutPosition  = GET_Short();
+    os2->sFamilyClass        = GET_Short();
+
+    for ( j = 0; j < 10; j++ )
+      os2->panose[j] = GET_Byte();
+
+    os2->ulUnicodeRange1     = GET_ULong();
+    os2->ulUnicodeRange2     = GET_ULong();
+    os2->ulUnicodeRange3     = GET_ULong();
+    os2->ulUnicodeRange4     = GET_ULong();
+
+    for ( j = 0; j < 4; j++ )
+      os2->achVendID[j] = GET_Byte();
+
+    os2->fsSelection         = GET_UShort();
+    os2->usFirstCharIndex    = GET_UShort();
+    os2->usLastCharIndex     = GET_UShort();
+    os2->sTypoAscender       = GET_Short();
+    os2->sTypoDescender      = GET_Short();
+    os2->sTypoLineGap        = GET_Short();
+    os2->usWinAscent         = GET_UShort();
+    os2->usWinDescent        = GET_UShort();
+
+    FORGET_Frame();
+
+    if ( os2->version >= 0x0001 )
+    {
+      /* only version 1 tables */
+
+      if ( ACCESS_Frame( 8L ) )  /* read into frame */
+        goto Exit;
+
+      os2->ulCodePageRange1 = GET_ULong();
+      os2->ulCodePageRange2 = GET_ULong();
+
+      FORGET_Frame();
+    }
+    else
+    {
+      os2->ulCodePageRange1 = 0;
+      os2->ulCodePageRange2 = 0;
+    }
+
+    FT_TRACE2(( "loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Postscript                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the Postscript table.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_PostScript( TT_Face    face,
+                                FT_Stream  stream )
+  {
+    TT_Error        error;
+    TT_Long         i;
+    TT_Postscript*  post = &face->postscript;
+
+
+    FT_TRACE2(( "PostScript " ));
+
+    if ( ( i = TT_LookUp_Table( face, TTAG_post ) ) < 0 )
+      return TT_Err_Post_Table_Missing;
+
+    if ( FILE_Seek( face->dir_tables[i].Offset ) ||
+         ACCESS_Frame( 32L ) )
+      return error;
+
+    /* read frame data into face table */
+
+    post->FormatType         = GET_ULong();
+    post->italicAngle        = GET_ULong();
+    post->underlinePosition  = GET_Short();
+    post->underlineThickness = GET_Short();
+    post->isFixedPitch       = GET_ULong();
+    post->minMemType42       = GET_ULong();
+    post->maxMemType42       = GET_ULong();
+    post->minMemType1        = GET_ULong();
+    post->maxMemType1        = GET_ULong();
+
+    FORGET_Frame();
+
+    /* we don't load the glyph names, we do that in another */
+    /* module (ttpost).                                     */
+
+    FT_TRACE2(( "loaded\n" ));
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Gasp                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the `GASP' table into a face object.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Gasp( TT_Face    face,
+                          FT_Stream  stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_Long        table;
+    TT_UShort      num_ranges;
+    TT_UShort      j;
+    TT_GaspRange*  gaspranges;
+
+
+    FT_TRACE2(( "TT_Load_Gasp( %08lx )\n", (TT_Long)face ));
+
+    error = TT_Err_Ok;
+
+    /* the gasp table is optional */
+    if ( ( table = TT_LookUp_Table( face, TTAG_gasp ) ) < 0 )
+      goto Exit;
+
+    if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+         ACCESS_Frame( 4L ) )
+      goto Exit;
+
+    face->gasp.version   = GET_UShort();
+    face->gasp.numRanges = GET_UShort();
+
+    FORGET_Frame();
+
+    num_ranges = face->gasp.numRanges;
+    FT_TRACE3(( "number of ranges = %d\n", num_ranges ));
+
+    if ( ALLOC_ARRAY( gaspranges, num_ranges, TT_GaspRange ) ||
+         ACCESS_Frame( num_ranges * 4L ) )
+      goto Exit;
+
+    face->gasp.gaspRanges = gaspranges;
+
+    for ( j = 0; j < num_ranges; j++ )
+    {
+      gaspranges[j].maxPPEM  = GET_UShort();
+      gaspranges[j].gaspFlag = GET_UShort();
+
+      FT_TRACE3(( " [max:%d flag:%d]",
+                gaspranges[j].maxPPEM,
+                gaspranges[j].gaspFlag ));
+    }
+    FT_TRACE3(( "\n" ));
+
+    FORGET_Frame();
+
+    FT_TRACE2(( "GASP loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Kern                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the first kerning table with format 0 in the font.  Only     */
+  /*    accepts the first horizontal kerning table.  Developers should use */
+  /*    the `ftxkern' extension to access other kerning tables in the font */
+  /*    file, if they really want to.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Kern( TT_Face    face,
+                          FT_Stream  stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+    TT_Long    table;
+    TT_UShort  n, num_tables, version;
+
+
+    error = TT_Err_Ok;
+    table = TT_LookUp_Table( face, TTAG_kern );
+    if ( table < 0 )
+      goto Exit;
+
+    if ( FILE_Seek( face->dir_tables[table].Offset ) ||
+         READ_UShort( version )                      ||
+         READ_UShort( num_tables )                   )
+      goto Exit;
+
+    for ( n = 0; n < num_tables; n++ )
+    {
+      TT_UShort  coverage;
+
+
+      if ( FILE_Skip( 4L )         ||
+           READ_UShort( coverage ) )
+        goto Exit;
+
+      if ( coverage == 0x0001 )
+      {
+        TT_UShort        num_pairs, m;
+        TT_Kern_0_Pair*  pair;
+
+
+        /* found a horizontal format 0 kerning table ! */
+        if ( READ_UShort( num_pairs ) ||
+             FILE_Skip( 6 ) )
+          goto Exit;
+
+        /* allocate array of kerning pairs */
+        if ( ALLOC_ARRAY( face->kern_pairs, num_pairs, TT_Kern_0_Pair ) )
+          goto Exit;
+
+        /* read the kerning pairs */
+        if ( ACCESS_Frame( 6L * num_pairs ) )
+          goto Exit;
+
+        pair = face->kern_pairs;
+        for ( m = 0; m < num_pairs; m++ )
+        {
+          pair->left  = GET_UShort();
+          pair->right = GET_UShort();
+          pair->value = GET_UShort();
+          pair++;
+        }
+
+        FORGET_Frame();
+
+        face->num_kern_pairs   = num_pairs;
+        face->kern_table_index = n;
+        goto Exit;
+      }
+    }
+
+    /* no kern table found -- doesn't matter */
+    face->kern_table_index = -1;
+    face->num_kern_pairs   = 0;
+    face->kern_pairs       = NULL;
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Hdmx                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal device metrics table.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Hdmx( TT_Face    face, 
+                          FT_Stream  stream )
+  {
+    TT_Error  error;
+    FT_Memory memory = stream->memory;
+
+    TT_HdmxRec*  rec;
+    TT_Hdmx      hdmx;
+    TT_Long      table;
+    TT_UShort    n;
+	TT_Long      num_glyphs;
+    TT_Long      record_size;
+
+    hdmx.version     = 0;
+    hdmx.num_records = 0;
+    hdmx.records     = 0;
+
+    face->hdmx = hdmx;
+
+    error = TT_Err_Ok;
+
+    /* ths table is optional */
+    if ( ( table = TT_LookUp_Table( face, TTAG_hdmx ) ) < 0 )
+      return error;
+
+    if ( FILE_Seek( face->dir_tables[table].Offset )  ||
+         ACCESS_Frame( 8L ) )
+      goto Exit;
+
+    hdmx.version     = GET_UShort();
+    hdmx.num_records = GET_Short();
+    record_size      = GET_Long();
+
+    FORGET_Frame();
+
+    /* Only recognize format 0 */
+    if ( hdmx.version != 0 )
+      goto Exit;
+
+    if ( ALLOC( hdmx.records, sizeof ( TT_HdmxRec ) * hdmx.num_records ) )
+      goto Exit;
+
+    num_glyphs   = face->root.num_glyphs;
+    record_size -= num_glyphs + 2;
+    rec          = hdmx.records;
+
+    for ( n = 0; n < hdmx.num_records; n++ )
+    {
+      /* read record */
+      if ( READ_Byte( rec->ppem      ) ||
+           READ_Byte( rec->max_width ) )
+        goto Exit;
+
+      if ( ALLOC( rec->widths, num_glyphs )  ||
+           FILE_Read( rec->widths, num_glyphs ) )
+        goto Exit;
+
+      /* skip padding bytes */
+      if ( record_size > 0 )
+        if ( FILE_Skip( record_size ) )
+          goto Exit;
+
+      rec++;
+    }
+
+    face->hdmx = hdmx;
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_Hdmx                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Frees the horizontal device metrics table.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target face object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Free_Hdmx( TT_Face  face )
+  {
+    if ( face )
+    {
+      TT_UShort  n;
+      FT_Memory  memory = face->root.driver->memory;
+
+
+      for ( n = 0; n < face->hdmx.num_records; n++ )
+        FREE( face->hdmx.records[n].widths );
+
+      FREE( face->hdmx.records );
+      face->hdmx.num_records = 0;
+    }
+
+    return TT_Err_Ok;
+  }
+
+
+/* END */
diff --git a/src/shared/sfnt/ttload.h b/src/shared/sfnt/ttload.h
new file mode 100644
index 0000000..889c9e0
--- /dev/null
+++ b/src/shared/sfnt/ttload.h
@@ -0,0 +1,353 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttload.h                                                               */
+/*                                                                         */
+/*    Load the basic TrueType tables, i.e., tables that can be either in   */
+/*    TTF or OTF font (specification).                                     */
+/*                                                                         */
+/*  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 TTLOAD_H
+#define TTLOAD_H
+
+
+#include <ftstream.h>
+#include <ttobjs.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_LookUp_Table                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Looks for a TrueType table by name.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A face object handle.                                      */
+  /*    tag  :: The  searched tag.                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Index of table if found, -1 otherwise.                             */
+  /*                                                                       */
+  EXPORT_DEF
+  TT_Long  TT_LookUp_Table( TT_Face   face,
+                            TT_ULong  tag );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Directory                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the table directory into a face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face      :: A handle to the target face object.                   */
+  /*    stream    :: The input stream.                                     */
+  /*    faceIndex :: The index of the TrueType font, if we're opening a    */
+  /*                 collection.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Directory( TT_Face    face,
+                               FT_Stream  stream,
+                               TT_Long    faceIndex );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Any                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads any font table into client memory.  Used by the              */
+  /*    TT_Get_Font_Data() API function.                                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: The face object to look for.                             */
+  /*                                                                       */
+  /*    tag    :: The tag of table to load.  Use the value 0 if you  want  */
+  /*              to access the whole font file, else set this parameter   */
+  /*              to a valid TrueType table tag that you can forge with    */
+  /*              the MAKE_TT_TAG macro.                                   */
+  /*                                                                       */
+  /*    offset :: The starting offset in the table (or the file if         */
+  /*              tag == 0).                                               */
+  /*                                                                       */
+  /*    length :: The address of the decision variable:                    */
+  /*                                                                       */
+  /*                If length == NULL:                                     */
+  /*                  Loads the whole table.  Returns an error if          */
+  /*                  `offset' == 0!                                       */
+  /*                                                                       */
+  /*                If *length == 0:                                       */
+  /*                  Exits immediately; returning the length of the given */
+  /*                  table or of the font file, depending on the value of */
+  /*                  `tag'.                                               */
+  /*                                                                       */
+  /*                If *length != 0:                                       */
+  /*                  Loads the next `length' bytes of table or font,      */
+  /*                  starting at offset `offset' (in table or font too).  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    buffer :: The address of target buffer.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Any( TT_Face   face,
+                         TT_ULong  tag,
+                         TT_Long   offset,
+                         void*     buffer,
+                         TT_Long*  length );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Header                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the TrueType font header.                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Header( TT_Face    face,
+                            FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Metrics_Header                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal or vertical header in a face object.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face     :: A handle to the target face object.                    */
+  /*    stream   :: The input stream.                                      */
+  /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Metrics_Header( TT_Face    face,
+                                    FT_Stream  stream,
+                                    TT_Bool    vertical );
+
+
+  LOCAL_DEF
+  TT_Error  TT_Load_CMap( TT_Face    face,
+                          FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_MaxProfile                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the maximum profile into a face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_MaxProfile( TT_Face    face,
+                                FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the name records.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Names( TT_Face    face,
+                           FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_OS2                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the OS2 table.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_OS2( TT_Face    face,
+                         FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Postscript                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the Postscript table.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_PostScript( TT_Face    face,
+                                FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Hdmx                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the horizontal device metrics table.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Hdmx( TT_Face    face,
+                          FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Frees the name records.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target face object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Free_Names( TT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_Hdmx                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Frees the horizontal device metrics table.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target face object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Free_Hdmx ( TT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Kern                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the first kerning table with format 0 in the font.  Only     */
+  /*    accepts the first horizontal kerning table.  Developers should use */
+  /*    the `ftxkern' extension to access other kerning tables in the font */
+  /*    file, if they really want to.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Kern( TT_Face    face,
+                          FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Gasp                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the `GASP' table into a face object.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Gasp( TT_Face    face,
+                          FT_Stream  stream );
+
+
+#endif /* TTLOAD_H */
+
+
+/* END */
diff --git a/src/shared/sfnt/ttpost.c b/src/shared/sfnt/ttpost.c
new file mode 100644
index 0000000..30aa19f
--- /dev/null
+++ b/src/shared/sfnt/ttpost.c
@@ -0,0 +1,713 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttpost.c                                                               */
+/*                                                                         */
+/*    Postscript names table processing (body).                            */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The post table is not completely loaded by the core engine.  This     */
+  /* file loads the missing PS glyph names and implements an API to access */
+  /* them.                                                                 */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include <ttpost.h>
+#include <ftstream.h>
+#include <tterrors.h>
+#include <ttload.h>
+#include <tttags.h>
+
+  /* the 258 default Mac PS glyph names */
+
+  const TT_String*  TT_Mac_Postscript_Names[258] =
+  {
+    /*   0 */
+    ".notdef",
+    ".null",
+    "CR",
+    "space",
+    "exclam",
+    "quotedbl",
+    "numbersign",
+    "dollar",
+    "percent",
+    "ampersand",
+
+    /*  10 */
+    "quotesingle",
+    "parenleft",
+    "parenright",
+    "asterisk",
+    "plus",
+    "comma",
+    "hyphen",
+    "period",
+    "slash",
+    "zero",
+
+    /*  20 */
+    "one",
+    "two",
+    "three",
+    "four",
+    "five",
+    "six",
+    "seven",
+    "eight",
+    "nine",
+    "colon",
+
+    /*  30 */
+    "semicolon",
+    "less",
+    "equal",
+    "greater", "question",
+    "at",
+    "A",
+    "B",
+    "C",
+    "D",
+
+    /*  40 */
+    "E",
+    "F",
+    "G",
+    "H",
+    "I",
+    "J",
+    "K",
+    "L",
+    "M",
+    "N",
+
+    /*  50 */
+    "O",
+    "P",
+    "Q",
+    "R",
+    "S",
+    "T",
+    "U",
+    "V",
+    "W",
+    "X",
+
+    /*  60 */
+    "Y",
+    "Z",
+    "bracketleft",
+    "backslash",
+    "bracketright",
+    "asciicircum",
+    "underscore",
+    "grave",
+    "a",
+    "b",
+
+    /*  70 */
+    "c",
+    "d",
+    "e",
+    "f",
+    "g",
+    "h",
+    "i",
+    "j",
+    "k",
+    "l",
+
+    /*  80 */
+    "m",
+    "n",
+    "o",
+    "p",
+    "q",
+    "r",
+    "s",
+    "t",
+    "u",
+    "v",
+
+    /*  90 */
+    "w",
+    "x",
+    "y",
+    "z",
+    "braceleft",
+    "bar",
+    "braceright",
+    "asciitilde",
+    "Adieresis",
+    "Aring",
+
+    /* 100 */
+    "Ccedilla",
+    "Eacute",
+    "Ntilde",
+    "Odieresis",
+    "Udieresis",
+    "aacute",
+    "agrave",
+    "acircumflex",
+    "adieresis",
+    "atilde",
+
+    /* 110 */
+    "aring",
+    "ccedilla",
+    "eacute",
+    "egrave",
+    "ecircumflex",
+    "edieresis",
+    "iacute",
+    "igrave",
+    "icircumflex",
+    "idieresis",
+
+    /* 120 */
+    "ntilde",
+    "oacute",
+    "ograve",
+    "ocircumflex",
+    "odieresis",
+    "otilde",
+    "uacute",
+    "ugrave",
+    "ucircumflex",
+    "udieresis",
+
+    /* 130 */
+    "dagger",
+    "degree",
+    "cent",
+    "sterling",
+    "section",
+    "bullet",
+    "paragraph",
+    "germandbls",
+    "registered",
+    "copyright",
+
+    /* 140 */
+    "trademark",
+    "acute",
+    "dieresis",
+    "notequal",
+    "AE",
+    "Oslash",
+    "infinity",
+    "plusminus",
+    "lessequal",
+    "greaterequal",
+
+    /* 150 */
+    "yen",
+    "mu",
+    "partialdiff",
+    "summation",
+    "product",
+    "pi",
+    "integral",
+    "ordfeminine",
+    "ordmasculine",
+    "Omega",
+
+    /* 160 */
+    "ae",
+    "oslash",
+    "questiondown",
+    "exclamdown",
+    "logicalnot",
+    "radical",
+    "florin",
+    "approxequal",
+    "Delta",
+    "guillemotleft",
+
+    /* 170 */
+    "guillemotright",
+    "ellipsis",
+    "nbspace",
+    "Agrave",
+    "Atilde",
+    "Otilde",
+    "OE",
+    "oe",
+    "endash",
+    "emdash",
+
+    /* 180 */
+    "quotedblleft",
+    "quotedblright",
+    "quoteleft",
+    "quoteright",
+    "divide",
+    "lozenge",
+    "ydieresis",
+    "Ydieresis",
+    "fraction",
+    "currency",
+
+    /* 190 */
+    "guilsinglleft",
+    "guilsinglright",
+    "fi",
+    "fl",
+    "daggerdbl",
+    "periodcentered",
+    "quotesinglbase",
+    "quotedblbase",
+    "perthousand",
+    "Acircumflex",
+
+    /* 200 */
+    "Ecircumflex",
+    "Aacute",
+    "Edieresis",
+    "Egrave",
+    "Iacute",
+    "Icircumflex",
+    "Idieresis",
+    "Igrave",
+    "Oacute",
+    "Ocircumflex",
+
+    /* 210 */
+    "apple",
+    "Ograve",
+    "Uacute",
+    "Ucircumflex",
+    "Ugrave",
+    "dotlessi",
+    "circumflex",
+     "tilde",
+     "macron",
+     "breve",
+
+    /* 220 */
+    "dotaccent",
+    "ring",
+    "cedilla",
+    "hungarumlaut",
+    "ogonek",
+    "caron",
+    "Lslash",
+    "lslash",
+    "Scaron",
+    "scaron",
+
+    /* 230 */
+    "Zcaron",
+    "zcaron",
+    "brokenbar",
+    "Eth",
+    "eth",
+    "Yacute",
+    "yacute",
+    "Thorn",
+    "thorn",
+    "minus",
+
+    /* 240 */
+    "multiply",
+    "onesuperior",
+    "twosuperior",
+    "threesuperior",
+    "onehalf",
+    "onequarter",
+    "threequarters",
+    "franc",
+    "Gbreve",
+    "gbreve",
+
+    /* 250 */
+    "Idot",
+    "Scedilla",
+    "scedilla",
+    "Cacute",
+    "cacute",
+    "Ccaron",
+    "ccaron",
+    "dmacron",
+  };
+
+
+  static
+  TT_Error  Load_Format_20( TT_Face    face,
+                            FT_Stream  stream )
+  {
+    FT_Memory  memory = stream->memory;
+    TT_Error   error;
+
+    TT_UShort  num_glyphs;
+    TT_UShort  num_names;
+
+    TT_UShort* glyph_indices = 0;
+    TT_Char**  name_strings  = 0;
+
+
+    if ( READ_UShort( num_glyphs ) )
+      goto Exit;
+
+    /* UNDOCUMENTED!  The number of glyphs in this table can be smaller */
+    /* than the value in the maxp table (cf. cyberbit.ttf).             */
+
+    /* There already exist fonts which have more than 32768 glyph names */
+    /* in this table, so the test for this threshold has been dropped.  */
+
+    if ( num_glyphs > face->root.num_glyphs )
+    {
+      error = TT_Err_Invalid_File_Format;
+      goto Exit;
+    }
+
+    /* load the indices */
+    {
+      TT_UShort  n;
+
+
+      if ( ALLOC_ARRAY ( glyph_indices, num_glyphs, TT_UShort ) ||
+           ACCESS_Frame( num_glyphs * 2L )                      )
+        goto Fail;
+
+      for ( n = 0; n < num_glyphs; n++ )
+        glyph_indices[n] = GET_UShort();
+
+      FORGET_Frame();
+    }
+
+    /* compute number of names stored in table */
+    {
+      TT_UShort  n;
+
+
+      num_names = 0;
+
+      for ( n = 0; n < num_glyphs; n++ )
+      {
+        TT_UShort  index;
+
+
+        index = glyph_indices[n];
+        if ( index >= 258 )
+        {
+          index -= 257;
+          if ( index > num_names )
+            num_names = index;
+        }
+      }
+    }
+
+    /* now load the name strings */
+    {
+      TT_UShort  n;
+
+
+      if ( ALLOC_ARRAY( name_strings, num_names, TT_Char* ) )
+        goto Fail;
+
+      for ( n = 0; n < num_names; n++ )
+      {
+        TT_Byte   len;
+
+
+        if ( READ_Byte  ( len )                             ||
+             ALLOC_ARRAY( name_strings[n], len+1, TT_Char ) ||
+             FILE_Read  ( name_strings[n], len )            )
+          goto Fail1;
+
+        name_strings[n][len] = '\0';
+      }
+    }
+
+    /* all right, set table fields and exit successfuly */
+    {
+      TT_Post_20*  table = &face->postscript_names.names.format_20;
+
+
+      table->num_glyphs    = num_glyphs;
+      table->num_names     = num_names;
+      table->glyph_indices = glyph_indices;
+      table->glyph_names   = name_strings;
+    }
+    return TT_Err_Ok;
+
+
+  Fail1:
+    {
+      TT_UShort  n;
+
+
+      for ( n = 0; n < num_names; n++ )
+        FREE( name_strings[n] );
+    }
+
+  Fail:
+    FREE( name_strings );
+    FREE( glyph_indices );
+
+  Exit:
+    return error;
+  }
+
+
+  static
+  TT_Error  Load_Format_25( TT_Face    face,
+                            FT_Stream  stream )
+  {
+    FT_Memory  memory = stream->memory;
+    TT_Error   error;
+
+    TT_UShort  num_glyphs;
+    TT_Char*   offset_table = 0;
+
+
+    /* UNDOCUMENTED!  This value appears only in the Apple TT specs. */
+    if ( READ_UShort( num_glyphs ) )
+      goto Exit;
+
+    /* check the number of glyphs */
+    if ( num_glyphs > face->root.num_glyphs || num_glyphs > 258 )
+    {
+      error = TT_Err_Invalid_File_Format;
+      goto Exit;
+    }
+
+    if ( ALLOC    ( offset_table, num_glyphs ) ||
+         FILE_Read( offset_table, num_glyphs ) )
+      goto Fail;
+
+    /* now check the offset table */
+    {
+      TT_UShort  n;
+
+
+      for ( n = 0; n < num_glyphs; n++ )
+      {
+        TT_Long  index = (TT_Long)n + offset_table[n];
+
+
+        if ( index < 0 || index > num_glyphs )
+        {
+          error = TT_Err_Invalid_File_Format;
+          goto Fail;
+        }
+      }
+    }
+
+    /* OK, set table fields and exit successfuly */
+    {
+      TT_Post_25*  table = &face->postscript_names.names.format_25;
+
+
+      table->num_glyphs = num_glyphs;
+      table->offsets    = offset_table;
+    }
+
+    return TT_Err_Ok;
+
+  Fail:
+    FREE( offset_table );
+
+  Exit:
+    return error;
+  }
+
+
+  static
+  TT_Error  Load_Post_Names( TT_Face  face )
+  {
+    FT_Stream   stream;
+    TT_Error    error;
+
+    /* get a stream for the face's resource */
+    stream = face->root.stream;
+
+    /* seek to the beginning of the PS names table */
+    {
+      TT_Long  table;
+
+
+      table = TT_LookUp_Table( face, TTAG_post );
+      if ( FILE_Seek( face->dir_tables[table].Offset + 32L ) )
+        goto Exit;
+    }
+
+    /* now read postscript table */
+    switch ( face->postscript.FormatType )
+    {
+    case 0x00020000:
+      error = Load_Format_20( face, stream );
+      break;
+
+    case 0x00028000:
+      error = Load_Format_25( face, stream );
+      break;
+
+    default:
+      error = TT_Err_Invalid_File_Format;
+    }
+
+    face->postscript_names.loaded = 1;
+
+  Exit:
+    return error;
+  }
+
+
+  LOCAL_FUNC
+  void  TT_Free_Post_Names( TT_Face  face )
+  {
+    FT_Memory       memory = face->root.memory;
+    TT_Post_Names*  names  = &face->postscript_names;
+
+
+    if ( names->loaded )
+    {
+      switch ( face->postscript.FormatType )
+      {
+      case 0x00020000:
+        {
+          TT_Post_20*  table = &names->names.format_20;
+          TT_UShort    n;
+
+
+          FREE( table->glyph_indices );
+          table->num_glyphs = 0;
+
+          for ( n = 0; n < table->num_names; n++ )
+            FREE( table->glyph_names[n] );
+
+          FREE( table->glyph_names );
+          table->num_names = 0;
+        }
+        break;
+
+      case 0x00028000:
+        {
+          TT_Post_25*  table = &names->names.format_25;
+
+
+          FREE( table->offsets );
+          table->num_glyphs = 0;
+        }
+        break;
+      }
+    }
+    names->loaded = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Get_PS_Name                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Gets the PostScript glyph name of a glyph.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    index  :: The glyph index.                                         */
+  /*                                                                       */
+  /*    PSname :: The address of a string pointer.  Will be NULL in case   */
+  /*              of error, otherwise it is a pointer to the glyph name.   */
+  /*                                                                       */
+  /*              You must not modify the returned string!                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error  TT_Get_PS_Name( TT_Face      face,
+                            TT_UInt      index,
+                            TT_String**  PSname )
+  {
+    TT_Error        error;
+    TT_Post_Names*  names;
+
+    if ( !face )
+      return TT_Err_Invalid_Face_Handle;
+
+    if ( index >= face->root.num_glyphs )
+      return TT_Err_Invalid_Glyph_Index;
+
+    names   = &face->postscript_names;
+
+    /* `.notdef' by default */
+    *PSname = (TT_String*)TT_Mac_Postscript_Names[0];
+
+    switch ( face->postscript.FormatType )
+    {
+    case 0x00010000:
+      if ( index < 258 )                    /* paranoid checking */
+        *PSname = (TT_String*)TT_Mac_Postscript_Names[index];
+      break;
+
+    case 0x00020000:
+      {
+        TT_Post_20*  table = &names->names.format_20;
+
+
+        if ( !names->loaded )
+        {
+          error = Load_Post_Names( face );
+          if ( error )
+            break;
+        }
+
+        if ( index < table->num_glyphs )
+        {
+          TT_UShort  name_index = table->glyph_indices[index];
+
+
+          if ( name_index < 258 )
+            *PSname = (TT_String*)TT_Mac_Postscript_Names[name_index];
+          else
+            *PSname = (TT_String*)table->glyph_names[name_index - 258];
+        }
+      }
+      break;
+
+    case 0x00028000:
+      {
+        TT_Post_25*  table = &names->names.format_25;
+
+
+        if ( !names->loaded )
+        {
+          error = Load_Post_Names( face );
+          if ( error )
+            break;
+        }
+
+        if ( index < table->num_glyphs )    /* paranoid checking */
+        {
+          index  += table->offsets[index];
+          *PSname = (TT_String*)TT_Mac_Postscript_Names[index];
+        }
+      }
+      break;
+
+    case 0x00030000:
+      break;                                /* nothing to do */
+    }
+
+    return TT_Err_Ok;
+  }
+
+
+/* END */
diff --git a/src/shared/sfnt/ttpost.h b/src/shared/sfnt/ttpost.h
new file mode 100644
index 0000000..1ff813e
--- /dev/null
+++ b/src/shared/sfnt/ttpost.h
@@ -0,0 +1,95 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttpost.h                                                               */
+/*                                                                         */
+/*    Postcript name table processing for TrueType and OpenType fonts      */
+/*    (specification).                                                     */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The post table is not completely loaded by the core engine.  This     */
+  /* file loads the missing PS glyph names and implements an API to access */
+  /* them.                                                                 */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef TTPOST_H
+#define TTPOST_H
+
+#include <ftconfig.h>
+#include <tttypes.h>
+#include <ttconfig.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define TT_Err_Invalid_Post_Table_Format  0x0B00
+#define TT_Err_Invalid_Post_Table         0x0B01
+
+
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+#if 0
+  /* the 258 standard Mac glyph names, used for format 1.0 and 2.5 */
+  LOCAL_DEF
+  const TT_String*  TT_Mac_Postscript_Names[];
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Get_PS_Name                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Gets the PostScript glyph name of a glyph.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    index  :: The glyph index.                                         */
+  /*                                                                       */
+  /*    PSname :: The address of a string pointer.  Will be NULL in case   */
+  /*              of error, otherwise it is a pointer to the glyph name.   */
+  /*                                                                       */
+  /*              You must not modify the returned string!                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  EXPORT_DEF
+  TT_Error TT_Get_PS_Name( TT_Face      face,
+                           TT_UInt      index,
+                           TT_String**  PSname );
+
+
+  LOCAL_DEF
+  void  TT_Free_Post_Names( TT_Face  face );
+
+
+#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* TTPOST_H */
+
+
+/* END */
diff --git a/src/shared/sfnt/ttsbit.c b/src/shared/sfnt/ttsbit.c
new file mode 100644
index 0000000..fd3fc2d
--- /dev/null
+++ b/src/shared/sfnt/ttsbit.c
@@ -0,0 +1,1443 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttsbit.c                                                               */
+/*                                                                         */
+/*    TrueType and OpenType embedded bitmap support (body).                */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/*                                                                         */
+/*  WARNING: This file should not be compiled directly, it is meant to be  */
+/*           included in the source of several font drivers (i.e., the TTF */
+/*           and OTF drivers).                                             */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ftdebug.h>
+
+#include <ttsbit.h>
+#include <tttags.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    blit_sbit                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Blits a bitmap from an input stream into a given target.  Supports */
+  /*    x and y offsets as well as byte padded lines.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    target      :: The target bitmap/pixmap.                           */
+  /*                                                                       */
+  /*    source      :: The input packed bitmap data.                       */
+  /*                                                                       */
+  /*    line_bits   :: The number of bits per line.                        */
+  /*                                                                       */
+  /*    byte_padded :: A flag which is true if lines are byte-padded.      */
+  /*                                                                       */
+  /*    x_offset    :: The horizontal offset.                              */
+  /*                                                                       */
+  /*    y_offset    :: The vertical offset.                                */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    IMPORTANT: The x and y offsets are relative to the top corner of   */
+  /*               the target bitmap (unlike the normal TrueType           */
+  /*               convention).  A positive y offset indicates a downwards */
+  /*               direction!                                              */
+  /*                                                                       */
+  static
+  void  blit_sbit( FT_Bitmap*  target,
+                   FT_Byte*    source,
+                   FT_Int      line_bits,
+                   FT_Bool     byte_padded,
+                   FT_Int      x_offset,
+                   FT_Int      y_offset )
+  {
+    FT_Byte*   line_buff;
+    FT_Int     line_incr;
+    FT_Int     height;
+
+    FT_UShort  acc;
+    FT_Byte    loaded;
+
+
+    /* first of all, compute starting write position */
+    line_incr = target->pitch;
+    line_buff = target->buffer;
+    
+    if (line_incr < 0)
+      line_buff -= line_incr*(target->rows-1);
+
+    line_buff += (x_offset >> 3) + y_offset * line_incr;
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* We use the extra-classic `accumulator' trick to extract the bits    */
+    /* from the source byte stream.                                        */
+    /*                                                                     */
+    /* Namely, the variable `acc' is a 16-bit accumulator containing the   */
+    /* last `loaded' bits from the input stream.  The bits are shifted to  */
+    /* the upmost position in `acc'.                                       */
+    /*                                                                     */
+    /***********************************************************************/
+
+    acc    = 0;  /* clear accumulator   */
+    loaded = 0;  /* no bits were loaded */
+
+    for ( height = target->rows; height > 0; height-- )
+    {
+      FT_Byte*  cur   = line_buff;    /* current write cursor          */
+      FT_Int    count = line_bits;    /* # of bits to extract per line */
+      FT_Byte   shift = x_offset & 7; /* current write shift           */
+      FT_Byte   space = 8 - shift;
+
+
+      /* first of all, read individual source bytes */
+      if ( count >= 8 )
+      {
+        count -= 8;
+        {
+          do
+          {
+            FT_Byte  val;
+
+            /* ensure that there are at least 8 bits in the accumulator */
+            if ( loaded < 8 )
+            {
+              acc    |= ((FT_UShort)*source++) << (8 - loaded);
+              loaded += 8;
+            }
+
+            /* now write one byte */
+            val     = (FT_Byte)(acc >> 8);
+            if (shift)
+            {
+              cur[0] |= val >> shift;
+              cur[1] |= val << space;
+            }
+            else
+              cur[0] = val;
+
+            cur++;
+            acc   <<= 8;  /* remove bits from accumulator */
+            loaded -= 8;
+            count  -= 8;
+          }
+          while ( count >= 0 );
+        }
+
+        /* restore `count' to correct value */
+        count += 8;
+      }
+
+      /* now write remaining bits (count < 8) */
+      if ( count > 0 )
+      {
+        FT_Byte  val;
+
+
+        /* ensure that there are at least `count' bits in the accumulator */
+        if ( loaded < count )
+        {
+          acc    |= ((FT_UShort)*source++) << (8 - loaded);
+          loaded += 8;
+        }
+
+        /* now write remaining bits */
+        val     = ((FT_Byte)(acc >> 8)) & ~(0xFF >> count);
+        cur[0] |= val >> shift;
+
+        if ( count > space )
+          cur[1] |= val << space;
+
+        acc   <<= count;
+        loaded -= count;
+      }
+
+      /* now, skip to next line */
+      if ( byte_padded )
+        acc = loaded = 0;   /* clear accumulator on byte-padded lines */
+
+      line_buff += line_incr;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Small_SBit_Metrics                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a small bitmap metrics record.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream  :: The input stream.                                       */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    metrics :: A small metrics structure.                              */
+  /*                                                                       */
+  static
+  void  TT_Load_Small_SBit_Metrics( TT_SBit_Small_Metrics*  metrics,
+                                    FT_Stream               stream )
+  {
+    metrics->height   = GET_Byte();
+    metrics->width    = GET_Byte();
+    metrics->bearingX = GET_Char();
+    metrics->bearingY = GET_Char();
+    metrics->advance  = GET_Byte();
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Metrics                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a bitmap metrics record.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream  :: The input stream.                                       */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    metrics :: A metrics structure.                                    */
+  /*                                                                       */
+  static
+  void  TT_Load_SBit_Metrics( TT_SBit_Metrics*  metrics,
+                              FT_Stream         stream )
+  {
+    metrics->height       = GET_Byte();
+    metrics->width        = GET_Byte();
+
+    metrics->horiBearingX = GET_Char();
+    metrics->horiBearingY = GET_Char();
+    metrics->horiAdvance  = GET_Byte();
+
+    metrics->vertBearingX = GET_Char();
+    metrics->vertBearingY = GET_Char();
+    metrics->vertAdvance  = GET_Byte();
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Line_Metrics                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a bitmap line metrics record.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream  :: The input stream.                                       */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    metrics :: A line metrics structure.                               */
+  /*                                                                       */
+  static
+  void  TT_Load_SBit_Line_Metrics( TT_SBit_Line_Metrics*  metrics,
+                                   FT_Stream              stream )
+  {
+    metrics->ascender  = GET_Char();
+    metrics->descender = GET_Char();
+    metrics->max_width = GET_Byte();
+
+    metrics->caret_slope_numerator   = GET_Char();
+    metrics->caret_slope_denominator = GET_Char();
+    metrics->caret_offset            = GET_Char();
+
+    metrics->min_origin_SB  = GET_Char();
+    metrics->min_advance_SB = GET_Char();
+    metrics->max_before_BL  = GET_Char();
+    metrics->min_after_BL   = GET_Char();
+    metrics->pads[0]        = GET_Char();
+    metrics->pads[1]        = GET_Char();
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Const_Metrics                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the metrics for `EBLC' index tables format 2 and 5.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range  :: The target range.                                        */
+  /*                                                                       */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Load_SBit_Const_Metrics( TT_SBit_Range*  range,
+                                     FT_Stream       stream )
+  {
+    TT_Error  error;
+
+    if ( !ACCESS_Frame( 12L ) )
+    {
+      range->image_size = GET_ULong();
+      TT_Load_SBit_Metrics( &range->metrics, stream );
+
+      FORGET_Frame();
+    }
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Range_Codes                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the range codes for `EBLC' index tables format 4 and 5.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range        :: The target range.                                  */
+  /*                                                                       */
+  /*    stream       :: The input stream.                                  */
+  /*                                                                       */
+  /*    load_offsets :: A flag whether to load the glyph offset table.     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Load_SBit_Range_Codes( TT_SBit_Range*  range,
+                                   FT_Stream       stream,
+                                   TT_Bool         load_offsets )
+  {
+    TT_Error   error;
+    TT_ULong   count, n, size;
+    FT_Memory  memory = stream->memory;
+
+
+    if ( READ_ULong( count ) )
+      goto Exit;
+
+    range->num_glyphs = count;
+
+    /* Allocate glyph offsets table if needed */
+    if ( load_offsets )
+    {
+      if ( ALLOC_ARRAY( range->glyph_offsets, count, TT_ULong ) )
+        goto Exit;
+
+      size = count * 4L;
+    }
+    else
+      size = count * 2L;
+
+    /* Allocate glyph codes table and access frame */
+    if ( ALLOC_ARRAY ( range->glyph_codes, count, TT_UShort ) ||
+         ACCESS_Frame( size )                                 )
+      goto Exit;
+
+    for ( n = 0; n < count; n++ )
+    {
+      range->glyph_codes[n] = GET_UShort();
+
+      if (load_offsets)
+        range->glyph_offsets[n] = (TT_ULong)range->image_offset + 
+                                  GET_UShort();
+    }
+
+    FORGET_Frame();
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Range                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given `EBLC' index/range table.                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range  :: The target range.                                        */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Load_SBit_Range( TT_SBit_Range*  range,
+                             FT_Stream       stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+
+
+    switch( range->index_format )
+    {
+    case 1:   /* variable metrics with 4-byte offsets */
+    case 3:   /* variable metrics with 2-byte offsets */
+      {
+        TT_ULong  num_glyphs, n;
+        TT_Int    size_elem;
+        TT_Bool   large = (range->index_format == 1);
+
+
+        num_glyphs        = range->last_glyph - range->first_glyph + 1L;
+        range->num_glyphs = num_glyphs;
+        num_glyphs++;    /* XXX : BEWARE - see spec */
+
+        size_elem  = ( large ? 4 : 2 );
+
+        if ( ALLOC_ARRAY( range->glyph_offsets,
+                          num_glyphs, TT_ULong )    ||
+
+             ACCESS_Frame( num_glyphs * size_elem ) )
+          goto Exit;
+
+        for ( n = 0; n < num_glyphs; n++ )
+          range->glyph_offsets[n] = (TT_ULong)( range->image_offset +
+                                     (large ? GET_ULong() : GET_UShort()) );
+        FORGET_Frame();
+      }
+      break;
+
+    case 2:   /* all glyphs have identical metrics */
+      error = Load_SBit_Const_Metrics( range, stream );
+      break;
+
+    case 4:
+      error = Load_SBit_Range_Codes( range, stream, 1 );
+      break;
+
+    case 5:
+      error = Load_SBit_Const_Metrics( range, stream ) ||
+              Load_SBit_Range_Codes( range, stream, 0 );
+      break;
+
+    default:
+      error = TT_Err_Invalid_File_Format;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Strikes                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the table of embedded bitmap sizes for this face.            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: The target face object.                                  */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_SBit_Strikes( TT_Face    face,
+                                  FT_Stream  stream )
+  {
+    TT_Error   error  = 0;
+    FT_Memory  memory = stream->memory;
+    TT_Fixed   version;
+    TT_ULong   num_strikes;
+    TT_ULong   table_base;
+    TT_Long    table;
+
+
+    /* this table is optional */
+    if ( ( table = TT_LookUp_Table( face, TTAG_EBLC ) ) < 0 )
+      goto Exit;
+
+    table_base = face->dir_tables[table].Offset;
+    if ( FILE_Seek( table_base ) ||
+         ACCESS_Frame( 8L )      )
+      goto Exit;
+
+    version     = GET_Long();
+    num_strikes = GET_ULong();
+
+    FORGET_Frame();
+
+    /* check version number and strike count */
+    if ( version     != 0x00020000 ||
+         num_strikes >= 0x10000    )
+    {
+      FT_ERROR(( "TT_Load_SBit_Strikes: invalid table version!\n" ));
+      error = TT_Err_Invalid_File_Format;
+
+      goto Exit;
+    }
+
+    /* allocate the strikes table */
+    if ( ALLOC_ARRAY( face->sbit_strikes, num_strikes, TT_SBit_Strike ) )
+      goto Exit;
+
+    face->num_sbit_strikes = num_strikes;
+
+    /* now read each strike table separately */
+    {
+      TT_SBit_Strike*  strike = face->sbit_strikes;
+      TT_ULong         count  = num_strikes;
+
+      if ( ACCESS_Frame( 48L * num_strikes ) )
+        goto Exit;
+
+      while ( count > 0 )
+      {
+        TT_ULong  indexTablesSize;
+
+
+        strike->ranges_offset    = GET_ULong();
+        indexTablesSize          = GET_ULong();  /* don't save */
+
+        strike->num_ranges       = GET_ULong();
+        strike->color_ref        = GET_ULong();
+
+        TT_Load_SBit_Line_Metrics( &strike->hori, stream );
+        TT_Load_SBit_Line_Metrics( &strike->vert, stream );
+
+        strike->start_glyph      = GET_UShort();
+        strike->end_glyph        = GET_UShort();
+        strike->x_ppem           = GET_Byte();
+        strike->y_ppem           = GET_Byte();
+        strike->bit_depth        = GET_Byte();
+        strike->flags            = GET_Char();
+
+        count--;
+        strike++;
+      }
+
+      FORGET_Frame();
+    }
+
+    /* allocate the index ranges for each strike table */
+    {
+      TT_SBit_Strike*  strike = face->sbit_strikes;
+      TT_ULong         count  = num_strikes;
+
+
+      while ( count > 0 )
+      {
+        TT_SBit_Range* range;
+        TT_ULong       count2 = strike->num_ranges;
+
+
+        if ( ALLOC_ARRAY( strike->sbit_ranges,
+                          strike->num_ranges,
+                          TT_SBit_Range ) )
+          goto Exit;
+
+        /* read each range */
+        if ( FILE_Seek( table_base + strike->ranges_offset ) ||
+             ACCESS_Frame( strike->num_ranges * 8L )         )
+          goto Exit;
+
+        range = strike->sbit_ranges;
+        while ( count2 > 0 )
+        {
+          range->first_glyph  = GET_UShort();
+          range->last_glyph   = GET_UShort();
+          range->table_offset = table_base + strike->ranges_offset
+                                 + GET_ULong();
+          count2--;
+          range++;
+        }
+
+        FORGET_Frame();
+
+        /* Now, read each index table */
+        count2 = strike->num_ranges;
+        range  = strike->sbit_ranges;
+        while ( count2 > 0 )
+        {
+          /* Read the header */
+          if ( FILE_Seek( range->table_offset ) ||
+               ACCESS_Frame( 8L )               )
+            goto Exit;
+
+          range->index_format = GET_UShort();
+          range->image_format = GET_UShort();
+          range->image_offset = GET_ULong();
+
+          FORGET_Frame();
+
+          error = Load_SBit_Range( range, stream );
+          if ( error )
+            goto Exit;
+
+          count2--;
+          range++;
+        }
+
+        count--;
+        strike++;
+      }
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_SBit_Strikes                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases the embedded bitmap tables.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: The target face object.                                    */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  TT_Free_SBit_Strikes( TT_Face  face )
+  {
+    FT_Memory        memory       = face->root.memory;
+    TT_SBit_Strike*  strike       = face->sbit_strikes;
+    TT_SBit_Strike*  strike_limit = strike + face->num_sbit_strikes;
+
+
+    if ( strike )
+    {
+      for ( ; strike < strike_limit; strike++ )
+      {
+        TT_SBit_Range*  range       = strike->sbit_ranges;
+        TT_SBit_Range*  range_limit = range + strike->num_ranges;
+
+        if ( range )
+        {
+          for ( ; range < range_limit; range++ )
+          {
+            /* release the glyph offsets and codes tables */
+            /* where appropriate                          */
+            FREE( range->glyph_offsets );
+            FREE( range->glyph_codes );
+          }
+        }
+        FREE( strike->sbit_ranges );
+        strike->num_ranges = 0;
+      }
+      FREE( face->sbit_strikes );
+    }
+    face->num_sbit_strikes = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Find_SBit_Range                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Scans a given strike's ranges and return, for a given glyph        */
+  /*    index, the corresponding sbit range, and `EBDT' offset.            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    glyph_index   :: The glyph index.                                  */
+  /*    strike        :: The source/current sbit strike.                   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    arange        :: The sbit range containing the glyph index.        */
+  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means the glyph index was found.           */
+  /*                                                                       */
+  static
+  TT_Error  Find_SBit_Range( TT_UShort        glyph_index,
+                             TT_SBit_Strike*  strike,
+                             TT_SBit_Range**  arange,
+                             TT_ULong*        aglyph_offset )
+  {
+    TT_SBit_Range  *range, *range_limit;
+
+
+    /* check whether the glyph index is within this strike's */
+    /* glyph range                                           */
+    if ( glyph_index < strike->start_glyph ||
+         glyph_index > strike->end_glyph   )
+      goto Fail;
+
+    /* scan all ranges in strike */
+    range       = strike->sbit_ranges;
+    range_limit = range + strike->num_ranges;
+    if ( !range )
+      goto Fail;
+
+    for ( ; range < range_limit; range++ )
+    {
+      if ( glyph_index >= range->first_glyph &&
+           glyph_index <= range->last_glyph  )
+      {
+        TT_UShort  delta = glyph_index - range->first_glyph;
+
+
+        switch ( range->index_format )
+        {
+        case 1:
+        case 3:
+          *aglyph_offset = range->glyph_offsets[delta];
+          break;
+
+        case 2:
+          *aglyph_offset = range->image_offset +
+                           range->image_size * delta;
+          break;
+
+        case 4:
+        case 5:
+          {
+            TT_ULong  n;
+
+
+            for ( n = 0; n < range->num_glyphs; n++ )
+            {
+              if ( range->glyph_codes[n] == glyph_index )
+              {
+                if ( range->index_format == 4 )
+                  *aglyph_offset = range->glyph_offsets[n];
+                else
+                  *aglyph_offset = range->image_offset +
+                                   n * range->image_size;
+                break;
+              }
+            }
+          }
+
+          /* fall-through */
+          default:
+            goto Fail;
+        }
+
+        /* return successfully! */
+        *arange  = range;
+
+        return 0;
+      }
+    }
+
+  Fail:
+    *arange        = 0;
+    *aglyph_offset = 0;
+
+    return TT_Err_Invalid_Argument;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Find_SBit_Image                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Checks whether an embedded bitmap (an `sbit') exists for a given   */
+  /*    glyph, at given x and y ppems.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face          :: The target face object.                           */
+  /*    glyph_index   :: The glyph index.                                  */
+  /*    x_ppem        :: The horizontal resolution in points per EM.       */
+  /*    y_ppem        :: The vertical resolution in points per EM.         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    arange        :: The SBit range containing the glyph index.        */
+  /*    astrike       :: The SBit strike containing the glyph index.       */
+  /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.  Returns                    */
+  /*    TT_Err_Invalid_Argument if no sbit exist for the requested glyph.  */
+  /*                                                                       */
+  static
+  TT_Error  Find_SBit_Image( TT_Face           face,
+                             TT_UShort         glyph_index,
+                             TT_Int            x_ppem,
+                             TT_Int            y_ppem,
+
+                             TT_SBit_Range**   arange,
+                             TT_SBit_Strike**  astrike,
+                             TT_ULong*         aglyph_offset )
+  {
+    TT_SBit_Strike*  strike = face->sbit_strikes;
+    TT_SBit_Strike*  strike_limit = strike + face->num_sbit_strikes;
+
+
+    if ( !strike)
+      goto Fail;
+
+    for ( ; strike < strike_limit; strike++ )
+    {
+      if ( strike->x_ppem == x_ppem && strike->y_ppem == y_ppem )
+      {
+        TT_Error  error;
+
+
+        error = Find_SBit_Range( glyph_index, strike, arange, aglyph_offset );
+        if ( error )
+          goto Fail;
+
+        *astrike = strike;
+
+        return TT_Err_Ok;
+      }
+    }
+
+  Fail:
+    /* no embedded bitmap for this glyph in face */
+    *arange        = 0;
+    *astrike       = 0;
+    *aglyph_offset = 0;
+
+    return TT_Err_Invalid_Argument;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Load_SBit_Metrics                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Gets the big metrics for a given SBit.                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    stream      :: The input stream.                                   */
+  /*    range       :: The SBit range containing the glyph.                */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    big_metrics :: A big SBit metrics structure for the glyph.         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The stream cursor must be positioned at the glyph's offset within  */
+  /*    the `EBDT' table before the call.                                  */
+  /*                                                                       */
+  /*    If the image format uses variable metrics, the stream cursor is    */
+  /*    positioned just after the metrics header in the `EBDT' table on    */
+  /*    function exit.                                                     */
+  /*                                                                       */
+  static
+  TT_Error  Load_SBit_Metrics( FT_Stream         stream,
+                               TT_SBit_Range*    range,
+                               TT_SBit_Metrics*  metrics )
+  {
+    TT_Error  error = TT_Err_Ok;
+
+
+    switch ( range->index_format )
+    {
+    case 1:  /* variable metrics */
+    case 3:
+    case 4:
+      {
+        switch ( range->image_format )
+        {
+        case 1:  /* small metrics */
+        case 2:
+        case 8:
+          {
+            TT_SBit_Small_Metrics  smetrics;
+
+
+            /* read small metrics */
+            if ( ACCESS_Frame( 5L ) )
+              goto Exit;
+            TT_Load_Small_SBit_Metrics( &smetrics, stream );
+            FORGET_Frame();
+
+            /* convert it to a big metrics */
+            metrics->height       = smetrics.height;
+            metrics->width        = smetrics.width;
+            metrics->horiBearingX = smetrics.bearingX;
+            metrics->horiBearingY = smetrics.bearingY;
+            metrics->horiAdvance  = smetrics.advance;
+
+            /* these metrics are made up at a higher level when */
+            /* needed.                                          */
+            metrics->vertBearingX = 0;
+            metrics->vertBearingY = 0;
+            metrics->vertAdvance  = 0;
+          }
+          break;
+
+        default:  /* big metrics */
+          if ( ACCESS_Frame( 8L ) )
+            goto Exit;
+          TT_Load_SBit_Metrics( metrics, stream );
+          FORGET_Frame();
+        }
+      }
+      break;
+
+    default:  /* constant metrics */
+      *metrics = range->metrics;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Crop_Bitmap                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Crops a bitmap to its tightest bounding box, and adjusts its       */
+  /*    metrics.                                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    image   :: The input glyph slot.                                   */
+  /*                                                                       */
+  /*    metrics :: The corresponding metrics structure.                    */
+  /*                                                                       */
+  static
+  void  Crop_Bitmap( FT_Bitmap*        map,
+                     TT_SBit_Metrics*  metrics )
+  {
+    /***********************************************************************/
+    /*                                                                     */
+    /* In this situation, some bounding boxes of embedded bitmaps are too  */
+    /* large.  We need to crop it to a reasonable size.                    */
+    /*                                                                     */
+    /*      ---------                                                      */
+    /*      |       |                -----                                 */
+    /*      |  ***  |                |***|                                 */
+    /*      |   *   |                | * |                                 */
+    /*      |   *   |    ------>     | * |                                 */
+    /*      |   *   |                | * |                                 */
+    /*      |   *   |                | * |                                 */
+    /*      |  ***  |                |***|                                 */
+    /*      ---------                -----                                 */
+    /*                                                                     */
+    /***********************************************************************/
+
+    TT_Int    rows, count;
+    TT_Long   line_len;
+    TT_Byte*  line;
+
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* first of all, checks the top-most lines of the bitmap, and removes  */
+    /* them if they're empty.                                              */
+    /*                                                                     */
+    {
+      line     = (TT_Byte*)map->buffer;
+      rows     = map->rows;
+      line_len = map->pitch;
+
+
+      for ( count = 0; count < rows; count++ )
+      {
+        TT_Byte*  cur   = line;
+        TT_Byte*  limit = line + line_len;
+
+
+        for ( ; cur < limit; cur++ )
+          if ( cur[0] )
+            goto Found_Top;
+
+        /* the current line was empty - skip to next one */
+        line  = limit;
+      }
+
+    Found_Top:
+      /* check that we have at least one filled line */
+      if ( count >= rows )
+        goto Empty_Bitmap;
+
+      /* now, crop the empty upper lines */
+      if ( count > 0 )
+      {
+        line = (TT_Byte*)map->buffer;
+
+        MEM_Move( line, line + count * line_len, (rows - count) * line_len );
+
+        metrics->height       -= count;
+        metrics->horiBearingY -= count;
+        metrics->vertBearingY -= count;
+
+        map->rows -= count;
+        rows      -= count;
+      }
+    }
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* second, crop the lower lines                                        */
+    /*                                                                     */
+    {
+      line = (TT_Byte*)map->buffer + (rows - 1) * line_len;
+
+      for ( count = 0; count < rows; count++ )
+      {
+        TT_Byte*  cur   = line;
+        TT_Byte*  limit = line + line_len;
+
+
+        for ( ; cur < limit; cur++ )
+          if ( cur[0] )
+            goto Found_Bottom;
+
+        /* the current line was empty - skip to previous one */
+        line -= line_len;
+      }
+
+    Found_Bottom:
+      if ( count > 0 )
+      {
+        metrics->height -= count;
+        rows            -= count;
+        map->rows       -= count;
+      }
+    }
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* third, get rid of the space on the left side of the glyph           */
+    /*                                                                     */
+    do
+    {
+      TT_Byte*  limit;
+
+
+      line  = (TT_Byte*)map->buffer;
+      limit = line + rows * line_len;
+
+      for ( ; line < limit; line += line_len )
+        if ( line[0] & 0x80 )
+          goto Found_Left;
+
+      /* shift the whole glyph one pixel to the left */
+      line  = (TT_Byte*)map->buffer;
+      limit = line + rows * line_len;
+
+      for ( ; line < limit; line += line_len )
+      {
+        TT_Int    n, width = map->width;
+        TT_Byte   old;
+        TT_Byte*  cur = line;
+
+
+        old = cur[0] << 1;
+        for ( n = 8; n < width; n += 8 )
+        {
+          TT_Byte  val;
+
+
+          val    = cur[1];
+          cur[0] = old | (val >> 7);
+          old    = val << 1;
+          cur++;
+        }
+        cur[0] = old;
+      }
+
+      map->width--;
+      metrics->horiBearingX++;
+      metrics->vertBearingX++;
+      metrics->width--;
+    } while ( map->width > 0 );
+
+  Found_Left:
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* finally, crop the bitmap width to get rid of the space on the right */
+    /* side of the glyph.                                                  */
+    /*                                                                     */
+    do
+    {
+      TT_Int    right = map->width-1;
+      TT_Byte*  limit;
+      TT_Byte   mask;
+
+
+      line  = (TT_Byte*)map->buffer + (right >> 3);
+      limit = line + rows*line_len;
+      mask  = 0x80 >> (right & 7);
+
+      for ( ; line < limit; line += line_len )
+        if ( line[0] & mask )
+          goto Found_Right;
+
+      /* crop the whole glyph to the right */
+      map->width--;
+      metrics->width--;
+    } while ( map->width > 0 );
+
+  Found_Right:
+    /* all right, the bitmap was cropped */
+    return;
+
+  Empty_Bitmap:
+    map->width      = 0;
+    map->rows       = 0;
+    map->pitch      = 0;
+    map->pixel_mode = ft_pixel_mode_mono;
+  }
+
+
+  static
+  TT_Error Load_SBit_Single( FT_Bitmap*        map,
+                             TT_Int            x_offset,
+                             TT_Int            y_offset,
+                             TT_Int            pix_bits,
+                             TT_UShort         image_format,
+                             TT_SBit_Metrics*  metrics,
+                             FT_Stream         stream )
+  {
+    TT_Error  error;
+
+
+    /* check that the source bitmap fits into the target pixmap */
+    if ( x_offset < 0 || x_offset + metrics->width  > map->width ||
+         y_offset < 0 || y_offset + metrics->height > map->rows  )
+    {
+      error = TT_Err_Invalid_Argument;
+
+      goto Exit;
+    }
+
+    {
+      TT_Int  glyph_width  = metrics->width;
+      TT_Int  glyph_height = metrics->height;
+      TT_Int  glyph_size;
+      TT_Int  line_bits    = pix_bits * glyph_width;
+      TT_Bool pad_bytes    = 0;
+
+
+      /* compute size of glyph image */
+      switch ( image_format )
+      {
+      case 1:  /* byte-padded formats */
+      case 6:
+        {
+          TT_Int  line_length;
+
+
+          switch ( pix_bits )
+          {
+          case 1:  line_length = (glyph_width+7) >> 3;   break;
+          case 2:  line_length = (glyph_width+3) >> 2;   break;
+          case 4:  line_length = (glyph_width+1) >> 1;   break;
+          default: line_length =  glyph_width;
+          }
+
+          glyph_size = glyph_height * line_length;
+          pad_bytes  = 1;
+        }
+        break;
+
+      case 2:
+      case 5:
+      case 7:
+        line_bits  =  glyph_width * pix_bits;
+        glyph_size = (glyph_height * line_bits + 7) >> 3;
+        break;
+
+      default:  /* invalid format */
+        return TT_Err_Invalid_File_Format;
+      }
+
+      /* Now read data and draw glyph into target pixmap       */
+      if ( ACCESS_Frame( glyph_size ) )
+        goto Exit;
+
+      /* don't forget to multiply `x_offset' by `map->pix_bits' as */
+      /* the sbit blitter doesn't make a difference between pixmap */
+      /* depths.                                                   */
+      blit_sbit( map, stream->cursor, line_bits, pad_bytes,
+                 x_offset * pix_bits, y_offset );
+
+      FORGET_Frame();
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  static
+  TT_Error Load_SBit_Image( TT_SBit_Strike*   strike,
+                            TT_SBit_Range*    range,
+                            TT_ULong          ebdt_pos,
+                            TT_ULong          glyph_offset,
+                            FT_Bitmap*        map,
+                            TT_Int            x_offset,
+                            TT_Int            y_offset,
+                            FT_Stream         stream,
+                            TT_SBit_Metrics*  metrics )
+  {
+    FT_Memory            memory = stream->memory;
+    TT_Error             error;
+
+
+    /* place stream at beginning of glyph data and read metrics */
+    if ( FILE_Seek( ebdt_pos + glyph_offset ) )
+      goto Exit;
+
+    error = Load_SBit_Metrics( stream, range, metrics );
+    if ( error )
+      goto Exit;
+
+    /* this function is recursive.  At the top-level call, the */
+    /* field map.buffer is NULL.  We thus begin by finding the */
+    /* dimensions of the higher-level glyph to allocate the    */
+    /* final pixmap buffer                                     */
+    if ( map->buffer == 0 )
+    {
+      TT_Long  size;
+
+
+      map->width    = metrics->width;
+      map->rows     = metrics->height;
+
+      switch ( strike->bit_depth )
+      {
+      case 1:
+        map->pixel_mode = ft_pixel_mode_mono; 
+        map->pitch      = (map->width+7) >> 3;
+        break;
+      case 2:
+        map->pixel_mode = ft_pixel_mode_pal2; 
+        map->pitch      = (map->width+3) >> 2;
+        break;
+      case 4:
+        map->pixel_mode = ft_pixel_mode_pal4; 
+        map->pitch      = (map->width+1) >> 1;
+        break;
+      case 8:
+        map->pixel_mode = ft_pixel_mode_grays; 
+        map->pitch      = map->width;
+        break;
+
+      default:
+        return TT_Err_Invalid_File_Format;
+      }
+
+      size = map->rows * map->pitch;
+
+      /* check that there is no empty image */
+      if ( size == 0 )
+        goto Exit;     /* exit successfully! */
+
+      if ( ALLOC( map->buffer, size ) )
+        goto Exit;
+    }
+
+    switch ( range->image_format )
+    {
+    case 1:  /* single sbit image - load it */
+    case 2:
+    case 5:
+    case 6:
+    case 7:
+      return Load_SBit_Single( map, x_offset, y_offset, strike->bit_depth,
+                               range->image_format, metrics, stream );
+
+    case 8:  /* compound format */
+    case 9:
+      break;
+
+    default: /* invalid image format */
+      return TT_Err_Invalid_File_Format;
+    }
+
+    /* All right, we're in a compound format.  First of all, read */
+    /* the array of elements                                      */
+    {
+      TT_SBit_Component*  components;
+      TT_SBit_Component*  comp;
+      TT_UShort           num_components, count;
+
+
+      if ( READ_UShort( num_components )                                ||
+           ALLOC_ARRAY( components, num_components, TT_SBit_Component ) )
+        goto Exit;
+
+      count = num_components;
+
+      if ( ACCESS_Frame( 4L * num_components ) )
+        goto Fail_Memory;
+
+      for ( comp = components; count > 0; count--, comp++ )
+      {
+        comp->glyph_code = GET_UShort();
+        comp->x_offset   = GET_Char();
+        comp->y_offset   = GET_Char();
+      }
+
+      FORGET_Frame();
+
+      /* Now recursively load each element glyph */
+      count = num_components;
+      comp  = components;
+      for ( ; count > 0; count--, comp++ )
+      {
+        TT_SBit_Range*   elem_range;
+        TT_SBit_Metrics  elem_metrics;
+        TT_ULong         elem_offset;
+
+
+        /* find the range for this element */
+        error = Find_SBit_Range( comp->glyph_code,
+                                 strike,
+                                 &elem_range,
+                                 &elem_offset );
+        if ( error )
+          goto Fail_Memory;
+
+        /* now load the element, recursively */
+        error = Load_SBit_Image( strike,
+                                 elem_range,
+                                 ebdt_pos,
+                                 elem_offset,
+                                 map,
+                                 x_offset + comp->x_offset,
+                                 y_offset + comp->y_offset,
+                                 stream,
+                                 &elem_metrics );
+        if ( error )
+          goto Fail_Memory;
+      }
+
+    Fail_Memory:
+      FREE( components );
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Image                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given glyph sbit image from the font resource.  This also  */
+  /*    returns its metrics.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: The target face object.                             */
+  /*                                                                       */
+  /*    x_ppem      :: The horizontal resolution in points per EM.         */
+  /*                                                                       */
+  /*    y_ppem      :: The vertical resolution in points per EM.           */
+  /*                                                                       */
+  /*    glyph_index :: The current glyph index.                            */
+  /*                                                                       */
+  /*    stream      :: The input stream.                                   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    map         :: The target pixmap.                                  */
+  /*    metrics     :: A big sbit metrics structure for the glyph image.   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.  Returns an error if no     */
+  /*    glyph sbit exists for the index.                                   */
+  /*                                                                       */
+  /*  <Note>                                                               */
+  /*    The `map.buffer' field is always freed before the glyph is loaded. */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_SBit_Image( TT_Face           face,
+                                TT_Int            x_ppem,
+                                TT_Int            y_ppem,
+                                TT_UInt           glyph_index,
+                                FT_Stream         stream,
+                                FT_Bitmap*        map,
+                                TT_SBit_Metrics*  metrics )
+  {
+    TT_Error         error;
+    FT_Memory        memory = stream->memory;
+    TT_ULong         ebdt_pos, glyph_offset;
+
+    TT_SBit_Strike*  strike;
+    TT_SBit_Range*   range;
+
+
+    /* Check whether there is a glyph sbit for the current index */
+    error = Find_SBit_Image( face, glyph_index, x_ppem, y_ppem,
+                             &range, &strike, &glyph_offset );
+    if ( error )
+      goto Exit;
+
+    /* now, find the location of the `EBDT' table in */
+    /* the font file                                 */
+    {
+      TT_Long  table = TT_LookUp_Table( face, TTAG_EBDT );
+
+
+      if ( table < 0 )
+      {
+        error = TT_Err_Invalid_File_Format;
+        goto Exit;
+      }
+
+      ebdt_pos = face->dir_tables[table].Offset;
+    }
+
+    /* clear the bitmap & load the bitmap */
+    FREE( map->buffer );
+    map->rows = map->pitch = map->width = 0;
+
+    error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
+                             map, 0, 0, stream, metrics );
+    if ( error )
+      goto Exit;
+
+    /* setup vertical metrics if needed */
+    if ( strike->flags & 1 )
+    {
+      /* in case of a horizontal strike only */
+      FT_Int  advance;
+      FT_Int  top;
+
+
+      advance = strike->hori.ascender - strike->hori.descender;
+      top     = advance / 10;
+
+      metrics->vertBearingX = -metrics->width / 2;
+      metrics->vertBearingY =  advance / 10;
+      metrics->vertAdvance  =  advance * 12 / 10;
+    }
+
+    /* Crop the bitmap now */
+    Crop_Bitmap( map, metrics );
+
+  Exit:
+    return error;
+  }
+
+
+/* END */
diff --git a/src/shared/sfnt/ttsbit.h b/src/shared/sfnt/ttsbit.h
new file mode 100644
index 0000000..414ceae
--- /dev/null
+++ b/src/shared/sfnt/ttsbit.h
@@ -0,0 +1,104 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttsbit.h                                                               */
+/*                                                                         */
+/*    TrueType and OpenType embedded bitmap support (specification).       */
+/*                                                                         */
+/*  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 TTSBIT_H
+#define TTSBIT_H
+
+#include <ttload.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Strikes                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the table of embedded bitmap sizes for this face.            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: The target face object.                                  */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_SBit_Strikes( TT_Face    face,
+                                  FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Free_SBit_Strikes                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Releases the embedded bitmap tables.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: The target face object.                                    */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Free_SBit_Strikes( TT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_SBit_Image                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a given glyph sbit image from the font resource.  This also  */
+  /*    returns its metrics.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: The target face object.                             */
+  /*                                                                       */
+  /*    x_ppem      :: The horizontal resolution in points per EM.         */
+  /*                                                                       */
+  /*    y_ppem      :: The vertical resolution in points per EM.           */
+  /*                                                                       */
+  /*    glyph_index :: The current glyph index.                            */
+  /*                                                                       */
+  /*    stream      :: The input stream.                                   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    map         :: The target pixmap.                                  */
+  /*    metrics     :: A big sbit metrics structure for the glyph image.   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.  Returns an error if no     */
+  /*    glyph sbit exists for the index.                                   */
+  /*                                                                       */
+  /*  <Note>                                                               */
+  /*    The `map.buffer' field is always freed before the glyph is loaded. */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_SBit_Image( TT_Face           face,
+                                TT_Int            x_ppem,
+                                TT_Int            y_ppem,
+                                TT_UInt           glyph_index,
+                                FT_Stream         stream,
+                                FT_Bitmap*        map,
+                                TT_SBit_Metrics*  metrics );
+
+
+#endif /* TTSBIT_H */
+
+
+/* END */
diff --git a/src/shared/sfnt/tttypes.h b/src/shared/sfnt/tttypes.h
new file mode 100644
index 0000000..33b2453
--- /dev/null
+++ b/src/shared/sfnt/tttypes.h
@@ -0,0 +1,1848 @@
+/***************************************************************************/
+/*                                                                         */
+/*  tttypes.h                                                              */
+/*                                                                         */
+/*    Basic SFNT/TrueType type definitions and interface (specification    */
+/*    only).                                                               */
+/*                                                                         */
+/*  This code is shared by all TrueType and OpenType drivers.              */
+/*                                                                         */
+/*                                                                         */
+/*  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 TTTYPES_H
+#define TTTYPES_H
+
+
+#include <freetype.h>
+
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***                DEFINITIONS OF BASIC DATA TYPES                    ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The REDEFINE() macro is used to convert a FreeType generic type into  */
+  /* a TrueType-specific one.  It simply replaces the `FT_' prefix by      */
+  /* `TT_' in order to define compatible types like TT_Long, TT_Error,     */
+  /* TT_Outline, etc.                                                      */
+  /*                                                                       */
+#undef  REDEFINE
+#define REDEFINE( type )  typedef FT_##type  TT_##type
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Bool                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef of unsigned char, used for simple booleans.              */
+  /*                                                                       */
+  REDEFINE( Bool );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_FWord                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 16-bit integer used to store a distance in original font  */
+  /*    units.                                                             */
+  /*                                                                       */
+  REDEFINE( FWord );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_UFWord                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An unsigned 16-bit integer used to store a distance in original    */
+  /*    font units.                                                        */
+  /*                                                                       */
+  REDEFINE( UFWord );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Char                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the _signed_ char type.                       */
+  /*                                                                       */
+  REDEFINE( Char );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Byte                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the _unsigned_ char type.                     */
+  /*                                                                       */
+  REDEFINE( Byte );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_String                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the char type, usually used for strings.      */
+  /*                                                                       */
+  REDEFINE( String );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Short                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for signed short.                                        */
+  /*                                                                       */
+  REDEFINE( Short );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_UShort                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for unsigned short.                                      */
+  /*                                                                       */
+  REDEFINE( UShort );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Int                                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for the int type.                                        */
+  /*                                                                       */
+  REDEFINE( Int );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_UInt                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for the unsigned int type.                               */
+  /*                                                                       */
+  REDEFINE( UInt );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Long                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for signed long.                                         */
+  /*                                                                       */
+  REDEFINE( Long );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_ULong                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for unsigned long.                                       */
+  /*                                                                       */
+  REDEFINE( ULong );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_F2Dot14                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 2.14 fixed float type used for unit vectors.              */
+  /*                                                                       */
+  REDEFINE( F2Dot14 );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_F26Dot6                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 26.6 fixed float type used for vectorial pixel            */
+  /*    coordinates.                                                       */
+  /*                                                                       */
+  REDEFINE( F26Dot6 );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Fixed                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This type is used to store 16.16 fixed float values, like scales   */
+  /*    or matrix coefficients.                                            */
+  /*                                                                       */
+  REDEFINE( Fixed );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Pos                                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The type FT_Pos is a 32-bit integer used to store vectorial        */
+  /*    coordinates.  Depending on the context, these can represent        */
+  /*    distances in integer font units, or 26.6 fixed float pixel         */
+  /*    coordinates.                                                       */
+  /*                                                                       */
+  REDEFINE( Pos );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Vector                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2d vector; coordinates are of   */
+  /*    the TT_Pos type.                                                   */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    x :: The horizontal coordinate.                                    */
+  /*    y :: The vertical coordinate.                                      */
+  /*                                                                       */
+  REDEFINE( Vector );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_UnitVector                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2d vector unit vector.  Uses    */
+  /*    TT_F2Dot14 types.                                                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    x :: Horizontal coordinate.                                        */
+  /*    y :: Vertical coordinate.                                          */
+  /*                                                                       */
+  REDEFINE( UnitVector );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Matrix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2x2 matrix.  Coefficients are   */
+  /*    in 16.16 fixed float format.  The computation performed is:        */
+  /*                                                                       */
+  /*       {                                                               */
+  /*          x' = x*xx + y*xy                                             */
+  /*          y' = x*yx + y*yy                                             */
+  /*       }                                                               */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    xx :: Matrix coefficient.                                          */
+  /*    xy :: Matrix coefficient.                                          */
+  /*    yx :: Matrix coefficient.                                          */
+  /*    yy :: Matrix coefficient.                                          */
+  /*                                                                       */
+  REDEFINE( Matrix );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_BBox                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold an outline's bounding box, i.e., the      */
+  /*    coordinates of its extrema in the horizontal and vertical          */
+  /*    directions.                                                        */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    xMin :: The horizontal minimum (left-most).                        */
+  /*    yMin :: The vertical minimum (bottom-most).                        */
+  /*    xMax :: The horizontal maximum (right-most).                       */
+  /*    yMax :: The vertical maximum (top-most).                           */
+  /*                                                                       */
+  REDEFINE( BBox );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Error                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType error code type.  A value of 0 is always interpreted  */
+  /*    as a successful operation.                                         */
+  /*                                                                       */
+  REDEFINE( Error );
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***             REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS         ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TTC_Header                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    TrueType collection header.  This table contains the offsets of    */
+  /*    the font headers of each distinct TrueType face in the file.       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    tag     :: Must be `ttc ' to indicate a TrueType collection.       */
+  /*    version :: The version number.                                     */
+  /*    count   :: The number of faces in the collection.  The             */
+  /*               specification says this should be an unsigned long, but */
+  /*               we use a signed long since we need the value -1 for     */
+  /*               specific purposes.                                      */
+  /*    offsets :: The offsets of the font headers, one per face.          */
+  /*                                                                       */
+  typedef struct  TTC_Header_
+  {
+    TT_ULong   Tag;
+    TT_Fixed   version;
+    TT_Long    DirCount;
+    TT_ULong*  TableDirectory;
+
+  } TTC_Header;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_TableDir                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This structure models a TrueType table directory.  It is used to   */
+  /*    access the various tables of the font face.                        */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    version       :: The version number; starts with 0x00010000.       */
+  /*    numTables     :: The number of tables.                             */
+  /*                                                                       */
+  /*    searchRange   :: Unused.                                           */
+  /*    entrySelector :: Unused.                                           */
+  /*    rangeShift    :: Unused.                                           */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This structure is only used during font opening.                   */
+  /*                                                                       */
+  typedef struct  TT_TableDir_
+  {
+    TT_Fixed   version;      /* should be 0x10000 */
+    TT_UShort  numTables;    /* number of tables  */
+
+    TT_UShort  searchRange;    /* These parameters are only used  */
+    TT_UShort  entrySelector;  /* for a dichotomy search in the   */
+    TT_UShort  rangeShift;     /* directory.  We ignore them.     */
+
+  } TT_TableDir;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_TableDirEntry                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This structure describes a given table of a TrueType font.         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    Tag      :: A four-bytes tag describing the table.                 */
+  /*    CheckSum :: The table checksum.  This value can be ignored.        */
+  /*    Offset   :: The offset of the table from the start of the TrueType */
+  /*                font in its resource.                                  */
+  /*    Length   :: The table length (in bytes).                           */
+  /*                                                                       */
+  typedef struct  TT_TableDirEntry_
+  {
+    TT_ULong  Tag;        /*        table type */
+    TT_ULong  CheckSum;   /*    table checksum */
+    TT_ULong  Offset;     /* table file offset */
+    TT_ULong  Length;     /*      table length */
+
+  } TT_TableDirEntry;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Header                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType font header table.  All       */
+  /*    fields follow the TrueType specification.                          */
+  /*                                                                       */
+  typedef struct  TT_Header_
+  {
+    TT_Fixed   Table_Version;
+    TT_Fixed   Font_Revision;
+
+    TT_Long    CheckSum_Adjust;
+    TT_Long    Magic_Number;
+
+    TT_UShort  Flags;
+    TT_UShort  Units_Per_EM;
+
+    TT_Long    Created [2];
+    TT_Long    Modified[2];
+
+    TT_FWord   xMin;
+    TT_FWord   yMin;
+    TT_FWord   xMax;
+    TT_FWord   yMax;
+
+    TT_UShort  Mac_Style;
+    TT_UShort  Lowest_Rec_PPEM;
+
+    TT_Short   Font_Direction;
+    TT_Short   Index_To_Loc_Format;
+    TT_Short   Glyph_Data_Format;
+
+  } TT_Header;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_HoriHeader                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType horizontal header, the `hhea' */
+  /*    table, as well as the corresponding horizontal metrics table,      */
+  /*    i.e., the `hmtx' table.                                            */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    Version                :: The table version.                       */
+  /*                                                                       */
+  /*    Ascender               :: The font's ascender, i.e., the distance  */
+  /*                              from the baseline to the top-most of all */
+  /*                              glyph points found in the font.          */
+  /*                                                                       */
+  /*                              This value is invalid in many fonts, as  */
+  /*                              it is usually set by the font designer,  */
+  /*                              and often reflects only a portion of the */
+  /*                              glyphs found in the font (maybe ASCII).  */
+  /*                                                                       */
+  /*                              You should use the `sTypoAscender' field */
+  /*                              of the OS/2 table instead if you want    */
+  /*                              the correct one.                         */
+  /*                                                                       */
+  /*    Descender              :: The font's descender, i.e., the distance */
+  /*                              from the baseline to the bottom-most of  */
+  /*                              all glyph points found in the font.  It  */
+  /*                              is negative.                             */
+  /*                                                                       */
+  /*                              This value is invalid in many fonts, as  */
+  /*                              it is usually set by the font designer,  */
+  /*                              and often reflects only a portion of the */
+  /*                              glyphs found in the font (maybe ASCII).  */
+  /*                                                                       */
+  /*                              You should use the `sTypoDescender'      */
+  /*                              field of the OS/2 table instead if you   */
+  /*                              want the correct one.                    */
+  /*                                                                       */
+  /*    Line_Gap               :: The font's line gap, i.e., the distance  */
+  /*                              to add to the ascender and descender to  */
+  /*                              get the BTB, i.e., the                   */
+  /*                              baseline-to-baseline distance for the    */
+  /*                              font.                                    */
+  /*                                                                       */
+  /*    advance_Width_Max      :: This field is the maximum of all advance */
+  /*                              widths found in the font.  It can be     */
+  /*                              used to compute the maximum width of an  */
+  /*                              arbitrary string of text.                */
+  /*                                                                       */
+  /*    min_Left_Side_Bearing  :: The minimum left side bearing of all     */
+  /*                              glyphs within the font.                  */
+  /*                                                                       */
+  /*    min_Right_Side_Bearing :: The minimum right side bearing of all    */
+  /*                              glyphs within the font.                  */
+  /*                                                                       */
+  /*    xMax_Extent            :: The maximum horizontal extent (i.e., the */
+  /*                              `width' of a glyph's bounding box) for   */
+  /*                              all glyphs in the font.                  */
+  /*                                                                       */
+  /*    caret_Slope_Rise       :: The rise coefficient of the cursor's     */
+  /*                              slope of the cursor (slope=rise/run).    */
+  /*                                                                       */
+  /*    caret_Slope_Run        :: The run coefficient of the cursor's      */
+  /*                              slope.                                   */
+  /*                                                                       */
+  /*    Reserved               :: 10 reserved bytes.                       */
+  /*                                                                       */
+  /*    metric_Data_Format     :: Always 0.                                */
+  /*                                                                       */
+  /*    number_Of_HMetrics     :: Number of HMetrics entries in the `hmtx' */
+  /*                              table -- this value can be smaller than  */
+  /*                              the total number of glyphs in the font.  */
+  /*                                                                       */
+  /*    long_metrics           :: A pointer into the `hmtx' table.         */
+  /*                                                                       */
+  /*    short_metrics          :: A pointer into the `hmtx' table.         */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
+  /*               be identical except for the names of their fields which */
+  /*               are different.                                          */
+  /*                                                                       */
+  /*               This ensures that a single function in the `ttload'     */
+  /*               module is able to read both the horizontal and vertical */
+  /*               headers.                                                */
+  /*                                                                       */
+  typedef struct  TT_HoriHeader_
+  {
+    TT_Fixed   Version;
+    TT_FWord   Ascender;
+    TT_FWord   Descender;
+    TT_FWord   Line_Gap;
+
+    TT_UFWord  advance_Width_Max;      /* advance width maximum */
+
+    TT_FWord   min_Left_Side_Bearing;  /* minimum left-sb       */
+    TT_FWord   min_Right_Side_Bearing; /* minimum right-sb      */
+    TT_FWord   xMax_Extent;            /* xmax extents          */
+    TT_FWord   caret_Slope_Rise;
+    TT_FWord   caret_Slope_Run;
+    TT_FWord   caret_Offset;
+
+    TT_Short   Reserved[4];
+
+    TT_Short   metric_Data_Format;
+    TT_UShort  number_Of_HMetrics;
+
+    /* The following fields are not defined by the TrueType specification */
+    /* but they're used to connect the metrics header to the relevant     */
+    /* `HMTX' table.                                                      */
+
+    void*      long_metrics;
+    void*      short_metrics;
+
+  } TT_HoriHeader;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_VertHeader                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType vertical header, the `vhea'   */
+  /*    table, as well as the corresponding vertical metrics table, i.e.,  */
+  /*    the `vmtx' table.                                                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    Version                 :: The table version.                      */
+  /*                                                                       */
+  /*    Ascender                :: The font's ascender, i.e., the distance */
+  /*                               from the baseline to the top-most of    */
+  /*                               all glyph points found in the font.     */
+  /*                                                                       */
+  /*                               This value is invalid in many fonts, as */
+  /*                               it is usually set by the font designer, */
+  /*                               and often reflects only a portion of    */
+  /*                               the glyphs found in the font (maybe     */
+  /*                               ASCII).                                 */
+  /*                                                                       */
+  /*                               You should use the `sTypoAscender'      */
+  /*                               field of the OS/2 table instead if you  */
+  /*                               want the correct one.                   */
+  /*                                                                       */
+  /*    Descender               :: The font's descender, i.e., the         */
+  /*                               distance from the baseline to the       */
+  /*                               bottom-most of all glyph points found   */
+  /*                               in the font.  It is negative.           */
+  /*                                                                       */
+  /*                               This value is invalid in many fonts, as */
+  /*                               it is usually set by the font designer, */
+  /*                               and often reflects only a portion of    */
+  /*                               the glyphs found in the font (maybe     */
+  /*                               ASCII).                                 */
+  /*                                                                       */
+  /*                               You should use the `sTypoDescender'     */
+  /*                               field of the OS/2 table instead if you  */
+  /*                               want the correct one.                   */
+  /*                                                                       */
+  /*    Line_Gap                :: The font's line gap, i.e., the distance */
+  /*                               to add to the ascender and descender to */
+  /*                               get the BTB, i.e., the                  */
+  /*                               baseline-to-baseline distance for the   */
+  /*                               font.                                   */
+  /*                                                                       */
+  /*    advance_Height_Max      :: This field is the maximum of all        */
+  /*                               advance heights found in the font.  It  */
+  /*                               can be used to compute the maximum      */
+  /*                               height of an arbitrary string of text.  */
+  /*                                                                       */
+  /*    min_Top_Side_Bearing    :: The minimum top side bearing of all     */
+  /*                               glyphs within the font.                 */
+  /*                                                                       */
+  /*    min_Bottom_Side_Bearing :: The minimum bottom side bearing of all  */
+  /*                               glyphs within the font.                 */
+  /*                                                                       */
+  /*    yMax_Extent             :: The maximum vertical extent (i.e., the  */
+  /*                               `height' of a glyph's bounding box) for */
+  /*                               all glyphs in the font.                 */
+  /*                                                                       */
+  /*    caret_Slope_Rise        :: The rise coefficient of the cursor's    */
+  /*                               slope of the cursor (slope=rise/run).   */
+  /*                                                                       */
+  /*    caret_Slope_Run         :: The run coefficient of the cursor's     */
+  /*                               slope.                                  */
+  /*                                                                       */
+  /*    Reserved                :: 10 reserved bytes.                      */
+  /*                                                                       */
+  /*    metric_Data_Format      :: Always 0.                               */
+  /*                                                                       */
+  /*    number_Of_HMetrics      :: Number of VMetrics entries in the       */
+  /*                               `vmtx' table -- this value can be       */
+  /*                               smaller than the total number of glyphs */
+  /*                               in the font.                            */
+  /*                                                                       */
+  /*    long_metrics           :: A pointer into the `vmtx' table.         */
+  /*                                                                       */
+  /*    short_metrics          :: A pointer into the `vmtx' table.         */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
+  /*               be identical except for the names of their fields which */
+  /*               are different.                                          */
+  /*                                                                       */
+  /*               This ensures that a single function in the `ttload'     */
+  /*               module is able to read both the horizontal and vertical */
+  /*               headers.                                                */
+  /*                                                                       */
+  typedef struct TT_VertHeader_
+  {
+    TT_Fixed   Version;
+    TT_FWord   Ascender;
+    TT_FWord   Descender;
+    TT_FWord   Line_Gap;
+
+    TT_UFWord  advance_Height_Max;      /* advance height maximum */
+
+    TT_FWord   min_Top_Side_Bearing;    /* minimum left-sb or top-sb       */
+    TT_FWord   min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb   */
+    TT_FWord   yMax_Extent;             /* xmax or ymax extents            */
+    TT_FWord   caret_Slope_Rise;
+    TT_FWord   caret_Slope_Run;
+    TT_FWord   caret_Offset;
+
+    TT_Short   Reserved[4];
+
+    TT_Short   metric_Data_Format;
+    TT_UShort  number_Of_VMetrics;
+
+    /* The following fields are not defined by the TrueType specification */
+    /* but they're used to connect the metrics header to the relevant     */
+    /* `HMTX' or `VMTX' table.                                            */
+
+    void*      long_metrics;
+    void*      short_metrics;
+
+  } TT_VertHeader;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_OS2                                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType OS/2 table. This is the long  */
+  /*    table version.  All fields comply to the TrueType specification.   */
+  /*                                                                       */
+  /*    Note that we now support old Mac fonts which do not include an     */
+  /*    OS/2 table.  In this case, the `version' field is always set to    */
+  /*    0xFFFF.                                                            */
+  /*                                                                       */
+  typedef struct  TT_OS2_
+  {
+    TT_UShort  version;                /* 0x0001 - more or 0xFFFF */
+    TT_FWord   xAvgCharWidth;
+    TT_UShort  usWeightClass;
+    TT_UShort  usWidthClass;
+    TT_Short   fsType;
+    TT_FWord   ySubscriptXSize;
+    TT_FWord   ySubscriptYSize;
+    TT_FWord   ySubscriptXOffset;
+    TT_FWord   ySubscriptYOffset;
+    TT_FWord   ySuperscriptXSize;
+    TT_FWord   ySuperscriptYSize;
+    TT_FWord   ySuperscriptXOffset;
+    TT_FWord   ySuperscriptYOffset;
+    TT_FWord   yStrikeoutSize;
+    TT_FWord   yStrikeoutPosition;
+    TT_Short   sFamilyClass;
+
+    TT_Byte    panose[10];
+
+    TT_ULong   ulUnicodeRange1;        /* Bits 0-31   */
+    TT_ULong   ulUnicodeRange2;        /* Bits 32-63  */
+    TT_ULong   ulUnicodeRange3;        /* Bits 64-95  */
+    TT_ULong   ulUnicodeRange4;        /* Bits 96-127 */
+
+    TT_Char    achVendID[4];
+
+    TT_UShort  fsSelection;
+    TT_UShort  usFirstCharIndex;
+    TT_UShort  usLastCharIndex;
+    TT_Short   sTypoAscender;
+    TT_Short   sTypoDescender;
+    TT_Short   sTypoLineGap;
+    TT_UShort  usWinAscent;
+    TT_UShort  usWinDescent;
+
+    /* only version 1 tables: */
+
+    TT_ULong   ulCodePageRange1;       /* Bits 0-31   */
+    TT_ULong   ulCodePageRange2;       /* Bits 32-63  */
+
+  } TT_OS2;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Postscript                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType Postscript table.  All fields */
+  /*    comply to the TrueType table.  This structure does not reference   */
+  /*    the Postscript glyph names, which can be nevertheless accessed     */
+  /*    with the `ttpost' module.                                          */
+  /*                                                                       */
+  typedef struct  TT_Postscript_
+  {
+    TT_Fixed  FormatType;
+    TT_Fixed  italicAngle;
+    TT_FWord  underlinePosition;
+    TT_FWord  underlineThickness;
+    TT_ULong  isFixedPitch;
+    TT_ULong  minMemType42;
+    TT_ULong  maxMemType42;
+    TT_ULong  minMemType1;
+    TT_ULong  maxMemType1;
+
+    /* Glyph names follow in the file, but we don't   */
+    /* load them by default.  See the ttpost.c file.  */
+
+  } TT_Postscript;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_CMapDir                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This structure describes the directory of the `cmap' table,        */
+  /*    containing the font's character mappings table.                    */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    tableVersionNumber :: The version number.                          */
+  /*    numCMaps           :: The number of charmaps in the font.          */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This structure is only used during font loading.                   */
+  /*                                                                       */
+  typedef struct  TT_CMapDir_
+  {
+    TT_UShort  tableVersionNumber;
+    TT_UShort  numCMaps;
+
+  } TT_CMapDir;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_CMapDirEntry                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This structure describes a charmap in a TrueType font.             */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    platformID :: An ID used to specify for which platform this        */
+  /*                  charmap is defined (FreeType manages all platforms). */
+  /*                                                                       */
+  /*    encodingID :: A platform-specific ID used to indicate which source */
+  /*                  encoding is used in this charmap.                    */
+  /*                                                                       */
+  /*    offset ::     The offset of the charmap relative to the start of   */
+  /*                  the `cmap' table.                                    */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This structure is only used during font loading.                   */
+  /*                                                                       */
+  typedef struct  TT_CMapDirEntry_
+  {
+    TT_UShort  platformID;
+    TT_UShort  platformEncodingID;
+    TT_Long    offset;
+
+  } TT_CMapDirEntry;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_MaxProfile                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The maximum profile is a table containing many max values which    */
+  /*    can be used to pre-allocate arrays.  This ensures that no memory   */
+  /*    allocation occurs during a glyph load.                             */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    version               :: The version number.                       */
+  /*                                                                       */
+  /*    numGlyphs             :: The number of glyphs in this TrueType     */
+  /*                             font.                                     */
+  /*                                                                       */
+  /*    maxPoints             :: The maximum number of points in a         */
+  /*                             non-composite TrueType glyph.  See also   */
+  /*                             the structure element                     */
+  /*                             `maxCompositePoints'.                     */
+  /*                                                                       */
+  /*    maxContours           :: The maximum number of contours in a       */
+  /*                             non-composite TrueType glyph.  See also   */
+  /*                             the structure element                     */
+  /*                             `maxCompositeContours'.                   */
+  /*                                                                       */
+  /*    maxCompositePoints    :: The maximum number of points in a         */
+  /*                             composite TrueType glyph.  See also the   */
+  /*                             structure element `maxPoints'.            */
+  /*                                                                       */
+  /*    maxCompositeContours  :: The maximum number of contours in a       */
+  /*                             composite TrueType glyph.  See also the   */
+  /*                             structure element `maxContours'.          */
+  /*                                                                       */
+  /*    maxZones              :: The maximum number of zones used for      */
+  /*                             glyph hinting.                            */
+  /*                                                                       */
+  /*    maxTwilightPoints     :: The maximum number of points in the       */
+  /*                             twilight zone used for glyph hinting.     */
+  /*                                                                       */
+  /*    maxStorage            :: The maximum number of elements in the     */
+  /*                             storage area used for glyph hinting.      */
+  /*                                                                       */
+  /*    maxFunctionDefs       :: The maximum number of function            */
+  /*                             definitions in the TrueType bytecode for  */
+  /*                             this font.                                */
+  /*                                                                       */
+  /*    maxInstructionDefs    :: The maximum number of instruction         */
+  /*                             definitions in the TrueType bytecode for  */
+  /*                             this font.                                */
+  /*                                                                       */
+  /*    maxStackElements      :: The maximum number of stack elements used */
+  /*                             during bytecode interpretation.           */
+  /*                                                                       */
+  /*    maxSizeOfInstructions :: The maximum number of TrueType opcodes    */
+  /*                             used for glyph hinting.                   */
+  /*                                                                       */
+  /*    maxComponentElements  :: An obscure value related to composite     */
+  /*                             glyphs definitions.                       */
+  /*                                                                       */
+  /*    maxComponentDepth     :: An obscure value related to composite     */
+  /*                             glyphs definitions.  Probably the maximum */
+  /*                             number of simple glyphs in a composite.   */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This structure is only used during font loading.                   */
+  /*                                                                       */
+  typedef struct  TT_MaxProfile_
+  {
+    TT_Fixed   version;
+    TT_UShort  numGlyphs;
+    TT_UShort  maxPoints;
+    TT_UShort  maxContours;
+    TT_UShort  maxCompositePoints;
+    TT_UShort  maxCompositeContours;
+    TT_UShort  maxZones;
+    TT_UShort  maxTwilightPoints;
+    TT_UShort  maxStorage;
+    TT_UShort  maxFunctionDefs;
+    TT_UShort  maxInstructionDefs;
+    TT_UShort  maxStackElements;
+    TT_UShort  maxSizeOfInstructions;
+    TT_UShort  maxComponentElements;
+    TT_UShort  maxComponentDepth;
+
+  } TT_MaxProfile;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_LongMetrics                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure modeling the long metrics of the `hmtx' and `vmtx'     */
+  /*    TrueType tables.  The values are expressed in font units.          */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    advance :: The advance width or height for the glyph.              */
+  /*    bearing :: The left-side or top-side bearing for the glyph.        */
+  /*                                                                       */
+  typedef struct  TT_LongMetrics_
+  {
+    TT_UShort  advance;
+    TT_Short   bearing;
+
+  } TT_LongMetrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type> TT_ShortMetrics                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple type to model the short metrics of the `hmtx' and `vmtx'  */
+  /*    tables.                                                            */
+  /*                                                                       */
+  typedef TT_Short  TT_ShortMetrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_NameRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure modeling TrueType name records.  Name records are used */
+  /*    to store important strings like family name, style name,           */
+  /*    copyright, etc. in _localized_ versions (i.e., language, encoding, */
+  /*    etc).                                                              */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    platformID   :: The ID of the name's encoding platform.            */
+  /*                                                                       */
+  /*    encodingID   :: The platform-specific ID for the name's encoding.  */
+  /*                                                                       */
+  /*    languageID   :: The platform-specific ID for the name's language.  */
+  /*                                                                       */
+  /*    nameID       :: The ID specifying what kind of name this is.       */
+  /*                                                                       */
+  /*    stringLength :: The length of the string in bytes.                 */
+  /*                                                                       */
+  /*    stringOffset :: The offset to the string in the `name' table.      */
+  /*                                                                       */
+  /*    string       :: A pointer to the string's bytes.  Note that these  */
+  /*                    are usually UTF-16 encoded characters.             */
+  /*                                                                       */
+  typedef struct  TT_NameRec_
+  {
+    TT_UShort  platformID;
+    TT_UShort  encodingID;
+    TT_UShort  languageID;
+    TT_UShort  nameID;
+    TT_UShort  stringLength;
+    TT_UShort  stringOffset;
+
+    /* this last field is not defined in the spec */
+    /* but used by the FreeType engine            */
+
+    TT_Byte*   string;
+
+  } TT_NameRec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_NameTable                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure modeling the TrueType name table.                      */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    format         :: The format of the name table.                    */
+  /*                                                                       */
+  /*    numNameRecords :: The number of names in table.                    */
+  /*                                                                       */
+  /*    storageOffset  :: The offset of the name table in the `name'       */
+  /*                      TrueType table.                                  */
+  /*                                                                       */
+  /*    names          :: An array of name records.                        */
+  /*                                                                       */
+  /*    storage        :: The names storage area.                          */
+  /*                                                                       */
+  typedef struct  TT_NameTable_
+  {
+    TT_UShort    format;
+    TT_UShort    numNameRecords;
+    TT_UShort    storageOffset;
+    TT_NameRec*  names;
+    TT_Byte*     storage;
+
+  } TT_NameTable;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***             OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS         ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_GaspRange                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A tiny structure used to model a gasp range according to the       */
+  /*    TrueType specification.                                            */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    maxPPEM  :: The maximum ppem value to which `gaspFlag' applies.    */
+  /*                                                                       */
+  /*    gaspFlag :: A flag describing the grid-fitting and anti-aliasing   */
+  /*                modes to be used.                                      */
+  /*                                                                       */
+  typedef struct  TT_GaspRange_
+  {
+    TT_UShort  maxPPEM;
+    TT_UShort  gaspFlag;
+
+  } TT_GaspRange;
+
+
+#define TT_GASP_GRIDFIT  0x01
+#define TT_GASP_DOGRAY   0x02
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Gasp                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure modeling the TrueType `gasp' table used to specify     */
+  /*    grid-fitting and anti-aliasing behaviour.                          */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    version    :: The version number.                                  */
+  /*    numRanges  :: The number of gasp ranges in table.                  */
+  /*    gaspRanges :: An array of gasp ranges.                             */
+  /*                                                                       */
+  typedef struct  TT_Gasp_
+  {
+    TT_UShort      version;
+    TT_UShort      numRanges;
+    TT_GaspRange*  gaspRanges;
+
+  } TT_Gasp;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_HdmxRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A small structure used to model the pre-computed widths of a given */
+  /*    size.  They're found in the `hdmx' table.                          */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    ppem      :: The pixels per EM value at which these metrics apply. */
+  /*                                                                       */
+  /*    max_width :: The maximum advance width for this metric.            */
+  /*                                                                       */
+  /*    widths    :: An array of widths.  Note: These are 8-bit bytes.     */
+  /*                                                                       */
+  typedef struct  TT_HdmxRec_
+  {
+    TT_Byte   ppem;
+    TT_Byte   max_width;
+    TT_Byte*  widths;
+
+  } TT_HdmxRec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_HdmxRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model the `hdmx' table, which contains         */
+  /*    pre-computed widths for a set of given sizes/dimensions.           */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    version     :: The version number.                                 */
+  /*    num_records :: The number of hdmx records.                         */
+  /*    records     :: An array of hdmx records.                           */
+  /*                                                                       */
+  typedef struct  TT_Hdmx_
+  {
+    TT_UShort    version;
+    TT_Short     num_records;
+    TT_HdmxRec*  records;
+
+  } TT_Hdmx;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Kern_0_Pair                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a kerning pair for the kerning table     */
+  /*    format 0.  The engine now loads this table if it finds one in the  */
+  /*    font file.                                                         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    left  :: The index of the left glyph in pair.                      */
+  /*    right :: The index of the right glyph in pair.                     */
+  /*    value :: The kerning distance.  A positive value spaces the        */
+  /*             glyphs, a negative one makes them closer.                 */
+  /*                                                                       */
+  typedef struct  TT_Kern_0_Pair_
+  {
+    TT_UShort  left;   /* index of left  glyph in pair */
+    TT_UShort  right;  /* index of right glyph in pair */
+    TT_FWord   value;  /* kerning value                */
+
+  } TT_Kern_0_Pair;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Metrics                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold the big metrics of a given glyph bitmap   */
+  /*    in a TrueType or OpenType font.  These are usually found in the    */
+  /*    `EBDT' (Microsoft) or `bdat' (Apple) table.                        */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    height       :: The glyph height in pixels.                        */
+  /*                                                                       */
+  /*    width        :: The glyph width in pixels.                         */
+  /*                                                                       */
+  /*    horiBearingX :: The horizontal left bearing.                       */
+  /*                                                                       */
+  /*    horiBearingY :: The horizontal top bearing.                        */
+  /*                                                                       */
+  /*    horiAdvance  :: The horizontal advance.                            */
+  /*                                                                       */
+  /*    vertBearingX :: The vertical left bearing.                         */
+  /*                                                                       */
+  /*    vertBearingY :: The vertical top bearing.                          */
+  /*                                                                       */
+  /*    vertAdvance  :: The vertical advance.                              */
+  /*                                                                       */
+  typedef struct  TT_SBit_Metrics_
+  {
+    TT_Byte  height;
+    TT_Byte  width;
+
+    TT_Char  horiBearingX;
+    TT_Char  horiBearingY;
+    TT_Byte  horiAdvance;
+
+    TT_Char  vertBearingX;
+    TT_Char  vertBearingY;
+    TT_Byte  vertAdvance;
+
+  } TT_SBit_Metrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Small_Metrics                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold the small metrics of a given glyph bitmap */
+  /*    in a TrueType or OpenType font.  These are usually found in the    */
+  /*    `EBDT' (Microsoft) or the `bdat' (Apple) table.                    */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    height    :: The glyph height in pixels.                           */
+  /*                                                                       */
+  /*    width     :: The glyph width in pixels.                            */
+  /*                                                                       */
+  /*    bearingX  :: The left-side bearing.                                */
+  /*                                                                       */
+  /*    bearingY  :: The top-side bearing.                                 */
+  /*                                                                       */
+  /*    advance   :: The advance width or height.                          */
+  /*                                                                       */
+  typedef struct  TT_SBit_Small_Metrics_
+  {
+    TT_Byte  height;
+    TT_Byte  width;
+
+    TT_Char  bearingX;
+    TT_Char  bearingY;
+    TT_Byte  advance;
+
+  } TT_SBit_Small_Metrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Line_Metrics                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to describe the text line metrics of a given      */
+  /*    bitmap strike, for either a horizontal or vertical layout.         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    ascender                :: The ascender in pixels.                 */
+  /*                                                                       */
+  /*    descender               :: The descender in pixels.                */
+  /*                                                                       */
+  /*    max_width               :: The maximum glyph width in pixels.      */
+  /*                                                                       */
+  /*    caret_slope_enumerator  :: Rise of the caret slope, typically set  */
+  /*                               to 1 for non-italic fonts.              */
+  /*                                                                       */
+  /*    caret_slope_denominator :: Rise of the caret slope, typically set  */
+  /*                               to 0 for non-italic fonts.              */
+  /*                                                                       */
+  /*    caret_offset            :: Offset in pixels to move the caret for  */
+  /*                               proper positioning.                     */
+  /*                                                                       */
+  /*    min_origin_SB           :: Minimum of horiBearingX (resp.          */
+  /*                               vertBearingY).                          */
+  /*    min_advance_SB          :: Minimum of                              */
+  /*                                                                       */
+  /*                                 horizontal advance -                  */
+  /*                                   ( horiBearingX + width )            */
+  /*                                                                       */
+  /*                               resp.                                   */
+  /*                                                                       */
+  /*                                 vertical advance -                    */
+  /*                                   ( vertBearingY + height )           */
+  /*                                                                       */
+  /*    max_before_BL           :: Maximum of horiBearingY (resp.          */
+  /*                               vertBearingY).                          */
+  /*                                                                       */
+  /*    min_after_BL            :: Minimum of                              */
+  /*                                                                       */
+  /*                                 horiBearingY - height                 */
+  /*                                                                       */
+  /*                               resp.                                   */
+  /*                                                                       */
+  /*                                 vertBearingX - width                  */
+  /*                                                                       */
+  typedef struct  TT_SBit_Line_Metrics_
+  {
+    TT_Char  ascender;
+    TT_Char  descender;
+    TT_Byte  max_width;
+    TT_Char  caret_slope_numerator;
+    TT_Char  caret_slope_denominator;
+    TT_Char  caret_offset;
+    TT_Char  min_origin_SB;
+    TT_Char  min_advance_SB;
+    TT_Char  max_before_BL;
+    TT_Char  min_after_BL;
+    TT_Char  pads[2];
+
+  } TT_SBit_Line_Metrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Range                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A TrueType/OpenType subIndexTable as defined in the `EBLC'         */
+  /*    (Microsoft) or `bloc' (Apple) tables.                              */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    first_glyph   :: The first glyph index in the range.               */
+  /*                                                                       */
+  /*    last_glyph    :: The last glyph index in the range.                */
+  /*                                                                       */
+  /*    index_format  :: The format of index table.  Valid values are 1    */
+  /*                     to 5.                                             */
+  /*                                                                       */
+  /*    image_format  :: The format of `EBDT' image data.                  */
+  /*                                                                       */
+  /*    image_offset  :: The offset to image data in `EBDT'.               */
+  /*                                                                       */
+  /*    image_size    :: For index formats 2 and 5.  This is the size in   */
+  /*                     bytes of each glyph bitmap.                       */
+  /*                                                                       */
+  /*    big_metrics   :: For index formats 2 and 5.  This is the big       */
+  /*                     metrics for each glyph bitmap.                    */
+  /*                                                                       */
+  /*    num_glyphs    :: For index formats 4 and 5.  This is the number of */
+  /*                     glyphs in the code array.                         */
+  /*                                                                       */
+  /*    glyph_offsets :: For index formats 1 and 3.                        */
+  /*                                                                       */
+  /*    glyph_codes   :: For index formats 4 and 5.                        */
+  /*                                                                       */
+  /*    table_offset  :: The offset of the index table in the `EBLC'       */
+  /*                     table.  Only used during strike loading.          */
+  /*                                                                       */
+  typedef struct  TT_SBit_Range
+  {
+    TT_UShort        first_glyph;
+    TT_UShort        last_glyph;
+
+    TT_UShort        index_format;
+    TT_UShort        image_format;
+    TT_ULong         image_offset;
+
+    TT_ULong         image_size;
+    TT_SBit_Metrics  metrics;
+    TT_ULong         num_glyphs;
+
+    TT_ULong*        glyph_offsets;
+    TT_UShort*       glyph_codes;
+
+    TT_ULong         table_offset;
+
+  } TT_SBit_Range;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Strike                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used describe a given bitmap strike in the `EBLC'      */
+  /*    (Microsoft) or `bloc' (Apple) tables.                              */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*   num_index_ranges :: The number of index ranges.                     */
+  /*                                                                       */
+  /*   index_ranges     :: An array of glyph index ranges.                 */
+  /*                                                                       */
+  /*   color_ref        :: Unused.  A color reference?                     */
+  /*                                                                       */
+  /*   hori             :: The line metrics for horizontal layouts.        */
+  /*                                                                       */
+  /*   vert             :: The line metrics for vertical layouts.          */
+  /*                                                                       */
+  /*   start_glyph      :: The lowest glyph index for this strike.         */
+  /*                                                                       */
+  /*   end_glyph        :: The highest glyph index for this strike.        */
+  /*                                                                       */
+  /*   x_ppem           :: The number of horizontal pixels per EM.         */
+  /*                                                                       */
+  /*   y_ppem           :: The number of vertical pixels per EM.           */
+  /*                                                                       */
+  /*   bit_depth        :: The bit depth.  Valid values are 1, 2, 4,       */
+  /*                       and 8.                                          */
+  /*                                                                       */
+  /*   flags            :: Is this a vertical or horizontal strike?        */
+  /*                                                                       */
+  typedef struct  TT_SBit_Strike_
+  {
+    TT_Int                 num_ranges;
+    TT_SBit_Range*         sbit_ranges;
+    TT_ULong               ranges_offset;
+
+    TT_ULong               color_ref;
+
+    TT_SBit_Line_Metrics   hori;
+    TT_SBit_Line_Metrics   vert;
+
+    TT_UShort              start_glyph;
+    TT_UShort              end_glyph;
+
+    TT_Byte                x_ppem;
+    TT_Byte                y_ppem;
+
+    TT_Byte                bit_depth;
+    TT_Char                flags;
+
+  } TT_SBit_Strike;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Component                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure to describe a compound sbit element.            */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    glyph_code :: The element's glyph index.                           */
+  /*    x_offset   :: The element's left bearing.                          */
+  /*    y_offset   :: The element's top bearing.                           */
+  /*                                                                       */
+  typedef struct  TT_SBit_Component_
+  {
+    TT_UShort  glyph_code;
+
+    TT_Char    x_offset;
+    TT_Char    y_offset;
+
+  } TT_SBit_Component;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Scale                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used describe a given bitmap scaling table, as defined */
+  /*    in the `EBSC' table.                                               */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    hori              :: The horizontal line metrics.                  */
+  /*                                                                       */
+  /*    vert              :: The vertical line metrics.                    */
+  /*                                                                       */
+  /*    x_ppem            :: The number of horizontal pixels per EM.       */
+  /*                                                                       */
+  /*    y_ppem            :: The number of vertical pixels per EM.         */
+  /*                                                                       */
+  /*    x_ppem_substitute :: Substitution x_ppem value.                    */
+  /*                                                                       */
+  /*    y_ppem_substitute :: Substitution y_ppem value.                    */
+  /*                                                                       */
+  typedef struct  TT_SBit_Scale_
+  {
+    TT_SBit_Line_Metrics  hori;
+    TT_SBit_Line_Metrics  vert;
+
+    TT_Byte               x_ppem;
+    TT_Byte               y_ppem;
+
+    TT_Byte               x_ppem_substitute;
+    TT_Byte               y_ppem_substitute;
+
+  } TT_SBit_Scale;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Post_20                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Postscript names sub-table, format 2.0.  Stores the PS name of     */
+  /*    each glyph in the font face.                                       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    num_glyphs    :: The number of named glyphs in the table.          */
+  /*                                                                       */
+  /*    num_names     :: The number of PS names stored in the table.       */
+  /*                                                                       */
+  /*    glyph_indices :: The indices of the glyphs in the names arrays.    */
+  /*                                                                       */
+  /*    glyph_names   :: The PS names not in Mac Encoding.                 */
+  /*                                                                       */
+  typedef struct  TT_Post_20_
+  {
+    TT_UShort   num_glyphs;
+    TT_UShort   num_names;
+    TT_UShort*  glyph_indices;
+    TT_Char**   glyph_names;
+
+  } TT_Post_20;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Post_25                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Postscript names sub-table, format 2.5.  Stores the PS name of     */
+  /*    each glyph in the font face.                                       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    num_glyphs :: The number of glyphs in the table.                   */
+  /*                                                                       */
+  /*    offsets    :: An array of signed offsets in a normal Mac           */
+  /*                  Postscript name encoding.                            */
+  /*                                                                       */
+  typedef struct  TT_Post_25_
+  {
+    TT_UShort  num_glyphs;
+    TT_Char*   offsets;
+
+  } TT_Post_25;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Post_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Postscript names table, either format 2.0 or 2.5.                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    loaded    :: A flag to indicate whether the PS names are loaded.   */
+  /*                                                                       */ 
+  /*    format_20 :: The sub-table used for format 2.0.                    */
+  /*                                                                       */
+  /*    format_25 :: The sub-table used for format 2.5.                    */
+  /*                                                                       */
+  typedef struct  TT_Post_Names_
+  {
+    TT_Bool       loaded;
+
+    union
+    {
+      TT_Post_20  format_20;
+      TT_Post_25  format_25;
+
+    } names;
+
+  } TT_Post_Names;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***                  ORIGINAL TT_FACE CLASS DEFINITION                ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This structure/class is defined here because it is common to the      */
+  /* following formats: TTF, OpenType-TT, and OpenType-CFF.                */
+  /*                                                                       */
+  /* Note however that the classes TT_Size, TT_GlyphSlot, and TT_CharMap   */
+  /* are not shared between font drivers, and are thus defined normally in */
+  /* `drivers/truetype/ttobjs.h'.                                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Face                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a TrueType face/font object.  A TT_Face encapsulates   */
+  /*    the resolution and scaling independent parts of a TrueType font    */
+  /*    resource.                                                          */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The TT_Face structure is also used as a `parent class' for the     */
+  /*    OpenType-CFF class (T2_Face).                                      */
+  /*                                                                       */
+  typedef struct TT_FaceRec_*   TT_Face;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                         TrueType Face Type                            */
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Face                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType face class.  These objects model the resolution and   */
+  /*    point-size independent data found in a TrueType font file.         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    root              :: The base FT_Face structure, managed by the    */
+  /*                         base layer.                                   */
+  /*                                                                       */
+  /*    ttcHeader         :: The TrueType collection header, used when the */
+  /*                         file is a `ttc' rather than a `ttf'.  For     */
+  /*                         ordinary font files, the field                */
+  /*                         `ttcHeader.DirCount' is set to 0.             */
+  /*                                                                       */
+  /*    num_tables        :: The number of TrueType tables in this font    */
+  /*                         file.                                         */
+  /*                                                                       */
+  /*    dir_tables        :: The directory of TrueType tables for this     */
+  /*                         font file.                                    */
+  /*                                                                       */
+  /*    header            :: The font's font header (`head' table).  Read  */
+  /*                         on font opening.                              */
+  /*                                                                       */
+  /*    horizontal        :: The font's horizontal header (`hhea' table).  */
+  /*                         This field also contains the associated       */
+  /*                         horizontal metrics table (`hmtx').            */
+  /*                                                                       */
+  /*    max_profile       :: The font's maximum profile table.  Read on    */
+  /*                         font opening.  Note that some maximum values  */
+  /*                         cannot be taken directly from this table.  We */
+  /*                         thus define additional fields below to hold   */
+  /*                         the computed maxima.                          */
+  /*                                                                       */
+  /*    max_components    :: The maximum number of glyph components        */
+  /*                         required to load any composite glyph from     */
+  /*                         this font.  Used to size the load stack.      */
+  /*                                                                       */
+  /*    vertical_info     :: A boolean which is set when the font file     */
+  /*                         contains vertical metrics.  If not, the value */
+  /*                         of the `vertical' field is undefined.         */
+  /*                                                                       */
+  /*    vertical          :: The font's vertical header (`vhea' table).    */
+  /*                         This field also contains the associated       */
+  /*                         vertical metrics table (`vmtx'), if found.    */
+  /*                         IMPORTANT: The contents of this field is      */
+  /*                         undefined if the `verticalInfo' field is      */
+  /*                         unset.                                        */
+  /*                                                                       */
+  /*    num_names         :: The number of name records within this        */
+  /*                         TrueType font.                                */
+  /*                                                                       */
+  /*    name_table        :: The table of name records (`name').           */
+  /*                                                                       */
+  /*    os2               :: The font's OS/2 table (`OS/2').               */
+  /*                                                                       */
+  /*    postscript        :: The font's PostScript table (`post' table).   */
+  /*                         The PostScript glyph names are not loaded by  */
+  /*                         the driver on face opening.  See the `ttpost' */
+  /*                         module for more details.                      */
+  /*                                                                       */
+  /*    num_charmaps      :: The number of character mappings in the font. */
+  /*                                                                       */
+  /*    charmaps          :: The array of charmap objects for this font    */
+  /*                         file.  Note that this field is a typeless     */
+  /*                         pointer.  The Reason is that the format of    */
+  /*                         charmaps varies with the underlying font      */
+  /*                         format and cannot be determined here.         */
+  /*                                                                       */
+  /*    hdmx              :: The face's horizontal device metrics (`hdmx'  */
+  /*                         table).  This table is optional in            */
+  /*                         TrueType/OpenType fonts.                      */
+  /*                                                                       */
+  /*    gasp              :: The grid-fitting and scaling properties table */
+  /*                         (`gasp').  This table is optional in          */
+  /*                         TrueType/OpenType fonts.                      */
+  /*                                                                       */
+  /*    num_sbit_strikes  :: The number of sbit strikes, i.e., bitmap      */
+  /*                         sizes, embedded in this font.                 */
+  /*                                                                       */
+  /*    sbit_strikes      :: An array of sbit strikes embedded in this     */
+  /*                         font.  This table is optional in a            */
+  /*                         TrueType/OpenType font.                       */
+  /*                                                                       */
+  /*    num_sbit_scales   :: The number of sbit scales for this font.      */
+  /*                                                                       */
+  /*    sbit_scales       :: Array of sbit scales embedded in this font.   */
+  /*                         This table is optional in a TrueType/OpenType */
+  /*                         font.                                         */
+  /*                                                                       */
+  /*    postscript_names  :: A table used to store the Postscript names of */
+  /*                         the glyphs for this font.  See the file       */
+  /*                         `ttconfig.h' for comments on the              */
+  /*                         TT_CONFIG_OPTION_POSTSCRIPT_NAMES option.     */
+  /*                                                                       */
+  /*    num_locations     :: The number of glyph locations in this         */
+  /*                         TrueType file.  This should be identical to   */
+  /*                         the number of glyphs.  Ignored for Type 2     */
+  /*                         fonts.                                        */
+  /*                                                                       */
+  /*    glyph_locations   :: An array of longs.  These are offsets to      */
+  /*                         glyph data within the `glyf' table.  Ignored  */
+  /*                         for Type 2 font faces.                        */
+  /*                                                                       */
+  /*    font_program_size :: Size in bytecodes of the face's font program. */
+  /*                         0 if none defined.  Ignored for Type 2 fonts. */
+  /*                                                                       */
+  /*    font_program      :: The face's font program (bytecode stream)     */
+  /*                         executed at load time, also used during glyph */
+  /*                         rendering.  Comes from the `fpgm' table.      */
+  /*                         Ignored for Type 2 font fonts.                */
+  /*                                                                       */
+  /*    cvt_program_size  :: Size in bytecodes of the face's cvt program.  */
+  /*                         Ignored for Type 2 fonts.                     */
+  /*                                                                       */
+  /*    cvt_program       :: The face's cvt program (bytecode stream)      */
+  /*                         executed each time an instance/size is        */
+  /*                         changed/reset.  Comes from the `prep' table.  */
+  /*                         Ignored for Type 2 fonts.                     */
+  /*                                                                       */
+  /*    cvt_size          :: Size of the control value table (in entries). */
+  /*                         Ignored for Type 2 fonts.                     */
+  /*                                                                       */
+  /*    cvt               :: The face's original control value table.      */
+  /*                         Coordinates are expressed in unscaled font    */
+  /*                         units.  Comes from the `cvt ` table.  Ignored */
+  /*                         for Type 2 fonts.                             */
+  /*                                                                       */
+  /*    num_kern_pairs    :: The number of kerning pairs present in the    */
+  /*                         font file.  The engine only loads the first   */
+  /*                         horizontal format 0 kern table it finds in    */
+  /*                         the font file.  You should use the `ttxkern'  */
+  /*                         structures if you want to access other        */
+  /*                         kerning tables.  Ignored for Type 2 fonts.    */
+  /*                                                                       */
+  /*    kern_table_index  :: The index of the kerning table in the font    */
+  /*                         kerning directory.  Only used by the ttxkern  */
+  /*                         extension to avoid data duplication.  Ignored */
+  /*                         for Type 2 fonts.                             */
+  /*                                                                       */
+  /*    kern_pairs        :: Array of kerning pairs, if any.  Ignored for  */
+  /*                         Type 2 fonts.                                 */
+  /*                                                                       */
+  typedef struct  TT_FaceRec_
+  {
+    FT_FaceRec         root;
+
+    TTC_Header         ttc_header;
+
+    TT_UShort          num_tables;
+    TT_TableDirEntry*  dir_tables;
+
+    TT_Header          header;       /* TrueType header table          */
+    TT_HoriHeader      horizontal;   /* TrueType horizontal header     */
+
+    TT_MaxProfile      max_profile;
+    TT_ULong           max_components;
+
+    TT_Bool            vertical_info;
+    TT_VertHeader      vertical;     /* TT Vertical header, if present */
+
+    TT_Int             num_names;    /* number of name records  */
+    TT_NameTable       name_table;   /* name table              */
+
+    TT_OS2             os2;          /* TrueType OS/2 table            */
+    TT_Postscript      postscript;   /* TrueType Postscript table      */
+
+    TT_Int             num_charmaps;
+    void*              charmaps;     /* array of TT_CharMapRec */
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* Optional TrueType/OpenType tables                                   */
+    /*                                                                     */
+    /***********************************************************************/
+
+    /* horizontal device metrics */
+    TT_Hdmx            hdmx;
+
+    /* grid-fitting and scaling table */
+    TT_Gasp            gasp;                 /* the `gasp' table */
+
+    /* embedded bitmaps support */
+    TT_Int             num_sbit_strikes;
+    TT_SBit_Strike*    sbit_strikes;
+
+    TT_Int             num_sbit_scales;
+    TT_SBit_Scale*     sbit_scales;
+
+    /* postscript names table */
+    TT_Post_Names      postscript_names;
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* TrueType-specific fields (ignored by the OTF-Type2 driver)          */
+    /*                                                                     */
+    /***********************************************************************/
+
+    /* the glyph locations */
+    TT_UShort          num_locations;
+    TT_Long*           glyph_locations;
+
+    /* the font program, if any */
+    TT_ULong           font_program_size;
+    TT_Byte*           font_program;
+
+    /* the cvt program, if any */
+    TT_ULong           cvt_program_size;
+    TT_Byte*           cvt_program;
+
+    /* the original, unscaled, control value table */
+    TT_ULong           cvt_size;
+    TT_Short*          cvt;
+
+    /* the format 0 kerning table, if any */
+    TT_Int             num_kern_pairs;
+    TT_Int             kern_table_index;
+    TT_Kern_0_Pair*    kern_pairs;
+
+  } TT_FaceRec;
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif /* TTTYPES_H */
+
+
+/* END */
diff --git a/src/shared/t1types.h b/src/shared/t1types.h
new file mode 100644
index 0000000..853b743
--- /dev/null
+++ b/src/shared/t1types.h
@@ -0,0 +1,485 @@
+/*******************************************************************
+ *
+ *  t1types.h                                                   1.0
+ *
+ *    Basic Type1/Type2 type definitions and interface.
+ *
+ *  This code is shared by the Type1 and Type2 drivers
+ *
+ *
+ *  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 T1TYPES_H
+#define T1TYPES_H
+
+#include <freetype.h>
+
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/***                                                                   ***/
+/***                                                                   ***/
+/***                DEFINITIONS OF BASIC DATA TYPES                    ***/
+/***                                                                   ***/
+/***                                                                   ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+
+/* The REDEFINE macro is used to convert a FreeType generic type into    */
+/* a TrueType-specific one. It simply replaces the "FT_" prefix by "T1_" */
+/* in order to define compatible T1_Long, T1_Error, T1_Outline, etc..    */
+/*                                                                       */
+#undef  REDEFINE
+#define REDEFINE( type )   typedef FT_##type  T1_##type
+
+
+  /* <Type> T1_Bool                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    A simple typedef of unsigned char, used for simple booleans.      */
+  /*                                                                      */
+  REDEFINE( Bool );
+
+
+  /* <Type> T1_FWord                                                      */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a signed 16-bit integer used to store a distance in original      */
+  /*    font units.                                                       */
+  /*                                                                      */
+  REDEFINE( FWord );
+
+
+  /* <Type> T1_UFWord                                                     */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    an unsigned 16-bit integer used to store a distance in original   */
+  /*    font units.                                                       */
+  /*                                                                      */
+  REDEFINE( UFWord );
+
+
+  /* <Type> T1_Char                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a simple typedef for the _signed_ char type.                      */
+  /*                                                                      */
+  REDEFINE( Char );
+
+
+  /* <Type> T1_Byte                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a simple typedef for the _unsigned_ char type.                    */
+  /*                                                                      */
+  REDEFINE( Byte );
+
+
+  /* <Type> T1_String                                                     */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a simple typedef for the char type, used for strings usually.     */
+  /*                                                                      */
+  REDEFINE( String );
+
+
+  /* <Type> T1_Short                                                      */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for signed short                                        */
+  /*                                                                      */
+  REDEFINE( Short );
+
+
+  /* <Type> T1_UShort                                                     */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for unsigned short                                      */
+  /*                                                                      */
+  REDEFINE( UShort );
+
+
+  /* <Type> FT_Int                                                        */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for the int type                                        */
+  /*                                                                      */
+  REDEFINE( Int );
+
+
+  /* <Type> FT_UInt                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for the unsigned int type                               */
+  /*                                                                      */
+  REDEFINE( UInt );
+
+
+  /* <Type> T1_Long                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for signed long                                         */
+  /*                                                                      */
+  REDEFINE( Long );
+
+
+  /* <Type> T1_ULong                                                      */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for unsigned long                                       */
+  /*                                                                      */
+  REDEFINE( ULong );
+
+
+  /* <Type> T1_F2Dot14                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    a signed 2.14 fixed float used for unit vectors                    */
+  /*                                                                       */
+  REDEFINE( F2Dot14 );
+
+
+  /* <Type> T1_F26Dot6                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    a signed 26.6 fixed float used for vectorial pixel coordinates     */
+  /*                                                                       */
+  REDEFINE( F26Dot6 );
+
+
+  /* <Type> T1_Fixed                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*     This type is used to store 16.16 fixed float values, like         */
+  /*     scales or matrix coefficients..                                   */
+  /*                                                                       */
+  REDEFINE( Fixed );
+
+
+  /* <Type> T1_Pos                                                      */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     The type T1_Pos is a 32-bits integer used to store vectorial   */
+  /*     coordinates. Depending on the context, these can represent     */
+  /*     distances in integer font units, or 26.6 fixed float pixel     */
+  /*     coordinates..                                                  */
+  /*                                                                    */
+  REDEFINE( Pos );
+
+
+  /* <Struct> T1_Vector                                                 */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     A simple structure used to store a 2d vector, coordinates      */
+  /*     are of the T1_Pos type.                                        */
+  /*                                                                    */
+  /* <Fields>                                                           */
+  /*    x  ::  horizontal coordinate                                    */
+  /*    y  ::  vertical coordinate                                      */
+  /*                                                                    */
+  REDEFINE( Vector );
+
+  /* <Struct> T1_UnitVector                                             */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     A simple structure used to store a 2d vector unit vector.      */
+  /*     uses T1_F2Dot14 types.                                         */
+  /*                                                                    */
+  /* <Fields>                                                           */
+  /*    x  ::  horizontal coordinate                                    */
+  /*    y  ::  vertical coordinate                                      */
+  /*                                                                    */
+  REDEFINE( UnitVector );
+
+
+  /* <Struct> T1_Matrix                                                 */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     A simple structure used to store a 2x2 matrix. Coefficients    */
+  /*     are in 16.16 fixed float format. The computation performed     */
+  /*     is :                                                           */
+  /*             {                                                      */
+  /*               x' = x*xx + y*xy                                     */
+  /*               y' = x*yx + y*yy                                     */
+  /*             }                                                      */
+  /*                                                                    */
+  /* <Fields>                                                           */
+  /*     xx  :: matrix coefficient                                      */
+  /*     xy  :: matrix coefficient                                      */
+  /*     yx  :: matrix coefficient                                      */
+  /*     yy  :: matrix coefficient                                      */
+  /*                                                                    */
+  REDEFINE( Matrix );
+
+
+  /* <Struct> T1_BBox                                                   */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     A structure used to hold an outline's bounding box, i.e.       */
+  /*     the coordinates of its extrema in the horizontal and vertical  */
+  /*     directions.                                                    */
+  /*                                                                    */
+  /* <Fields>                                                           */
+  /*     xMin   ::  the horizontal minimum  (left-most)                 */
+  /*     yMin   ::  the vertical minimum    (bottom-most)               */
+  /*     xMax   ::  the horizontal maximum  (right-most)                */
+  /*     yMax   ::  the vertical maximum    (top-most)                  */
+  /*                                                                    */
+  REDEFINE( BBox );
+
+
+  /* <Type> T1_Error                                                    */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*    The FreeType error code type. A value of 0 is always            */
+  /*    interpreted as a succesful operation.                           */
+  /*                                                                    */
+  REDEFINE( Error );
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/***                                                                   ***/
+/***                                                                   ***/
+/***                REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS            ***/
+/***                                                                   ***/
+/***                                                                   ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Struct> T1_FontInfo                                                */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    The FontInfo dictionary structure.                               */
+  /*                                                                     */
+  /* <Fields>                                                            */
+  /*    version             ::                                           */
+  /*    notice              ::                                           */
+  /*    full_name           ::                                           */
+  /*    family_name         ::                                           */
+  /*    weight              ::                                           */
+  /*    italic_angle        ::                                           */
+  /*    is_fixed_pitch      ::                                           */
+  /*    underline_position  ::                                           */
+  /*    underline_thickness ::                                           */
+  /*                                                                     */
+  typedef struct T1_FontInfo_
+  {
+    T1_String*     version;
+    T1_String*     notice;
+    T1_String*     full_name;
+    T1_String*     family_name;
+    T1_String*     weight;
+    T1_Long        italic_angle;
+    T1_Bool        is_fixed_pitch;
+    T1_Short       underline_position;
+    T1_UShort      underline_thickness;
+
+  } T1_FontInfo;
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Struct> T1_Private                                                 */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    The Private dictionary structure.                                */
+  /*                                                                     */
+  /* <Fields>                                                            */
+  /*    unique_id :: the font's unique id                                */
+  /*    lenIV     :: length of decrypt padding                           */
+  /*                                                                     */
+  /*    num_blues              :: number of blue values                  */
+  /*    num_other_blues        :: number of other blue values            */
+  /*    num_family_blues       :: number of family blue values           */
+  /*    num_family_other_blues :: number of family other blue values     */
+  /*                                                                     */
+  /*    blue_values        :: array of blue values                       */
+  /*    other_blues        :: array of other blue values                 */
+  /*    family_blues       :: array of family blue values                */
+  /*    family_other_blues :: array of family other blue values          */
+  /*                                                                     */
+  /*    blue_scale         ::                                            */
+  /*    blue_shift         ::                                            */
+  /*    blue_scale         ::                                            */
+  /*                                                                     */
+  /*    standard_width     ::                                            */
+  /*    standard_height    ::                                            */
+  /*                                                                     */
+  /*    num_snap_widths    ::                                            */
+  /*    num_snap_heights   ::                                            */
+  /*    force_bold         ::                                            */
+  /*    round_stem_up      ::                                            */
+  /*                                                                     */
+  /*    stem_snap_widths   ::                                            */
+  /*    stem_snap_heights  ::                                            */
+  /*                                                                     */
+  /*    language_group     ::                                            */
+  /*    password           ::                                            */
+  /*                                                                     */
+  /*    min_feature        ::                                            */
+  /*                                                                     */
+  /*                                                                     */
+  typedef struct T1_Private_
+  {
+    T1_Int       unique_id;
+    T1_Int       lenIV;
+
+    T1_Byte      num_blues;
+    T1_Byte      num_other_blues;
+    T1_Byte      num_family_blues;
+    T1_Byte      num_family_other_blues;
+
+    T1_Short     blue_values[14];
+    T1_Short     other_blues[10];
+
+    T1_Short     family_blues      [14];
+    T1_Short     family_other_blues[10];
+
+    T1_Fixed     blue_scale;
+    T1_Int       blue_shift;
+    T1_Int       blue_fuzz;
+
+    T1_UShort    standard_width;
+    T1_UShort    standard_height;
+
+    T1_Byte      num_snap_widths;
+    T1_Byte      num_snap_heights;
+    T1_Bool      force_bold;
+    T1_Bool      round_stem_up;
+
+    T1_Short     stem_snap_widths [13];  /* reserve one place for the std */
+    T1_Short     stem_snap_heights[13];  /* reserve one place for the std */
+
+    T1_Long      language_group;
+    T1_Long      password;
+
+    T1_Short     min_feature[2];
+
+  } T1_Private;
+
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Struct> T1_Private                                                 */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    The Private dictionary structure.                                */
+  /*                                                                     */
+  /* <Fields>                                                            */
+  /*    num_chars   :: number of char codes in encoding. Usually 256     */
+  /*    code_first  :: lower char code in encoding                       */
+  /*    code_last   :: higher char code in encoding                      */
+  /*                                                                     */
+  /*    char_code   :: array of character codes                          */
+  /*    char_index  :: array of correpsonding glyph indices              */
+  /*    char_name   :: array of correpsonding glyph names                */
+  /*                                                                     */
+  typedef struct T1_Encoding_
+  {
+    T1_Int      num_chars;
+    T1_Int      code_first;
+    T1_Int      code_last;
+
+    T1_Short*   char_index;
+    T1_String** char_name;
+
+  } T1_Encoding;
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/***                                                                   ***/
+/***                                                                   ***/
+/***                  ORIGINAL TT_FACE CLASS DEFINITION                ***/
+/***                                                                   ***/
+/***                                                                   ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/***                                                                   ***/
+/***                                                                   ***/
+/***    This structure/class is defined here because it is common      ***/
+/***    to the following formats : TTF, OpenType-TT and OpenType-CFF   ***/
+/***                                                                   ***/
+/***    Note however that the classes TT_Size, TT_GlyphSlot and        ***/
+/***    TT_CharMap are not shared between font drivers, and are        ***/
+/***    thus defined normally in "drivers/truetype/ttobjs.h"           ***/
+/***                                                                   ***/
+/***                                                                   ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+
+  typedef struct T1_FaceRec_*   T1_Face;
+
+
+  /***************************************************/
+  /*                                                 */
+  /*  T1_Face :                                      */
+  /*                                                 */
+  /*    Type1 face record..                          */
+  /*                                                 */
+
+  typedef struct T1_FaceRec_
+  {
+    FT_FaceRec      root;
+
+    T1_FontInfo     font_info;
+    FT_String*      font_name;
+
+    T1_Encoding     encoding;
+
+    T1_Byte*        subrs_block;
+    T1_Byte*        charstrings_block;
+
+    T1_Int          num_subrs;
+    T1_Byte**       subrs;
+    T1_Int*         subrs_len;
+
+    T1_Int          num_glyphs;
+    T1_String**     glyph_names;       /* array of glyph names       */
+    T1_Byte**       charstrings;       /* array of glyph charstrings */
+    T1_Int*         charstrings_len;
+
+    T1_Byte         paint_type;
+    T1_Byte         font_type;
+    T1_Matrix       font_matrix;
+    T1_BBox         font_bbox;
+    T1_Long         unique_id;
+    T1_Long         font_id;
+
+    T1_Int          stroke_width;
+    T1_Private      private_dict;
+
+  } T1_FaceRec;
+
+
+#endif /* T1TYPES_H */
diff --git a/src/shared/tterrors.h b/src/shared/tterrors.h
new file mode 100644
index 0000000..a8c6b5f
--- /dev/null
+++ b/src/shared/tterrors.h
@@ -0,0 +1,126 @@
+/***************************************************************************/
+/*                                                                         */
+/*  tterrors.h                                                             */
+/*                                                                         */
+/*    TrueType error ID definitions (specification only).                  */
+/*                                                                         */
+/*  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 TTERRORS_H
+#define TTERRORS_H
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Error codes declaration                                               */
+  /*                                                                       */
+  /* The error codes are grouped in `classes' used to indicate the `level' */
+  /* at which the error happened.  The class is given by an error code's   */
+  /* high byte.                                                            */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /* Success is always 0. */
+
+#define  TT_Err_Ok                       FT_Err_Ok
+
+  /* High level API errors. */
+
+#define  TT_Err_Invalid_File_Format      FT_Err_Invalid_File_Format
+#define  TT_Err_Invalid_Argument         FT_Err_Invalid_Argument
+#define  TT_Err_Invalid_Driver_Handle    FT_Err_Invalid_Driver_Handle
+#define  TT_Err_Invalid_Face_Handle      FT_Err_Invalid_Face_Handle
+#define  TT_Err_Invalid_Instance_Handle  FT_Err_Invalid_Size_Handle
+#define  TT_Err_Invalid_Glyph_Handle     FT_Err_Invalid_Slot_Handle
+#define  TT_Err_Invalid_CharMap_Handle   FT_Err_Invalid_CharMap_Handle
+#define  TT_Err_Invalid_Glyph_Index      FT_Err_Invalid_Glyph_Index
+
+#define  TT_Err_Unimplemented_Feature    FT_Err_Unimplemented_Feature
+#define  TT_Err_Unavailable_Outline      FT_Err_Unavailable_Outline
+#define  TT_Err_Unavailable_Bitmap       FT_Err_Unavailable_Bitmap
+#define  TT_Err_Unavailable_Pixmap       FT_Err_Unavailable_Pixmap
+#define  TT_Err_File_Is_Not_Collection   FT_Err_File_Is_Not_Collection
+
+#define  TT_Err_Invalid_Engine           FT_Err_Invalid_Driver_Handle
+
+  /* Internal errors. */
+
+#define  TT_Err_Out_Of_Memory            FT_Err_Out_Of_Memory
+#define  TT_Err_Unlisted_Object          FT_Err_Unlisted_Object
+
+  /* General glyph outline errors. */
+
+#define  TT_Err_Too_Many_Points          FT_Err_Too_Many_Points
+#define  TT_Err_Too_Many_Contours        FT_Err_Too_Many_Contours
+#define  TT_Err_Too_Many_Ins             FT_Err_Too_Many_Hints
+#define  TT_Err_Invalid_Composite        FT_Err_Invalid_Composite
+
+  /* Bytecode interpreter error codes. */
+
+  /* These error codes are produced by the TrueType */
+  /* bytecode interpreter.  They usually indicate a */
+  /* broken font file, a broken glyph within a font */
+  /* file, or a bug in the interpreter!             */
+
+#define TT_Err_Invalid_Opcode             0x400
+#define TT_Err_Too_Few_Arguments          0x401
+#define TT_Err_Stack_Overflow             0x402
+#define TT_Err_Code_Overflow              0x403
+#define TT_Err_Bad_Argument               0x404
+#define TT_Err_Divide_By_Zero             0x405
+#define TT_Err_Storage_Overflow           0x406
+#define TT_Err_Cvt_Overflow               0x407
+#define TT_Err_Invalid_Reference          0x408
+#define TT_Err_Invalid_Distance           0x409
+#define TT_Err_Interpolate_Twilight       0x40A
+#define TT_Err_Debug_OpCode               0x40B
+#define TT_Err_ENDF_In_Exec_Stream        0x40C
+#define TT_Err_Out_Of_CodeRanges          0x40D
+#define TT_Err_Nested_DEFS                0x40E
+#define TT_Err_Invalid_CodeRange          0x40F
+#define TT_Err_Invalid_Displacement       0x410
+#define TT_Err_Execution_Too_Long         0x411
+#define TT_Err_Too_Many_Function_Defs     0x412
+#define TT_Err_Too_Many_Instruction_Defs  0x413
+
+  /* Other TrueType specific error codes. */
+
+#define TT_Err_Table_Missing            0x420
+#define TT_Err_Too_Many_Extensions      0x421
+#define TT_Err_Extensions_Unsupported   0x422
+#define TT_Err_Invalid_Extension_Id     0x423
+
+#define TT_Err_No_Vertical_Data         0x424
+
+#define TT_Err_Max_Profile_Missing      0x430
+#define TT_Err_Header_Table_Missing     0x431
+#define TT_Err_Horiz_Header_Missing     0x432
+#define TT_Err_Locations_Missing        0x433
+#define TT_Err_Name_Table_Missing       0x434
+#define TT_Err_CMap_Table_Missing       0x435
+#define TT_Err_Hmtx_Table_Missing       0x436
+#define TT_Err_OS2_Table_Missing        0x437
+#define TT_Err_Post_Table_Missing       0x438
+
+#define TT_Err_Invalid_Horiz_Metrics    0x440
+#define TT_Err_Invalid_CharMap_Format   0x441
+#define TT_Err_Invalid_PPem             0x442
+#define TT_Err_Invalid_Vert_Metrics     0x443
+
+#define TT_Err_Could_Not_Find_Context   0x450
+
+#endif /* FTERRID_H */
+
+
+/* END */
diff --git a/src/shared/ttnameid.h b/src/shared/ttnameid.h
new file mode 100644
index 0000000..98b19ab
--- /dev/null
+++ b/src/shared/ttnameid.h
@@ -0,0 +1,603 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttnameid.h                                                             */
+/*                                                                         */
+/*    TrueType name ID definitions (specification only).                   */
+/*                                                                         */
+/*  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 FREETYPE_H
+#error "Don't include this file! Use freetype.h instead."
+#endif
+
+
+#ifndef TTNAMEID_H
+#define TTNAMEID_H
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values for the `Platform' identifier code in the name        */
+  /* records of the TTF `name' table.                                      */
+  /*                                                                       */
+#define TT_PLATFORM_APPLE_UNICODE  0
+#define TT_PLATFORM_MACINTOSH      1
+#define TT_PLATFORM_ISO            2
+#define TT_PLATFORM_MICROSOFT      3
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the platform specific encoding identifier field in */
+  /* the name records of the TTF `name' table when the `Platform'          */
+  /* identifier code is TT_PLATFORM_APPLE_UNICODE.                         */
+  /*                                                                       */
+#define TT_APPLE_ID_DEFAULT      0
+#define TT_APPLE_ID_UNICODE_1_1  1
+#define TT_APPLE_ID_ISO_10646    2
+#define TT_APPLE_ID_UNICODE_2_0  3
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the platform specific encoding identifier field in */
+  /* the name records of the TTF `name' table when the `Platform'          */
+  /* identifier code is TT_PLATFORM_MACINTOSH.                             */
+  /*                                                                       */
+#define TT_MAC_ID_ROMAN                 0
+#define TT_MAC_ID_JAPANESE              1
+#define TT_MAC_ID_TRADITIONAL_CHINESE   2
+#define TT_MAC_ID_KOREAN                3
+#define TT_MAC_ID_ARABIC                4
+#define TT_MAC_ID_HEBREW                5
+#define TT_MAC_ID_GREEK                 6
+#define TT_MAC_ID_RUSSIAN               7
+#define TT_MAC_ID_RSYMBOL               8
+#define TT_MAC_ID_DEVANAGARI            9
+#define TT_MAC_ID_GURMUKHI             10
+#define TT_MAC_ID_GUJARATI             11
+#define TT_MAC_ID_ORIYA                12
+#define TT_MAC_ID_BENGALI              13
+#define TT_MAC_ID_TAMIL                14
+#define TT_MAC_ID_TELUGU               15
+#define TT_MAC_ID_KANNADA              16
+#define TT_MAC_ID_MALAYALAM            17
+#define TT_MAC_ID_SINHALESE            18
+#define TT_MAC_ID_BURMESE              19
+#define TT_MAC_ID_KHMER                20
+#define TT_MAC_ID_THAI                 21
+#define TT_MAC_ID_LAOTIAN              22
+#define TT_MAC_ID_GEORGIAN             23
+#define TT_MAC_ID_ARMENIAN             24
+#define TT_MAC_ID_MALDIVIAN            25
+#define TT_MAC_ID_SIMPLIFIED_CHINESE   25
+#define TT_MAC_ID_TIBETAN              26
+#define TT_MAC_ID_MONGOLIAN            27
+#define TT_MAC_ID_GEEZ                 28
+#define TT_MAC_ID_SLAVIC               29
+#define TT_MAC_ID_VIETNAMESE           30
+#define TT_MAC_ID_SINDHI               31
+#define TT_MAC_ID_UNINTERP             32
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the platform specific encoding identifier field in */
+  /* the name records of the TTF `name' table when the `Platform'          */
+  /* identifier code is TT_PLATFORM_ISO.                                   */
+  /*                                                                       */
+#define TT_ISO_ID_7BIT_ASCII  0
+#define TT_ISO_ID_10646       1
+#define TT_ISO_ID_8859_1      2
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the platform specific encoding identifier field in */
+  /* the name records of the TTF `name' table when the `Platform'          */
+  /* identifier code is TT_PLATFORM_MICROSOFT.                             */
+  /*                                                                       */
+#define TT_MS_ID_SYMBOL_CS   0
+#define TT_MS_ID_UNICODE_CS  1
+#define TT_MS_ID_SJIS        2
+#define TT_MS_ID_GB2312      3
+#define TT_MS_ID_BIG_5       4
+#define TT_MS_ID_WANSUNG     5
+#define TT_MS_ID_JOHAB       6
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the language identifier field in the name records  */
+  /* of the TTF `name' table when the `Platform' identifier code is        */
+  /* TT_PLATFORM_MACINTOSH.                                                */
+  /*                                                                       */
+  /* The canonical source for the Apple assigned Language ID's is at       */
+  /* http://fonts.apple.com/TTRefMan/RM06/Chap6name.html.                  */
+  /*                                                                       */
+#define TT_MAC_LANGID_ENGLISH                      0
+#define TT_MAC_LANGID_FRENCH                       1
+#define TT_MAC_LANGID_GERMAN                       2
+#define TT_MAC_LANGID_ITALIAN                      3
+#define TT_MAC_LANGID_DUTCH                        4
+#define TT_MAC_LANGID_SWEDISH                      5
+#define TT_MAC_LANGID_SPANISH                      6
+#define TT_MAC_LANGID_DANISH                       7
+#define TT_MAC_LANGID_PORTUGUESE                   8
+#define TT_MAC_LANGID_NORWEGIAN                    9
+#define TT_MAC_LANGID_HEBREW                      10
+#define TT_MAC_LANGID_JAPANESE                    11
+#define TT_MAC_LANGID_ARABIC                      12
+#define TT_MAC_LANGID_FINNISH                     13
+#define TT_MAC_LANGID_GREEK                       14
+#define TT_MAC_LANGID_ICELANDIC                   15
+#define TT_MAC_LANGID_MALTESE                     16
+#define TT_MAC_LANGID_TURKISH                     17
+#define TT_MAC_LANGID_CROATIAN                    18
+#define TT_MAC_LANGID_CHINESE_TRADITIONAL         19
+#define TT_MAC_LANGID_URDU                        20
+#define TT_MAC_LANGID_HINDI                       21
+#define TT_MAC_LANGID_THAI                        22
+#define TT_MAC_LANGID_KOREAN                      23
+#define TT_MAC_LANGID_LITHUANIAN                  24
+#define TT_MAC_LANGID_POLISH                      25
+#define TT_MAC_LANGID_HUNGARIAN                   26
+#define TT_MAC_LANGID_ESTONIAN                    27
+#define TT_MAC_LANGID_LETTISH                     28
+#define TT_MAC_LANGID_SAAMISK                     29
+#define TT_MAC_LANGID_FAEROESE                    30
+#define TT_MAC_LANGID_FARSI                       31
+#define TT_MAC_LANGID_RUSSIAN                     32
+#define TT_MAC_LANGID_CHINESE_SIMPLIFIED          33
+#define TT_MAC_LANGID_FLEMISH                     34
+#define TT_MAC_LANGID_IRISH                       35
+#define TT_MAC_LANGID_ALBANIAN                    36
+#define TT_MAC_LANGID_ROMANIAN                    37
+#define TT_MAC_LANGID_CZECH                       38
+#define TT_MAC_LANGID_SLOVAK                      39
+#define TT_MAC_LANGID_SLOVENIAN                   40
+#define TT_MAC_LANGID_YIDDISH                     41
+#define TT_MAC_LANGID_SERBIAN                     42
+#define TT_MAC_LANGID_MACEDONIAN                  43
+#define TT_MAC_LANGID_BULGARIAN                   44
+#define TT_MAC_LANGID_UKRAINIAN                   45
+#define TT_MAC_LANGID_BYELORUSSIAN                46
+#define TT_MAC_LANGID_UZBEK                       47
+#define TT_MAC_LANGID_KAZAKH                      48
+#define TT_MAC_LANGID_AZERBAIJANI                 49
+#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT   50
+#define TT_MAC_LANGID_ARMENIAN                    51
+#define TT_MAC_LANGID_GEORGIAN                    52
+#define TT_MAC_LANGID_MOLDAVIAN                   53
+#define TT_MAC_LANGID_KIRGHIZ                     54
+#define TT_MAC_LANGID_TAJIKI                      55
+#define TT_MAC_LANGID_TURKMEN                     56
+#define TT_MAC_LANGID_MONGOLIAN                   57
+#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT   58
+#define TT_MAC_LANGID_PASHTO                      59
+#define TT_MAC_LANGID_KURDISH                     60
+#define TT_MAC_LANGID_KASHMIRI                    61
+#define TT_MAC_LANGID_SINDHI                      62
+#define TT_MAC_LANGID_TIBETAN                     63
+#define TT_MAC_LANGID_NEPALI                      64
+#define TT_MAC_LANGID_SANSKRIT                    65
+#define TT_MAC_LANGID_MARATHI                     66
+#define TT_MAC_LANGID_BENGALI                     67
+#define TT_MAC_LANGID_ASSAMESE                    68
+#define TT_MAC_LANGID_GUJARATI                    69
+#define TT_MAC_LANGID_PUNJABI                     70
+#define TT_MAC_LANGID_ORIYA                       71
+#define TT_MAC_LANGID_MALAYALAM                   72
+#define TT_MAC_LANGID_KANNADA                     73
+#define TT_MAC_LANGID_TAMIL                       74
+#define TT_MAC_LANGID_TELUGU                      75
+#define TT_MAC_LANGID_SINHALESE                   76
+#define TT_MAC_LANGID_BURMESE                     77
+#define TT_MAC_LANGID_KHMER                       78
+#define TT_MAC_LANGID_LAO                         79
+#define TT_MAC_LANGID_VIETNAMESE                  80
+#define TT_MAC_LANGID_INDONESIAN                  81
+#define TT_MAC_LANGID_TAGALOG                     82
+#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT          83
+#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT         84
+#define TT_MAC_LANGID_AMHARIC                     85
+#define TT_MAC_LANGID_TIGRINYA                    86
+#define TT_MAC_LANGID_GALLA                       87
+#define TT_MAC_LANGID_SOMALI                      88
+#define TT_MAC_LANGID_SWAHILI                     89
+#define TT_MAC_LANGID_RUANDA                      90
+#define TT_MAC_LANGID_RUNDI                       91
+#define TT_MAC_LANGID_CHEWA                       92
+#define TT_MAC_LANGID_MALAGASY                    93
+#define TT_MAC_LANGID_ESPERANTO                   94
+#define TT_MAC_LANGID_WELSH                      128
+#define TT_MAC_LANGID_BASQUE                     129
+#define TT_MAC_LANGID_CATALAN                    130
+#define TT_MAC_LANGID_LATIN                      131
+#define TT_MAC_LANGID_QUECHUA                    132
+#define TT_MAC_LANGID_GUARANI                    133
+#define TT_MAC_LANGID_AYMARA                     134
+#define TT_MAC_LANGID_TATAR                      135
+#define TT_MAC_LANGID_UIGHUR                     136
+#define TT_MAC_LANGID_DZONGKHA                   137
+#define TT_MAC_LANGID_JAVANESE                   138
+#define TT_MAC_LANGID_SUNDANESE                  139
+#define TT_MAC_LANGID_SCOTTISH_GAELIC            140
+#define TT_MAC_LANGID_IRISH_GAELIC               141
+#define TT_MAC_LANGID_BRETON                     142
+#define TT_MAC_LANGID_INUKTITUT                  143
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the language identifier field in the name records  */
+  /* of the TTF `name' table when the `Platform' identifier code is        */
+  /* TT_PLATFORM_MICROSOFT.                                                */
+  /*                                                                       */
+  /* The canonical source for the MS assigned LCID's is at                 */
+  /* http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt.               */
+  /*                                                                       */
+#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA               0x0401
+#define TT_MS_LANGID_ARABIC_IRAQ                       0x0801
+#define TT_MS_LANGID_ARABIC_EGYPT                      0x0c01
+#define TT_MS_LANGID_ARABIC_LIBYA                      0x1001
+#define TT_MS_LANGID_ARABIC_ALGERIA                    0x1401
+#define TT_MS_LANGID_ARABIC_MOROCCO                    0x1801
+#define TT_MS_LANGID_ARABIC_TUNISIA                    0x1c01
+#define TT_MS_LANGID_ARABIC_OMAN                       0x2001
+#define TT_MS_LANGID_ARABIC_YEMEN                      0x2401
+#define TT_MS_LANGID_ARABIC_SYRIA                      0x2801
+#define TT_MS_LANGID_ARABIC_JORDAN                     0x2c01
+#define TT_MS_LANGID_ARABIC_LEBANON                    0x3001
+#define TT_MS_LANGID_ARABIC_KUWAIT                     0x3401
+#define TT_MS_LANGID_ARABIC_UAE                        0x3801
+#define TT_MS_LANGID_ARABIC_BAHRAIN                    0x3c01
+#define TT_MS_LANGID_ARABIC_QATAR                      0x4001
+#define TT_MS_LANGID_BULGARIAN_BULGARIA                0x0402
+#define TT_MS_LANGID_CATALAN_SPAIN                     0x0403
+#define TT_MS_LANGID_CHINESE_TAIWAN                    0x0404
+#define TT_MS_LANGID_CHINESE_PRC                       0x0804
+#define TT_MS_LANGID_CHINESE_HONG_KONG                 0x0c04
+#define TT_MS_LANGID_CHINESE_SINGAPORE                 0x1004
+#define TT_MS_LANGID_CHINESE_MACAU                     0x1404
+#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC              0x0405
+#define TT_MS_LANGID_DANISH_DENMARK                    0x0406
+#define TT_MS_LANGID_GERMAN_GERMANY                    0x0407
+#define TT_MS_LANGID_GERMAN_SWITZERLAND                0x0807
+#define TT_MS_LANGID_GERMAN_AUSTRIA                    0x0c07
+#define TT_MS_LANGID_GERMAN_LUXEMBOURG                 0x1007
+#define TT_MS_LANGID_GERMAN_LIECHTENSTEI               0x1407
+#define TT_MS_LANGID_GREEK_GREECE                      0x0408
+#define TT_MS_LANGID_ENGLISH_UNITED_STATES             0x0409
+#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM            0x0809
+#define TT_MS_LANGID_ENGLISH_AUSTRALIA                 0x0c09
+#define TT_MS_LANGID_ENGLISH_CANADA                    0x1009
+#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND               0x1409
+#define TT_MS_LANGID_ENGLISH_IRELAND                   0x1809
+#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA              0x1c09
+#define TT_MS_LANGID_ENGLISH_JAMAICA                   0x2009
+#define TT_MS_LANGID_ENGLISH_CARIBBEAN                 0x2409
+#define TT_MS_LANGID_ENGLISH_BELIZE                    0x2809
+#define TT_MS_LANGID_ENGLISH_TRINIDAD                  0x2c09
+#define TT_MS_LANGID_ENGLISH_ZIMBABWE                  0x3009
+#define TT_MS_LANGID_ENGLISH_PHILIPPINES               0x3409
+#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT    0x040a
+#define TT_MS_LANGID_SPANISH_MEXICO                    0x080a
+#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT  0x0c0a
+#define TT_MS_LANGID_SPANISH_GUATEMALA                 0x100a
+#define TT_MS_LANGID_SPANISH_COSTA_RICA                0x140a
+#define TT_MS_LANGID_SPANISH_PANAMA                    0x180a
+#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC        0x1c0a
+#define TT_MS_LANGID_SPANISH_VENEZUELA                 0x200a
+#define TT_MS_LANGID_SPANISH_COLOMBIA                  0x240a
+#define TT_MS_LANGID_SPANISH_PERU                      0x280a
+#define TT_MS_LANGID_SPANISH_ARGENTINA                 0x2c0a
+#define TT_MS_LANGID_SPANISH_ECUADOR                   0x300a
+#define TT_MS_LANGID_SPANISH_CHILE                     0x340a
+#define TT_MS_LANGID_SPANISH_URUGUAY                   0x380a
+#define TT_MS_LANGID_SPANISH_PARAGUAY                  0x3c0a
+#define TT_MS_LANGID_SPANISH_BOLIVIA                   0x400a
+#define TT_MS_LANGID_SPANISH_EL_SALVADOR               0x440a
+#define TT_MS_LANGID_SPANISH_HONDURAS                  0x480a
+#define TT_MS_LANGID_SPANISH_NICARAGUA                 0x4c0a
+#define TT_MS_LANGID_SPANISH_PUERTO_RICO               0x500a
+#define TT_MS_LANGID_FINNISH_FINLAND                   0x040b
+#define TT_MS_LANGID_FRENCH_FRANCE                     0x040c
+#define TT_MS_LANGID_FRENCH_BELGIUM                    0x080c
+#define TT_MS_LANGID_FRENCH_CANADA                     0x0c0c
+#define TT_MS_LANGID_FRENCH_SWITZERLAND                0x100c
+#define TT_MS_LANGID_FRENCH_LUXEMBOURG                 0x140c
+#define TT_MS_LANGID_FRENCH_MONACO                     0x180c
+#define TT_MS_LANGID_HEBREW_ISRAEL                     0x040d
+#define TT_MS_LANGID_HUNGARIAN_HUNGARY                 0x040e
+#define TT_MS_LANGID_ICELANDIC_ICELAND                 0x040f
+#define TT_MS_LANGID_ITALIAN_ITALY                     0x0410
+#define TT_MS_LANGID_ITALIAN_SWITZERLAND               0x0810
+#define TT_MS_LANGID_JAPANESE_JAPAN                    0x0411
+#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA     0x0412
+#define TT_MS_LANGID_KOREAN_JOHAB_KOREA                0x0812
+#define TT_MS_LANGID_DUTCH_NETHERLANDS                 0x0413
+#define TT_MS_LANGID_DUTCH_BELGIUM                     0x0813
+#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL           0x0414
+#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK          0x0814
+#define TT_MS_LANGID_POLISH_POLAND                     0x0415
+#define TT_MS_LANGID_PORTUGUESE_BRAZIL                 0x0416
+#define TT_MS_LANGID_PORTUGUESE_PORTUGAL               0x0816
+#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND        0x0417
+#define TT_MS_LANGID_ROMANIAN_ROMANIA                  0x0418
+#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA                0x0818
+#define TT_MS_LANGID_RUSSIAN_RUSSIA                    0x0419
+#define TT_MS_LANGID_RUSSIAN_MOLDAVIA                  0x0819
+#define TT_MS_LANGID_CROATIAN_CROATIA                  0x041a
+#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN              0x081a
+#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC           0x0c1a
+#define TT_MS_LANGID_SLOVAK_SLOVAKIA                   0x041b
+#define TT_MS_LANGID_ALBANIAN_ALBANIA                  0x041c
+#define TT_MS_LANGID_SWEDISH_SWEDEN                    0x041d
+#define TT_MS_LANGID_SWEDISH_FINLAND                   0x081d
+#define TT_MS_LANGID_THAI_THAILAND                     0x041e
+#define TT_MS_LANGID_TURKISH_TURKEY                    0x041f
+#define TT_MS_LANGID_URDU_PAKISTAN                     0x0420
+#define TT_MS_LANGID_INDONESIAN_INDONESIA              0x0421
+#define TT_MS_LANGID_UKRAINIAN_UKRAINE                 0x0422
+#define TT_MS_LANGID_BELARUSIAN_BELARUS                0x0423
+#define TT_MS_LANGID_SLOVENE_SLOVENIA                  0x0424
+#define TT_MS_LANGID_ESTONIAN_ESTONIA                  0x0425
+#define TT_MS_LANGID_LATVIAN_LATVIA                    0x0426
+#define TT_MS_LANGID_LITHUANIAN_LITHUANIA              0x0427
+#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA      0x0827
+#define TT_MS_LANGID_MAORI_NEW_ZEALAND                 0x0428
+#define TT_MS_LANGID_FARSI_IRAN                        0x0429
+#define TT_MS_LANGID_VIETNAMESE_VIET_NAM               0x042a
+#define TT_MS_LANGID_ARMENIAN_ARMENIA                  0x042b
+#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN            0x042c
+#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC         0x082c
+#define TT_MS_LANGID_BASQUE_SPAIN                      0x042d
+#define TT_MS_LANGID_SORBIAN_GERMANY                   0x042e
+#define TT_MS_LANGID_MACEDONIAN_MACEDONIA              0x042f
+#define TT_MS_LANGID_SUTU_SOUTH_AFRICA                 0x0430
+#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA               0x0431
+#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA               0x0432
+#define TT_MS_LANGID_VENDA_SOUTH_AFRICA                0x0433
+#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA                0x0434
+#define TT_MS_LANGID_ZULU_SOUTH_AFRICA                 0x0435
+#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA            0x0436
+#define TT_MS_LANGID_GEORGIAN_GEORGIA                  0x0437
+#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS           0x0438
+#define TT_MS_LANGID_HINDI_INDIA                       0x0439
+#define TT_MS_LANGID_MALTESE_MALTA                     0x043a
+#define TT_MS_LANGID_SAAMI_LAPONIA                     0x043b
+#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043c
+#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083c
+#define TT_MS_LANGID_MALAY_MALAYSIA                    0x043e
+#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM           0x083e
+#define TT_MS_LANGID_KAZAK_KAZAKSTAN                   0x043f
+#define TT_MS_LANGID_SWAHILI_KENYA                     0x0441
+#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN            0x0443
+#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC         0x0843
+#define TT_MS_LANGID_TATAR_TATARSTAN                   0x0444
+#define TT_MS_LANGID_BENGALI_INDIA                     0x0445
+#define TT_MS_LANGID_PUNJABI_INDIA                     0x0446
+#define TT_MS_LANGID_GUJARATI_INDIA                    0x0447
+#define TT_MS_LANGID_ORIYA_INDIA                       0x0448
+#define TT_MS_LANGID_TAMIL_INDIA                       0x0449
+#define TT_MS_LANGID_TELUGU_INDIA                      0x044a
+#define TT_MS_LANGID_KANNADA_INDIA                     0x044b
+#define TT_MS_LANGID_MALAYALAM_INDIA                   0x044c
+#define TT_MS_LANGID_ASSAMESE_INDIA                    0x044d
+#define TT_MS_LANGID_MARATHI_INDIA                     0x044e
+#define TT_MS_LANGID_SANSKRIT_INDIA                    0x044f
+#define TT_MS_LANGID_KONKANI_INDIA                     0x0457
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* possible values of the `Name' identifier field in the name records of */
+  /* the TTF `name' table.  These values are platform independent.         */
+  /*                                                                       */
+#define TT_NAME_ID_COPYRIGHT             0
+#define TT_NAME_ID_FONT_FAMILY           1
+#define TT_NAME_ID_FONT_SUBFAMILY        2
+#define TT_NAME_ID_UNIQUE_ID             3
+#define TT_NAME_ID_FULL_NAME             4
+#define TT_NAME_ID_VERSION_STRING        5
+#define TT_NAME_ID_PS_NAME               6
+#define TT_NAME_ID_TRADEMARK             7
+/* the following values are from the OpenType spec */
+#define TT_NAME_ID_MANUFACTURER          8
+#define TT_NAME_ID_DESIGNER              9
+#define TT_NAME_ID_DESCRIPTION          10
+#define TT_NAME_ID_VENDOR_URL           11
+#define TT_NAME_ID_DESIGNER_URL         12
+#define TT_NAME_ID_LICENSE              13
+#define TT_NAME_ID_LICENSE_URL          14
+/* number 15 is reserved */
+#define TT_NAME_ID_PREFERRED_FAMILY     16
+#define TT_NAME_ID_PREFERRED_SUBFAMILY  17
+#define TT_NAME_ID_MAC_FULL_NAME        18
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Bit mask values for the Unicode ranges from the TTF `OS2 ' table.     */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+/* General Scripts Area */
+
+/* Bit  0   C0 Controls and Basic Latin */
+#define TT_UCR_BASIC_LATIN                      (1 <<  0) /* U+0000-U+007F */
+/* Bit  1   C1 Controls and Latin-1 Supplement */
+#define TT_UCR_LATIN1_SUPPLEMENT                (1 <<  1) /* U+0080-U+00FF */
+/* Bit  2   Latin Extended-A */
+#define TT_UCR_LATIN_EXTENDED_A                 (1 <<  2) /* U+0100-U+017F */
+/* Bit  3   Latin Extended-B */
+#define TT_UCR_LATIN_EXTENDED_B                 (1 <<  3) /* U+0180-U+024F */
+/* Bit  4   IPA Extensions */
+#define TT_UCR_IPA_EXTENSIONS                   (1 <<  4) /* U+0250-U+02AF */
+/* Bit  5   Spacing Modifier Letters */
+#define TT_UCR_SPACING_MODIFIER                 (1 <<  5) /* U+02B0-U+02FF */
+/* Bit  6   Combining Diacritical Marks */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS      (1 <<  6) /* U+0300-U+036F */
+/* Bit  7   Greek */
+#define TT_UCR_GREEK                            (1 <<  7) /* U+0370-U+03FF */
+/* Bit 8 is reserved (was: Greek Symbols and Coptic) */
+/* Bit  9   Cyrillic */
+#define TT_UCR_CYRILLIC                         (1 <<  9) /* U+0400-U+04FF */
+/* Bit 10   Armenian */
+#define TT_UCR_ARMENIAN                         (1 << 10) /* U+0530-U+058F */
+/* Bit 11   Hebrew */
+#define TT_UCR_HEBREW                           (1 << 11) /* U+0590-U+05FF */
+/* Bit 12 is reserved (was: Hebrew Extended) */
+/* Bit 13   Arabic */
+#define TT_UCR_ARABIC                           (1 << 13) /* U+0600-U+06FF */
+/* Bit 14 is reserved (was: Arabic Extended) */
+/* Bit 15   Devanagari */
+#define TT_UCR_DEVANAGARI                       (1 << 15) /* U+0900-U+097F */
+/* Bit 16   Bengali */
+#define TT_UCR_BENGALI                          (1 << 16) /* U+0980-U+09FF */
+/* Bit 17   Gurmukhi */
+#define TT_UCR_GURMUKHI                         (1 << 17) /* U+0A00-U+0A7F */
+/* Bit 18   Gujarati */
+#define TT_UCR_GUJARATI                         (1 << 18) /* U+0A80-U+0AFF */
+/* Bit 19   Oriya */
+#define TT_UCR_ORIYA                            (1 << 19) /* U+0B00-U+0B7F */
+/* Bit 20   Tamil */
+#define TT_UCR_TAMIL                            (1 << 20) /* U+0B80-U+0BFF */
+/* Bit 21   Telugu */
+#define TT_UCR_TELUGU                           (1 << 21) /* U+0C00-U+0C7F */
+/* Bit 22   Kannada */
+#define TT_UCR_KANNADA                          (1 << 22) /* U+0C80-U+0CFF */
+/* Bit 23   Malayalam */
+#define TT_UCR_MALAYALAM                        (1 << 23) /* U+0D00-U+0D7F */
+/* Bit 24   Thai */
+#define TT_UCR_THAI                             (1 << 24) /* U+0E00-U+0E7F */
+/* Bit 25   Lao */
+#define TT_UCR_LAO                              (1 << 25) /* U+0E80-U+0EFF */
+/* Bit 26   Georgian */
+#define TT_UCR_GEORGIAN                         (1 << 26) /* U+10A0-U+10FF */
+/* Bit 27 is reserved (was Georgian Extended) */
+/* Bit 28   Hangul Jamo */
+#define TT_UCR_HANGUL_JAMO                      (1 << 28) /* U+1100-U+11FF */
+/* Bit 29   Latin Extended Additional */
+#define TT_UCR_LATIN_EXTENDED_ADDITIONAL        (1 << 29) /* U+1E00-U+1EFF */
+/* Bit 30   Greek Extended */
+#define TT_UCR_GREEK_EXTENDED                   (1 << 30) /* U+1F00-U+1FFF */
+
+/* Symbols Area */
+
+/* Bit 31   General Punctuation */
+#define TT_UCR_GENERAL_PUNCTUATION              (1 << 31) /* U+2000-U+206F */
+/* Bit 32   Superscripts And Subscripts */
+#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS          (1 <<  0) /* U+2070-U+209F */
+/* Bit 33   Currency Symbols */
+#define TT_UCR_CURRENCY_SYMBOLS                 (1 <<  1) /* U+20A0-U+20CF */
+/* Bit 34   Combining Diacritical Marks For Symbols */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB (1 <<  2) /* U+20D0-U+20FF */
+/* Bit 35   Letterlike Symbols */
+#define TT_UCR_LETTERLIKE_SYMBOLS               (1 <<  3) /* U+2100-U+214F */
+/* Bit 36   Number Forms */
+#define TT_UCR_NUMBER_FORMS                     (1 <<  4) /* U+2150-U+218F */
+/* Bit 37   Arrows */
+#define TT_UCR_ARROWS                           (1 <<  5) /* U+2190-U+21FF */
+/* Bit 38   Mathematical Operators */
+#define TT_UCR_MATHEMATICAL_OPERATORS           (1 <<  6) /* U+2200-U+22FF */
+/* Bit 39 Miscellaneous Technical */
+#define TT_UCR_MISCELLANEOUS_TECHNICAL          (1 <<  7) /* U+2300-U+23FF */
+/* Bit 40   Control Pictures */
+#define TT_UCR_CONTROL_PICTURES                 (1 <<  8) /* U+2400-U+243F */
+/* Bit 41   Optical Character Recognition */
+#define TT_UCR_OCR                              (1 <<  9) /* U+2440-U+245F */
+/* Bit 42   Enclosed Alphanumerics */
+#define TT_UCR_ENCLOSED_ALPHANUMERICS           (1 << 10) /* U+2460-U+24FF */
+/* Bit 43   Box Drawing */
+#define TT_UCR_BOX_DRAWING                      (1 << 11) /* U+2500-U+257F */
+/* Bit 44   Block Elements */
+#define TT_UCR_BLOCK_ELEMENTS                   (1 << 12) /* U+2580-U+259F */
+/* Bit 45   Geometric Shapes */
+#define TT_UCR_GEOMETRIC_SHAPES                 (1 << 13) /* U+25A0-U+25FF */
+/* Bit 46   Miscellaneous Symbols */
+#define TT_UCR_MISCELLANEOUS_SYMBOLS            (1 << 14) /* U+2600-U+26FF */
+/* Bit 47   Dingbats */
+#define TT_UCR_DINGBATS                         (1 << 15) /* U+2700-U+27BF */
+
+/* CJK Phonetics and Symbols Area */
+
+/* Bit 48   CJK Symbols And Punctuation */
+#define TT_UCR_CJK_SYMBOLS                      (1 << 16) /* U+3000-U+303F */
+/* Bit 49   Hiragana */
+#define TT_UCR_HIRAGANA                         (1 << 17) /* U+3040-U+309F */
+/* Bit 50   Katakana */
+#define TT_UCR_KATAKANA                         (1 << 18) /* U+30A0-U+30FF */
+/* Bit 51   Bopomofo */
+#define TT_UCR_BOPOMOFO                         (1 << 19) /* U+3100-U+312F */
+/* Bit 52   Hangul Compatibility Jamo */
+#define TT_UCR_HANGUL_COMPATIBILITY_JAMO        (1 << 20) /* U+3130-U+318F */
+/* Bit 53   CJK Miscellaneous */
+#define TT_UCR_CJK_MISC                         (1 << 21) /* U+3190-U+319F */
+/* Bit 54   Enclosed CJK Letters And Months */
+#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS      (1 << 22) /* U+3200-U+32FF */
+/* Bit 55   CJK Compatibility */
+#define TT_UCR_CJK_COMPATIBILITY                (1 << 23) /* U+3300-U+33FF */
+
+/* Hangul Syllables Area */
+
+/* Bit 56   Hangul */
+#define TT_UCR_HANGUL                           (1 << 24) /* U+AC00-U+D7A3 */
+
+/* Surrogates Area */
+
+/* Bit 57   Surrogates */
+#define TT_UCR_SURROGATES                       (1 << 25) /* U+D800-U+DFFF */
+/* Bit 58 is reserved for Unicode SubRanges */
+
+/* CJK Ideographs Area */
+
+/* Bit 59   CJK Unified Ideographs */
+#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS           (1 << 27) /* U+4E00-U+9FFF */
+
+/* Private Use Area */
+
+/* Bit 60   Private Use */
+#define TT_UCR_PRIVATE_USE                      (1 << 28) /* U+E000-U+F8FF */
+
+/* Compatibility Area and Specials */
+
+/* Bit 61   CJK Compatibility Ideographs */
+#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS     (1 << 29) /* U+F900-U+FAFF */
+/* Bit 62   Alphabetic Presentation Forms */
+#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS    (1 << 30) /* U+FB00-U+FB4F */
+/* Bit 63   Arabic Presentation Forms-A */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_A      (1 << 31) /* U+FB50-U+FSFF */
+/* Bit 64   Combining Half Marks */
+#define TT_UCR_COMBINING_HALF_MARKS             (1 <<  0) /* U+FE20-U+FE2F */
+/* Bit 65   CJK Compatibility Forms */
+#define TT_UCR_CJK_COMPATIBILITY_FORMS          (1 <<  1) /* U+FE30-U+FE4F */
+/* Bit 66   Small Form Variants */
+#define TT_UCR_SMALL_FORM_VARIANTS              (1 <<  2) /* U+FE50-U+FE6F */
+/* Bit 67   Arabic Presentation Forms-B */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_B      (1 <<  3) /* U+FE70-U+FEFF */
+/* Bit 68   Halfwidth And Fullwidth Forms */
+#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS        (1 <<  4) /* U+FF00-U+FFEF */
+/* Bit 69   Specials */
+#define TT_UCR_SPECIALS                         (1 <<  5) /* U+FEFF,
+                                                             U+FFF0-U+FFFF */
+/* Bit 70   Tibetan */
+#define TT_UCR_TIBETAN                          (1 <<  6) /* U+0F00-U+0FBF */
+
+
+#endif /* TTNAMEID_H */
+
+
+/* END */
diff --git a/src/shared/tttags.h b/src/shared/tttags.h
new file mode 100644
index 0000000..73bbfc0
--- /dev/null
+++ b/src/shared/tttags.h
@@ -0,0 +1,60 @@
+/***************************************************************************/
+/*                                                                         */
+/*  tttags.h                                                               */
+/*                                                                         */
+/*    Tags for TrueType tables (specification only).                       */
+/*                                                                         */
+/*  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 TTAGS_H
+#define TTAGS_H
+
+
+#include <freetype.h>   /* for MAKE_TT_TAG() */
+
+
+#define TTAG_cmap  FT_MAKE_TAG( 'c', 'm', 'a', 'p' )
+#define TTAG_cvt   FT_MAKE_TAG( 'c', 'v', 't', ' ' )
+#define TTAG_EBDT  FT_MAKE_TAG( 'E', 'B', 'D', 'T' )
+#define TTAG_EBLC  FT_MAKE_TAG( 'E', 'B', 'L', 'C' )
+#define TTAG_EBSC  FT_MAKE_TAG( 'E', 'B', 'S', 'C' )
+#define TTAG_fpgm  FT_MAKE_TAG( 'f', 'p', 'g', 'm' )
+#define TTAG_gasp  FT_MAKE_TAG( 'g', 'a', 's', 'p' )
+#define TTAG_glyf  FT_MAKE_TAG( 'g', 'l', 'y', 'f' )
+#define TTAG_GSUB  FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
+#define TTAG_hdmx  FT_MAKE_TAG( 'h', 'd', 'm', 'x' )
+#define TTAG_head  FT_MAKE_TAG( 'h', 'e', 'a', 'd' )
+#define TTAG_hhea  FT_MAKE_TAG( 'h', 'h', 'e', 'a' )
+#define TTAG_hmtx  FT_MAKE_TAG( 'h', 'm', 't', 'x' )
+#define TTAG_kern  FT_MAKE_TAG( 'k', 'e', 'r', 'n' )
+#define TTAG_loca  FT_MAKE_TAG( 'l', 'o', 'c', 'a' )
+#define TTAG_LTSH  FT_MAKE_TAG( 'L', 'T', 'S', 'H' )
+#define TTAG_maxp  FT_MAKE_TAG( 'm', 'a', 'x', 'p' )
+#define TTAG_name  FT_MAKE_TAG( 'n', 'a', 'm', 'e' )
+#define TTAG_OS2   FT_MAKE_TAG( 'O', 'S', '/', '2' )
+#define TTAG_OTTO  FT_MAKE_TAG( 'O', 'T', 'T', 'O' )
+#define TTAG_PCLT  FT_MAKE_TAG( 'P', 'C', 'L', 'T' )
+#define TTAG_post  FT_MAKE_TAG( 'p', 'o', 's', 't' )
+#define TTAG_prep  FT_MAKE_TAG( 'p', 'r', 'e', 'p' )
+#define TTAG_true  FT_MAKE_TAG( 't', 'r', 'u', 'e' )
+#define TTAG_ttc   FT_MAKE_TAG( 't', 't', 'c', ' ' )
+#define TTAG_ttcf  FT_MAKE_TAG( 't', 't', 'c', 'f' )
+#define TTAG_VDMX  FT_MAKE_TAG( 'V', 'D', 'M', 'X' )
+#define TTAG_vhea  FT_MAKE_TAG( 'v', 'h', 'e', 'a' )
+#define TTAG_vmtx  FT_MAKE_TAG( 'v', 'm', 't', 'x' )
+
+
+#endif /* TTAGS_H */
+
+
+/* END */
diff --git a/src/shared/tttypes.h b/src/shared/tttypes.h
new file mode 100644
index 0000000..a5140e9
--- /dev/null
+++ b/src/shared/tttypes.h
@@ -0,0 +1,2066 @@
+/***************************************************************************/
+/*                                                                         */
+/*  tttypes.h                                                              */
+/*                                                                         */
+/*    Basic SFNT/TrueType type definitions and interface (specification    */
+/*    only).                                                               */
+/*                                                                         */
+/*  This code is shared by all TrueType and OpenType drivers.              */
+/*                                                                         */
+/*                                                                         */
+/*  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 TTTYPES_H
+#define TTTYPES_H
+
+
+#include <freetype.h>
+
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***                DEFINITIONS OF BASIC DATA TYPES                    ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The REDEFINE() macro is used to convert a FreeType generic type into  */
+  /* a TrueType-specific one.  It simply replaces the `FT_' prefix by      */
+  /* `TT_' in order to define compatible types like TT_Long, TT_Error,     */
+  /* TT_Outline, etc.                                                      */
+  /*                                                                       */
+#undef  REDEFINE
+#define REDEFINE( type )  typedef FT_##type  TT_##type
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Bool                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef of unsigned char, used for simple booleans.              */
+  /*                                                                       */
+  REDEFINE( Bool );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_FWord                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 16-bit integer used to store a distance in original font  */
+  /*    units.                                                             */
+  /*                                                                       */
+  REDEFINE( FWord );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_UFWord                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An unsigned 16-bit integer used to store a distance in original    */
+  /*    font units.                                                        */
+  /*                                                                       */
+  REDEFINE( UFWord );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Char                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the _signed_ char type.                       */
+  /*                                                                       */
+  REDEFINE( Char );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Byte                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the _unsigned_ char type.                     */
+  /*                                                                       */
+  REDEFINE( Byte );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_String                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple typedef for the char type, usually used for strings.      */
+  /*                                                                       */
+  REDEFINE( String );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Short                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for signed short.                                        */
+  /*                                                                       */
+  REDEFINE( Short );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_UShort                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for unsigned short.                                      */
+  /*                                                                       */
+  REDEFINE( UShort );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Int                                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for the int type.                                        */
+  /*                                                                       */
+  REDEFINE( Int );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_UInt                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for the unsigned int type.                               */
+  /*                                                                       */
+  REDEFINE( UInt );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Long                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for signed long.                                         */
+  /*                                                                       */
+  REDEFINE( Long );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_ULong                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A typedef for unsigned long.                                       */
+  /*                                                                       */
+  REDEFINE( ULong );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_F2Dot14                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 2.14 fixed float type used for unit vectors.              */
+  /*                                                                       */
+  REDEFINE( F2Dot14 );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_F26Dot6                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A signed 26.6 fixed float type used for vectorial pixel            */
+  /*    coordinates.                                                       */
+  /*                                                                       */
+  REDEFINE( F26Dot6 );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Fixed                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This type is used to store 16.16 fixed float values, like scales   */
+  /*    or matrix coefficients.                                            */
+  /*                                                                       */
+  REDEFINE( Fixed );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Pos                                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The type FT_Pos is a 32-bit integer used to store vectorial        */
+  /*    coordinates.  Depending on the context, these can represent        */
+  /*    distances in integer font units, or 26.6 fixed float pixel         */
+  /*    coordinates.                                                       */
+  /*                                                                       */
+  REDEFINE( Pos );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Vector                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2d vector; coordinates are of   */
+  /*    the TT_Pos type.                                                   */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    x :: The horizontal coordinate.                                    */
+  /*    y :: The vertical coordinate.                                      */
+  /*                                                                       */
+  REDEFINE( Vector );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_UnitVector                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2d vector unit vector.  Uses    */
+  /*    TT_F2Dot14 types.                                                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    x :: Horizontal coordinate.                                        */
+  /*    y :: Vertical coordinate.                                          */
+  /*                                                                       */
+  REDEFINE( UnitVector );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Matrix                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure used to store a 2x2 matrix.  Coefficients are   */
+  /*    in 16.16 fixed float format.  The computation performed is:        */
+  /*                                                                       */
+  /*       {                                                               */
+  /*          x' = x*xx + y*xy                                             */
+  /*          y' = x*yx + y*yy                                             */
+  /*       }                                                               */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    xx :: Matrix coefficient.                                          */
+  /*    xy :: Matrix coefficient.                                          */
+  /*    yx :: Matrix coefficient.                                          */
+  /*    yy :: Matrix coefficient.                                          */
+  /*                                                                       */
+  REDEFINE( Matrix );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_BBox                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold an outline's bounding box, i.e., the      */
+  /*    coordinates of its extrema in the horizontal and vertical          */
+  /*    directions.                                                        */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    xMin :: The horizontal minimum (left-most).                        */
+  /*    yMin :: The vertical minimum (bottom-most).                        */
+  /*    xMax :: The horizontal maximum (right-most).                       */
+  /*    yMax :: The vertical maximum (top-most).                           */
+  /*                                                                       */
+  REDEFINE( BBox );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Error                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType error code type.  A value of 0 is always interpreted  */
+  /*    as a successful operation.                                         */
+  /*                                                                       */
+  REDEFINE( Error );
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***             REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS         ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TTC_Header                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    TrueType collection header.  This table contains the offsets of    */
+  /*    the font headers of each distinct TrueType face in the file.       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    tag     :: Must be `ttc ' to indicate a TrueType collection.       */
+  /*    version :: The version number.                                     */
+  /*    count   :: The number of faces in the collection.  The             */
+  /*               specification says this should be an unsigned long, but */
+  /*               we use a signed long since we need the value -1 for     */
+  /*               specific purposes.                                      */
+  /*    offsets :: The offsets of the font headers, one per face.          */
+  /*                                                                       */
+  typedef struct  TTC_Header_
+  {
+    TT_ULong   Tag;
+    TT_Fixed   version;
+    TT_Long    DirCount;
+    TT_ULong*  TableDirectory;
+
+  } TTC_Header;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_TableDir                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This structure models a TrueType table directory.  It is used to   */
+  /*    access the various tables of the font face.                        */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    version       :: The version number; starts with 0x00010000.       */
+  /*    numTables     :: The number of tables.                             */
+  /*                                                                       */
+  /*    searchRange   :: Unused.                                           */
+  /*    entrySelector :: Unused.                                           */
+  /*    rangeShift    :: Unused.                                           */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This structure is only used during font opening.                   */
+  /*                                                                       */
+  typedef struct  TT_TableDir_
+  {
+    TT_Fixed   version;      /* should be 0x10000 */
+    TT_UShort  numTables;    /* number of tables  */
+
+    TT_UShort  searchRange;    /* These parameters are only used  */
+    TT_UShort  entrySelector;  /* for a dichotomy search in the   */
+    TT_UShort  rangeShift;     /* directory.  We ignore them.     */
+
+  } TT_TableDir;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Table                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This structure describes a given table of a TrueType font.         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    Tag      :: A four-bytes tag describing the table.                 */
+  /*    CheckSum :: The table checksum.  This value can be ignored.        */
+  /*    Offset   :: The offset of the table from the start of the TrueType */
+  /*                font in its resource.                                  */
+  /*    Length   :: The table length (in bytes).                           */
+  /*                                                                       */
+  typedef struct  TT_Table_
+  {
+    TT_ULong  Tag;        /*        table type */
+    TT_ULong  CheckSum;   /*    table checksum */
+    TT_ULong  Offset;     /* table file offset */
+    TT_ULong  Length;     /*      table length */
+
+  } TT_Table;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Header                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType font header table.  All       */
+  /*    fields follow the TrueType specification.                          */
+  /*                                                                       */
+  typedef struct  TT_Header_
+  {
+    TT_Fixed   Table_Version;
+    TT_Fixed   Font_Revision;
+
+    TT_Long    CheckSum_Adjust;
+    TT_Long    Magic_Number;
+
+    TT_UShort  Flags;
+    TT_UShort  Units_Per_EM;
+
+    TT_Long    Created [2];
+    TT_Long    Modified[2];
+
+    TT_FWord   xMin;
+    TT_FWord   yMin;
+    TT_FWord   xMax;
+    TT_FWord   yMax;
+
+    TT_UShort  Mac_Style;
+    TT_UShort  Lowest_Rec_PPEM;
+
+    TT_Short   Font_Direction;
+    TT_Short   Index_To_Loc_Format;
+    TT_Short   Glyph_Data_Format;
+
+  } TT_Header;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_HoriHeader                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType horizontal header, the `hhea' */
+  /*    table, as well as the corresponding horizontal metrics table,      */
+  /*    i.e., the `hmtx' table.                                            */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    Version                :: The table version.                       */
+  /*                                                                       */
+  /*    Ascender               :: The font's ascender, i.e., the distance  */
+  /*                              from the baseline to the top-most of all */
+  /*                              glyph points found in the font.          */
+  /*                                                                       */
+  /*                              This value is invalid in many fonts, as  */
+  /*                              it is usually set by the font designer,  */
+  /*                              and often reflects only a portion of the */
+  /*                              glyphs found in the font (maybe ASCII).  */
+  /*                                                                       */
+  /*                              You should use the `sTypoAscender' field */
+  /*                              of the OS/2 table instead if you want    */
+  /*                              the correct one.                         */
+  /*                                                                       */
+  /*    Descender              :: The font's descender, i.e., the distance */
+  /*                              from the baseline to the bottom-most of  */
+  /*                              all glyph points found in the font.  It  */
+  /*                              is negative.                             */
+  /*                                                                       */
+  /*                              This value is invalid in many fonts, as  */
+  /*                              it is usually set by the font designer,  */
+  /*                              and often reflects only a portion of the */
+  /*                              glyphs found in the font (maybe ASCII).  */
+  /*                                                                       */
+  /*                              You should use the `sTypoDescender'      */
+  /*                              field of the OS/2 table instead if you   */
+  /*                              want the correct one.                    */
+  /*                                                                       */
+  /*    Line_Gap               :: The font's line gap, i.e., the distance  */
+  /*                              to add to the ascender and descender to  */
+  /*                              get the BTB, i.e., the                   */
+  /*                              baseline-to-baseline distance for the    */
+  /*                              font.                                    */
+  /*                                                                       */
+  /*    advance_Width_Max      :: This field is the maximum of all advance */
+  /*                              widths found in the font.  It can be     */
+  /*                              used to compute the maximum width of an  */
+  /*                              arbitrary string of text.                */
+  /*                                                                       */
+  /*    min_Left_Side_Bearing  :: The minimum left side bearing of all     */
+  /*                              glyphs within the font.                  */
+  /*                                                                       */
+  /*    min_Right_Side_Bearing :: The minimum right side bearing of all    */
+  /*                              glyphs within the font.                  */
+  /*                                                                       */
+  /*    xMax_Extent            :: The maximum horizontal extent (i.e., the */
+  /*                              `width' of a glyph's bounding box) for   */
+  /*                              all glyphs in the font.                  */
+  /*                                                                       */
+  /*    caret_Slope_Rise       :: The rise coefficient of the cursor's     */
+  /*                              slope of the cursor (slope=rise/run).    */
+  /*                                                                       */
+  /*    caret_Slope_Run        :: The run coefficient of the cursor's      */
+  /*                              slope.                                   */
+  /*                                                                       */
+  /*    Reserved               :: 10 reserved bytes.                       */
+  /*                                                                       */
+  /*    metric_Data_Format     :: Always 0.                                */
+  /*                                                                       */
+  /*    number_Of_HMetrics     :: Number of HMetrics entries in the `hmtx' */
+  /*                              table -- this value can be smaller than  */
+  /*                              the total number of glyphs in the font.  */
+  /*                                                                       */
+  /*    long_metrics           :: A pointer into the `hmtx' table.         */
+  /*                                                                       */
+  /*    short_metrics          :: A pointer into the `hmtx' table.         */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
+  /*               be identical except for the names of their fields which */
+  /*               are different.                                          */
+  /*                                                                       */
+  /*               This ensures that a single function in the `ttload'     */
+  /*               module is able to read both the horizontal and vertical */
+  /*               headers.                                                */
+  /*                                                                       */
+  typedef struct  TT_HoriHeader_
+  {
+    TT_Fixed   Version;
+    TT_FWord   Ascender;
+    TT_FWord   Descender;
+    TT_FWord   Line_Gap;
+
+    TT_UFWord  advance_Width_Max;      /* advance width maximum */
+
+    TT_FWord   min_Left_Side_Bearing;  /* minimum left-sb       */
+    TT_FWord   min_Right_Side_Bearing; /* minimum right-sb      */
+    TT_FWord   xMax_Extent;            /* xmax extents          */
+    TT_FWord   caret_Slope_Rise;
+    TT_FWord   caret_Slope_Run;
+    TT_FWord   caret_Offset;
+
+    TT_Short   Reserved[4];
+
+    TT_Short   metric_Data_Format;
+    TT_UShort  number_Of_HMetrics;
+
+    /* The following fields are not defined by the TrueType specification */
+    /* but they're used to connect the metrics header to the relevant     */
+    /* `HMTX' table.                                                      */
+
+    void*      long_metrics;
+    void*      short_metrics;
+
+  } TT_HoriHeader;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_VertHeader                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType vertical header, the `vhea'   */
+  /*    table, as well as the corresponding vertical metrics table, i.e.,  */
+  /*    the `vmtx' table.                                                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    Version                 :: The table version.                      */
+  /*                                                                       */
+  /*    Ascender                :: The font's ascender, i.e., the distance */
+  /*                               from the baseline to the top-most of    */
+  /*                               all glyph points found in the font.     */
+  /*                                                                       */
+  /*                               This value is invalid in many fonts, as */
+  /*                               it is usually set by the font designer, */
+  /*                               and often reflects only a portion of    */
+  /*                               the glyphs found in the font (maybe     */
+  /*                               ASCII).                                 */
+  /*                                                                       */
+  /*                               You should use the `sTypoAscender'      */
+  /*                               field of the OS/2 table instead if you  */
+  /*                               want the correct one.                   */
+  /*                                                                       */
+  /*    Descender               :: The font's descender, i.e., the         */
+  /*                               distance from the baseline to the       */
+  /*                               bottom-most of all glyph points found   */
+  /*                               in the font.  It is negative.           */
+  /*                                                                       */
+  /*                               This value is invalid in many fonts, as */
+  /*                               it is usually set by the font designer, */
+  /*                               and often reflects only a portion of    */
+  /*                               the glyphs found in the font (maybe     */
+  /*                               ASCII).                                 */
+  /*                                                                       */
+  /*                               You should use the `sTypoDescender'     */
+  /*                               field of the OS/2 table instead if you  */
+  /*                               want the correct one.                   */
+  /*                                                                       */
+  /*    Line_Gap                :: The font's line gap, i.e., the distance */
+  /*                               to add to the ascender and descender to */
+  /*                               get the BTB, i.e., the                  */
+  /*                               baseline-to-baseline distance for the   */
+  /*                               font.                                   */
+  /*                                                                       */
+  /*    advance_Height_Max      :: This field is the maximum of all        */
+  /*                               advance heights found in the font.  It  */
+  /*                               can be used to compute the maximum      */
+  /*                               height of an arbitrary string of text.  */
+  /*                                                                       */
+  /*    min_Top_Side_Bearing    :: The minimum top side bearing of all     */
+  /*                               glyphs within the font.                 */
+  /*                                                                       */
+  /*    min_Bottom_Side_Bearing :: The minimum bottom side bearing of all  */
+  /*                               glyphs within the font.                 */
+  /*                                                                       */
+  /*    yMax_Extent             :: The maximum vertical extent (i.e., the  */
+  /*                               `height' of a glyph's bounding box) for */
+  /*                               all glyphs in the font.                 */
+  /*                                                                       */
+  /*    caret_Slope_Rise        :: The rise coefficient of the cursor's    */
+  /*                               slope of the cursor (slope=rise/run).   */
+  /*                                                                       */
+  /*    caret_Slope_Run         :: The run coefficient of the cursor's     */
+  /*                               slope.                                  */
+  /*                                                                       */
+  /*    Reserved                :: 10 reserved bytes.                      */
+  /*                                                                       */
+  /*    metric_Data_Format      :: Always 0.                               */
+  /*                                                                       */
+  /*    number_Of_HMetrics      :: Number of VMetrics entries in the       */
+  /*                               `vmtx' table -- this value can be       */
+  /*                               smaller than the total number of glyphs */
+  /*                               in the font.                            */
+  /*                                                                       */
+  /*    long_metrics           :: A pointer into the `vmtx' table.         */
+  /*                                                                       */
+  /*    short_metrics          :: A pointer into the `vmtx' table.         */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
+  /*               be identical except for the names of their fields which */
+  /*               are different.                                          */
+  /*                                                                       */
+  /*               This ensures that a single function in the `ttload'     */
+  /*               module is able to read both the horizontal and vertical */
+  /*               headers.                                                */
+  /*                                                                       */
+  typedef struct TT_VertHeader_
+  {
+    TT_Fixed   Version;
+    TT_FWord   Ascender;
+    TT_FWord   Descender;
+    TT_FWord   Line_Gap;
+
+    TT_UFWord  advance_Height_Max;      /* advance height maximum */
+
+    TT_FWord   min_Top_Side_Bearing;    /* minimum left-sb or top-sb       */
+    TT_FWord   min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb   */
+    TT_FWord   yMax_Extent;             /* xmax or ymax extents            */
+    TT_FWord   caret_Slope_Rise;
+    TT_FWord   caret_Slope_Run;
+    TT_FWord   caret_Offset;
+
+    TT_Short   Reserved[4];
+
+    TT_Short   metric_Data_Format;
+    TT_UShort  number_Of_VMetrics;
+
+    /* The following fields are not defined by the TrueType specification */
+    /* but they're used to connect the metrics header to the relevant     */
+    /* `HMTX' or `VMTX' table.                                            */
+
+    void*      long_metrics;
+    void*      short_metrics;
+
+  } TT_VertHeader;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_OS2                                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType OS/2 table. This is the long  */
+  /*    table version.  All fields comply to the TrueType specification.   */
+  /*                                                                       */
+  /*    Note that we now support old Mac fonts which do not include an     */
+  /*    OS/2 table.  In this case, the `version' field is always set to    */
+  /*    0xFFFF.                                                            */
+  /*                                                                       */
+  typedef struct  TT_OS2_
+  {
+    TT_UShort  version;                /* 0x0001 - more or 0xFFFF */
+    TT_FWord   xAvgCharWidth;
+    TT_UShort  usWeightClass;
+    TT_UShort  usWidthClass;
+    TT_Short   fsType;
+    TT_FWord   ySubscriptXSize;
+    TT_FWord   ySubscriptYSize;
+    TT_FWord   ySubscriptXOffset;
+    TT_FWord   ySubscriptYOffset;
+    TT_FWord   ySuperscriptXSize;
+    TT_FWord   ySuperscriptYSize;
+    TT_FWord   ySuperscriptXOffset;
+    TT_FWord   ySuperscriptYOffset;
+    TT_FWord   yStrikeoutSize;
+    TT_FWord   yStrikeoutPosition;
+    TT_Short   sFamilyClass;
+
+    TT_Byte    panose[10];
+
+    TT_ULong   ulUnicodeRange1;        /* Bits 0-31   */
+    TT_ULong   ulUnicodeRange2;        /* Bits 32-63  */
+    TT_ULong   ulUnicodeRange3;        /* Bits 64-95  */
+    TT_ULong   ulUnicodeRange4;        /* Bits 96-127 */
+
+    TT_Char    achVendID[4];
+
+    TT_UShort  fsSelection;
+    TT_UShort  usFirstCharIndex;
+    TT_UShort  usLastCharIndex;
+    TT_Short   sTypoAscender;
+    TT_Short   sTypoDescender;
+    TT_Short   sTypoLineGap;
+    TT_UShort  usWinAscent;
+    TT_UShort  usWinDescent;
+
+    /* only version 1 tables: */
+
+    TT_ULong   ulCodePageRange1;       /* Bits 0-31   */
+    TT_ULong   ulCodePageRange2;       /* Bits 32-63  */
+
+  } TT_OS2;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Postscript                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a TrueType Postscript table.  All fields */
+  /*    comply to the TrueType table.  This structure does not reference   */
+  /*    the Postscript glyph names, which can be nevertheless accessed     */
+  /*    with the `ttpost' module.                                          */
+  /*                                                                       */
+  typedef struct  TT_Postscript_
+  {
+    TT_Fixed  FormatType;
+    TT_Fixed  italicAngle;
+    TT_FWord  underlinePosition;
+    TT_FWord  underlineThickness;
+    TT_ULong  isFixedPitch;
+    TT_ULong  minMemType42;
+    TT_ULong  maxMemType42;
+    TT_ULong  minMemType1;
+    TT_ULong  maxMemType1;
+
+    /* Glyph names follow in the file, but we don't   */
+    /* load them by default.  See the ttpost.c file.  */
+
+  } TT_Postscript;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_CMapDir                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This structure describes the directory of the `cmap' table,        */
+  /*    containing the font's character mappings table.                    */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    tableVersionNumber :: The version number.                          */
+  /*    numCMaps           :: The number of charmaps in the font.          */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This structure is only used during font loading.                   */
+  /*                                                                       */
+  typedef struct  TT_CMapDir_
+  {
+    TT_UShort  tableVersionNumber;
+    TT_UShort  numCMaps;
+
+  } TT_CMapDir;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_CMapDirEntry                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This structure describes a charmap in a TrueType font.             */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    platformID :: An ID used to specify for which platform this        */
+  /*                  charmap is defined (FreeType manages all platforms). */
+  /*                                                                       */
+  /*    encodingID :: A platform-specific ID used to indicate which source */
+  /*                  encoding is used in this charmap.                    */
+  /*                                                                       */
+  /*    offset ::     The offset of the charmap relative to the start of   */
+  /*                  the `cmap' table.                                    */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This structure is only used during font loading.                   */
+  /*                                                                       */
+  typedef struct  TT_CMapDirEntry_
+  {
+    TT_UShort  platformID;
+    TT_UShort  platformEncodingID;
+    TT_Long    offset;
+
+  } TT_CMapDirEntry;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_MaxProfile                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The maximum profile is a table containing many max values which    */
+  /*    can be used to pre-allocate arrays.  This ensures that no memory   */
+  /*    allocation occurs during a glyph load.                             */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    version               :: The version number.                       */
+  /*                                                                       */
+  /*    numGlyphs             :: The number of glyphs in this TrueType     */
+  /*                             font.                                     */
+  /*                                                                       */
+  /*    maxPoints             :: The maximum number of points in a         */
+  /*                             non-composite TrueType glyph.  See also   */
+  /*                             the structure element                     */
+  /*                             `maxCompositePoints'.                     */
+  /*                                                                       */
+  /*    maxContours           :: The maximum number of contours in a       */
+  /*                             non-composite TrueType glyph.  See also   */
+  /*                             the structure element                     */
+  /*                             `maxCompositeContours'.                   */
+  /*                                                                       */
+  /*    maxCompositePoints    :: The maximum number of points in a         */
+  /*                             composite TrueType glyph.  See also the   */
+  /*                             structure element `maxPoints'.            */
+  /*                                                                       */
+  /*    maxCompositeContours  :: The maximum number of contours in a       */
+  /*                             composite TrueType glyph.  See also the   */
+  /*                             structure element `maxContours'.          */
+  /*                                                                       */
+  /*    maxZones              :: The maximum number of zones used for      */
+  /*                             glyph hinting.                            */
+  /*                                                                       */
+  /*    maxTwilightPoints     :: The maximum number of points in the       */
+  /*                             twilight zone used for glyph hinting.     */
+  /*                                                                       */
+  /*    maxStorage            :: The maximum number of elements in the     */
+  /*                             storage area used for glyph hinting.      */
+  /*                                                                       */
+  /*    maxFunctionDefs       :: The maximum number of function            */
+  /*                             definitions in the TrueType bytecode for  */
+  /*                             this font.                                */
+  /*                                                                       */
+  /*    maxInstructionDefs    :: The maximum number of instruction         */
+  /*                             definitions in the TrueType bytecode for  */
+  /*                             this font.                                */
+  /*                                                                       */
+  /*    maxStackElements      :: The maximum number of stack elements used */
+  /*                             during bytecode interpretation.           */
+  /*                                                                       */
+  /*    maxSizeOfInstructions :: The maximum number of TrueType opcodes    */
+  /*                             used for glyph hinting.                   */
+  /*                                                                       */
+  /*    maxComponentElements  :: An obscure value related to composite     */
+  /*                             glyphs definitions.                       */
+  /*                                                                       */
+  /*    maxComponentDepth     :: An obscure value related to composite     */
+  /*                             glyphs definitions.  Probably the maximum */
+  /*                             number of simple glyphs in a composite.   */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This structure is only used during font loading.                   */
+  /*                                                                       */
+  typedef struct  TT_MaxProfile_
+  {
+    TT_Fixed   version;
+    TT_UShort  numGlyphs;
+    TT_UShort  maxPoints;
+    TT_UShort  maxContours;
+    TT_UShort  maxCompositePoints;
+    TT_UShort  maxCompositeContours;
+    TT_UShort  maxZones;
+    TT_UShort  maxTwilightPoints;
+    TT_UShort  maxStorage;
+    TT_UShort  maxFunctionDefs;
+    TT_UShort  maxInstructionDefs;
+    TT_UShort  maxStackElements;
+    TT_UShort  maxSizeOfInstructions;
+    TT_UShort  maxComponentElements;
+    TT_UShort  maxComponentDepth;
+
+  } TT_MaxProfile;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_LongMetrics                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure modeling the long metrics of the `hmtx' and `vmtx'     */
+  /*    TrueType tables.  The values are expressed in font units.          */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    advance :: The advance width or height for the glyph.              */
+  /*    bearing :: The left-side or top-side bearing for the glyph.        */
+  /*                                                                       */
+  typedef struct  TT_LongMetrics_
+  {
+    TT_UShort  advance;
+    TT_Short   bearing;
+
+  } TT_LongMetrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type> TT_ShortMetrics                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple type to model the short metrics of the `hmtx' and `vmtx'  */
+  /*    tables.                                                            */
+  /*                                                                       */
+  typedef TT_Short  TT_ShortMetrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_NameRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure modeling TrueType name records.  Name records are used */
+  /*    to store important strings like family name, style name,           */
+  /*    copyright, etc. in _localized_ versions (i.e., language, encoding, */
+  /*    etc).                                                              */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    platformID   :: The ID of the name's encoding platform.            */
+  /*                                                                       */
+  /*    encodingID   :: The platform-specific ID for the name's encoding.  */
+  /*                                                                       */
+  /*    languageID   :: The platform-specific ID for the name's language.  */
+  /*                                                                       */
+  /*    nameID       :: The ID specifying what kind of name this is.       */
+  /*                                                                       */
+  /*    stringLength :: The length of the string in bytes.                 */
+  /*                                                                       */
+  /*    stringOffset :: The offset to the string in the `name' table.      */
+  /*                                                                       */
+  /*    string       :: A pointer to the string's bytes.  Note that these  */
+  /*                    are usually UTF-16 encoded characters.             */
+  /*                                                                       */
+  typedef struct  TT_NameRec_
+  {
+    TT_UShort  platformID;
+    TT_UShort  encodingID;
+    TT_UShort  languageID;
+    TT_UShort  nameID;
+    TT_UShort  stringLength;
+    TT_UShort  stringOffset;
+
+    /* this last field is not defined in the spec */
+    /* but used by the FreeType engine            */
+
+    TT_Byte*   string;
+
+  } TT_NameRec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_NameTable                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure modeling the TrueType name table.                      */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    format         :: The format of the name table.                    */
+  /*                                                                       */
+  /*    numNameRecords :: The number of names in table.                    */
+  /*                                                                       */
+  /*    storageOffset  :: The offset of the name table in the `name'       */
+  /*                      TrueType table.                                  */
+  /*                                                                       */
+  /*    names          :: An array of name records.                        */
+  /*                                                                       */
+  /*    storage        :: The names storage area.                          */
+  /*                                                                       */
+  typedef struct  TT_NameTable_
+  {
+    TT_UShort    format;
+    TT_UShort    numNameRecords;
+    TT_UShort    storageOffset;
+    TT_NameRec*  names;
+    TT_Byte*     storage;
+
+  } TT_NameTable;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***             OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS         ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_GaspRange                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A tiny structure used to model a gasp range according to the       */
+  /*    TrueType specification.                                            */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    maxPPEM  :: The maximum ppem value to which `gaspFlag' applies.    */
+  /*                                                                       */
+  /*    gaspFlag :: A flag describing the grid-fitting and anti-aliasing   */
+  /*                modes to be used.                                      */
+  /*                                                                       */
+  typedef struct  TT_GaspRange_
+  {
+    TT_UShort  maxPPEM;
+    TT_UShort  gaspFlag;
+
+  } TT_GaspRange;
+
+
+#define TT_GASP_GRIDFIT  0x01
+#define TT_GASP_DOGRAY   0x02
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Gasp                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure modeling the TrueType `gasp' table used to specify     */
+  /*    grid-fitting and anti-aliasing behaviour.                          */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    version    :: The version number.                                  */
+  /*    numRanges  :: The number of gasp ranges in table.                  */
+  /*    gaspRanges :: An array of gasp ranges.                             */
+  /*                                                                       */
+  typedef struct  TT_Gasp_
+  {
+    TT_UShort      version;
+    TT_UShort      numRanges;
+    TT_GaspRange*  gaspRanges;
+
+  } TT_Gasp;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_HdmxRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A small structure used to model the pre-computed widths of a given */
+  /*    size.  They're found in the `hdmx' table.                          */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    ppem      :: The pixels per EM value at which these metrics apply. */
+  /*                                                                       */
+  /*    max_width :: The maximum advance width for this metric.            */
+  /*                                                                       */
+  /*    widths    :: An array of widths.  Note: These are 8-bit bytes.     */
+  /*                                                                       */
+  typedef struct  TT_HdmxRec_
+  {
+    TT_Byte   ppem;
+    TT_Byte   max_width;
+    TT_Byte*  widths;
+
+  } TT_HdmxRec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_HdmxRec                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model the `hdmx' table, which contains         */
+  /*    pre-computed widths for a set of given sizes/dimensions.           */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    version     :: The version number.                                 */
+  /*    num_records :: The number of hdmx records.                         */
+  /*    records     :: An array of hdmx records.                           */
+  /*                                                                       */
+  typedef struct  TT_Hdmx_
+  {
+    TT_UShort    version;
+    TT_Short     num_records;
+    TT_HdmxRec*  records;
+
+  } TT_Hdmx;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Kern_0_Pair                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a kerning pair for the kerning table     */
+  /*    format 0.  The engine now loads this table if it finds one in the  */
+  /*    font file.                                                         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    left  :: The index of the left glyph in pair.                      */
+  /*    right :: The index of the right glyph in pair.                     */
+  /*    value :: The kerning distance.  A positive value spaces the        */
+  /*             glyphs, a negative one makes them closer.                 */
+  /*                                                                       */
+  typedef struct  TT_Kern_0_Pair_
+  {
+    TT_UShort  left;   /* index of left  glyph in pair */
+    TT_UShort  right;  /* index of right glyph in pair */
+    TT_FWord   value;  /* kerning value                */
+
+  } TT_Kern_0_Pair;
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***                  EMBEDDED BITMAPS SUPPORT                         ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Metrics                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold the big metrics of a given glyph bitmap   */
+  /*    in a TrueType or OpenType font.  These are usually found in the    */
+  /*    `EBDT' (Microsoft) or `bdat' (Apple) table.                        */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    height       :: The glyph height in pixels.                        */
+  /*                                                                       */
+  /*    width        :: The glyph width in pixels.                         */
+  /*                                                                       */
+  /*    horiBearingX :: The horizontal left bearing.                       */
+  /*                                                                       */
+  /*    horiBearingY :: The horizontal top bearing.                        */
+  /*                                                                       */
+  /*    horiAdvance  :: The horizontal advance.                            */
+  /*                                                                       */
+  /*    vertBearingX :: The vertical left bearing.                         */
+  /*                                                                       */
+  /*    vertBearingY :: The vertical top bearing.                          */
+  /*                                                                       */
+  /*    vertAdvance  :: The vertical advance.                              */
+  /*                                                                       */
+  typedef struct  TT_SBit_Metrics_
+  {
+    TT_Byte  height;
+    TT_Byte  width;
+
+    TT_Char  horiBearingX;
+    TT_Char  horiBearingY;
+    TT_Byte  horiAdvance;
+
+    TT_Char  vertBearingX;
+    TT_Char  vertBearingY;
+    TT_Byte  vertAdvance;
+
+  } TT_SBit_Metrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Small_Metrics                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to hold the small metrics of a given glyph bitmap */
+  /*    in a TrueType or OpenType font.  These are usually found in the    */
+  /*    `EBDT' (Microsoft) or the `bdat' (Apple) table.                    */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    height    :: The glyph height in pixels.                           */
+  /*                                                                       */
+  /*    width     :: The glyph width in pixels.                            */
+  /*                                                                       */
+  /*    bearingX  :: The left-side bearing.                                */
+  /*                                                                       */
+  /*    bearingY  :: The top-side bearing.                                 */
+  /*                                                                       */
+  /*    advance   :: The advance width or height.                          */
+  /*                                                                       */
+  typedef struct  TT_SBit_Small_Metrics_
+  {
+    TT_Byte  height;
+    TT_Byte  width;
+
+    TT_Char  bearingX;
+    TT_Char  bearingY;
+    TT_Byte  advance;
+
+  } TT_SBit_Small_Metrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Line_Metrics                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to describe the text line metrics of a given      */
+  /*    bitmap strike, for either a horizontal or vertical layout.         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    ascender                :: The ascender in pixels.                 */
+  /*                                                                       */
+  /*    descender               :: The descender in pixels.                */
+  /*                                                                       */
+  /*    max_width               :: The maximum glyph width in pixels.      */
+  /*                                                                       */
+  /*    caret_slope_enumerator  :: Rise of the caret slope, typically set  */
+  /*                               to 1 for non-italic fonts.              */
+  /*                                                                       */
+  /*    caret_slope_denominator :: Rise of the caret slope, typically set  */
+  /*                               to 0 for non-italic fonts.              */
+  /*                                                                       */
+  /*    caret_offset            :: Offset in pixels to move the caret for  */
+  /*                               proper positioning.                     */
+  /*                                                                       */
+  /*    min_origin_SB           :: Minimum of horiBearingX (resp.          */
+  /*                               vertBearingY).                          */
+  /*    min_advance_SB          :: Minimum of                              */
+  /*                                                                       */
+  /*                                 horizontal advance -                  */
+  /*                                   ( horiBearingX + width )            */
+  /*                                                                       */
+  /*                               resp.                                   */
+  /*                                                                       */
+  /*                                 vertical advance -                    */
+  /*                                   ( vertBearingY + height )           */
+  /*                                                                       */
+  /*    max_before_BL           :: Maximum of horiBearingY (resp.          */
+  /*                               vertBearingY).                          */
+  /*                                                                       */
+  /*    min_after_BL            :: Minimum of                              */
+  /*                                                                       */
+  /*                                 horiBearingY - height                 */
+  /*                                                                       */
+  /*                               resp.                                   */
+  /*                                                                       */
+  /*                                 vertBearingX - width                  */
+  /*                                                                       */
+  typedef struct  TT_SBit_Line_Metrics_
+  {
+    TT_Char  ascender;
+    TT_Char  descender;
+    TT_Byte  max_width;
+    TT_Char  caret_slope_numerator;
+    TT_Char  caret_slope_denominator;
+    TT_Char  caret_offset;
+    TT_Char  min_origin_SB;
+    TT_Char  min_advance_SB;
+    TT_Char  max_before_BL;
+    TT_Char  min_after_BL;
+    TT_Char  pads[2];
+
+  } TT_SBit_Line_Metrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Range                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A TrueType/OpenType subIndexTable as defined in the `EBLC'         */
+  /*    (Microsoft) or `bloc' (Apple) tables.                              */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    first_glyph   :: The first glyph index in the range.               */
+  /*                                                                       */
+  /*    last_glyph    :: The last glyph index in the range.                */
+  /*                                                                       */
+  /*    index_format  :: The format of index table.  Valid values are 1    */
+  /*                     to 5.                                             */
+  /*                                                                       */
+  /*    image_format  :: The format of `EBDT' image data.                  */
+  /*                                                                       */
+  /*    image_offset  :: The offset to image data in `EBDT'.               */
+  /*                                                                       */
+  /*    image_size    :: For index formats 2 and 5.  This is the size in   */
+  /*                     bytes of each glyph bitmap.                       */
+  /*                                                                       */
+  /*    big_metrics   :: For index formats 2 and 5.  This is the big       */
+  /*                     metrics for each glyph bitmap.                    */
+  /*                                                                       */
+  /*    num_glyphs    :: For index formats 4 and 5.  This is the number of */
+  /*                     glyphs in the code array.                         */
+  /*                                                                       */
+  /*    glyph_offsets :: For index formats 1 and 3.                        */
+  /*                                                                       */
+  /*    glyph_codes   :: For index formats 4 and 5.                        */
+  /*                                                                       */
+  /*    table_offset  :: The offset of the index table in the `EBLC'       */
+  /*                     table.  Only used during strike loading.          */
+  /*                                                                       */
+  typedef struct  TT_SBit_Range
+  {
+    TT_UShort        first_glyph;
+    TT_UShort        last_glyph;
+
+    TT_UShort        index_format;
+    TT_UShort        image_format;
+    TT_ULong         image_offset;
+
+    TT_ULong         image_size;
+    TT_SBit_Metrics  metrics;
+    TT_ULong         num_glyphs;
+
+    TT_ULong*        glyph_offsets;
+    TT_UShort*       glyph_codes;
+
+    TT_ULong         table_offset;
+
+  } TT_SBit_Range;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Strike                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used describe a given bitmap strike in the `EBLC'      */
+  /*    (Microsoft) or `bloc' (Apple) tables.                              */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*   num_index_ranges :: The number of index ranges.                     */
+  /*                                                                       */
+  /*   index_ranges     :: An array of glyph index ranges.                 */
+  /*                                                                       */
+  /*   color_ref        :: Unused.  A color reference?                     */
+  /*                                                                       */
+  /*   hori             :: The line metrics for horizontal layouts.        */
+  /*                                                                       */
+  /*   vert             :: The line metrics for vertical layouts.          */
+  /*                                                                       */
+  /*   start_glyph      :: The lowest glyph index for this strike.         */
+  /*                                                                       */
+  /*   end_glyph        :: The highest glyph index for this strike.        */
+  /*                                                                       */
+  /*   x_ppem           :: The number of horizontal pixels per EM.         */
+  /*                                                                       */
+  /*   y_ppem           :: The number of vertical pixels per EM.           */
+  /*                                                                       */
+  /*   bit_depth        :: The bit depth.  Valid values are 1, 2, 4,       */
+  /*                       and 8.                                          */
+  /*                                                                       */
+  /*   flags            :: Is this a vertical or horizontal strike?        */
+  /*                                                                       */
+  typedef struct  TT_SBit_Strike_
+  {
+    TT_Int                 num_ranges;
+    TT_SBit_Range*         sbit_ranges;
+    TT_ULong               ranges_offset;
+
+    TT_ULong               color_ref;
+
+    TT_SBit_Line_Metrics   hori;
+    TT_SBit_Line_Metrics   vert;
+
+    TT_UShort              start_glyph;
+    TT_UShort              end_glyph;
+
+    TT_Byte                x_ppem;
+    TT_Byte                y_ppem;
+
+    TT_Byte                bit_depth;
+    TT_Char                flags;
+
+  } TT_SBit_Strike;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Component                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A simple structure to describe a compound sbit element.            */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    glyph_code :: The element's glyph index.                           */
+  /*    x_offset   :: The element's left bearing.                          */
+  /*    y_offset   :: The element's top bearing.                           */
+  /*                                                                       */
+  typedef struct  TT_SBit_Component_
+  {
+    TT_UShort  glyph_code;
+
+    TT_Char    x_offset;
+    TT_Char    y_offset;
+
+  } TT_SBit_Component;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_SBit_Scale                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used describe a given bitmap scaling table, as defined */
+  /*    in the `EBSC' table.                                               */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    hori              :: The horizontal line metrics.                  */
+  /*                                                                       */
+  /*    vert              :: The vertical line metrics.                    */
+  /*                                                                       */
+  /*    x_ppem            :: The number of horizontal pixels per EM.       */
+  /*                                                                       */
+  /*    y_ppem            :: The number of vertical pixels per EM.         */
+  /*                                                                       */
+  /*    x_ppem_substitute :: Substitution x_ppem value.                    */
+  /*                                                                       */
+  /*    y_ppem_substitute :: Substitution y_ppem value.                    */
+  /*                                                                       */
+  typedef struct  TT_SBit_Scale_
+  {
+    TT_SBit_Line_Metrics  hori;
+    TT_SBit_Line_Metrics  vert;
+
+    TT_Byte               x_ppem;
+    TT_Byte               y_ppem;
+
+    TT_Byte               x_ppem_substitute;
+    TT_Byte               y_ppem_substitute;
+
+  } TT_SBit_Scale;
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***                  POSTSCRIPT GLYPH NAMES SUPPORT                   ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Post_20                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Postscript names sub-table, format 2.0.  Stores the PS name of     */
+  /*    each glyph in the font face.                                       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    num_glyphs    :: The number of named glyphs in the table.          */
+  /*                                                                       */
+  /*    num_names     :: The number of PS names stored in the table.       */
+  /*                                                                       */
+  /*    glyph_indices :: The indices of the glyphs in the names arrays.    */
+  /*                                                                       */
+  /*    glyph_names   :: The PS names not in Mac Encoding.                 */
+  /*                                                                       */
+  typedef struct  TT_Post_20_
+  {
+    TT_UShort   num_glyphs;
+    TT_UShort   num_names;
+    TT_UShort*  glyph_indices;
+    TT_Char**   glyph_names;
+
+  } TT_Post_20;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Post_25                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Postscript names sub-table, format 2.5.  Stores the PS name of     */
+  /*    each glyph in the font face.                                       */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    num_glyphs :: The number of glyphs in the table.                   */
+  /*                                                                       */
+  /*    offsets    :: An array of signed offsets in a normal Mac           */
+  /*                  Postscript name encoding.                            */
+  /*                                                                       */
+  typedef struct  TT_Post_25_
+  {
+    TT_UShort  num_glyphs;
+    TT_Char*   offsets;
+
+  } TT_Post_25;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Post_Names                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Postscript names table, either format 2.0 or 2.5.                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    loaded    :: A flag to indicate whether the PS names are loaded.   */
+  /*                                                                       */ 
+  /*    format_20 :: The sub-table used for format 2.0.                    */
+  /*                                                                       */
+  /*    format_25 :: The sub-table used for format 2.5.                    */
+  /*                                                                       */
+  typedef struct  TT_Post_Names_
+  {
+    TT_Bool       loaded;
+
+    union
+    {
+      TT_Post_20  format_20;
+      TT_Post_25  format_25;
+
+    } names;
+
+  } TT_Post_Names;
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***                  TRUETYPE CHARMAPS SUPPORT                        ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /* format 0 */
+  typedef struct  TT_CMap0_
+  {
+    TT_Byte*  glyphIdArray;
+
+  } TT_CMap0;
+
+
+  /* format 2 */
+  typedef struct  TT_CMap2SubHeader_
+  {
+    TT_UShort  firstCode;      /* first valid low byte         */
+    TT_UShort  entryCount;     /* number of valid low bytes    */
+    TT_Short   idDelta;        /* delta value to glyphIndex    */
+    TT_UShort  idRangeOffset;  /* offset from here to 1st code */
+
+  } TT_CMap2SubHeader;
+
+
+  typedef struct  TT_CMap2_
+  {
+    TT_UShort*  subHeaderKeys;
+    /* high byte mapping table            */
+    /* value = subHeader index * 8        */
+
+    TT_CMap2SubHeader*  subHeaders;
+    TT_UShort*          glyphIdArray;
+    TT_UShort           numGlyphId;   /* control value */
+
+  } TT_CMap2;
+
+
+  /* format 4 */
+  typedef struct  TT_CMap4Segment_
+  {
+    TT_UShort  endCount;
+    TT_UShort  startCount;
+    TT_Short   idDelta;
+    TT_UShort  idRangeOffset;
+
+  } TT_CMap4Segment;
+
+
+  typedef struct  TT_CMap4_
+  {
+    TT_UShort  segCountX2;     /* number of segments * 2       */
+    TT_UShort  searchRange;    /* these parameters can be used */
+    TT_UShort  entrySelector;  /* for a binary search          */
+    TT_UShort  rangeShift;
+
+    TT_CMap4Segment*  segments;
+    TT_UShort*        glyphIdArray;
+    TT_UShort         numGlyphId;   /* control value */
+
+  } TT_CMap4;
+
+
+  /* format 6 */
+  typedef struct  TT_CMap6_
+  {
+    TT_UShort   firstCode;      /* first character code of subrange      */
+    TT_UShort   entryCount;     /* number of character codes in subrange */
+
+    TT_UShort*  glyphIdArray;
+
+  } TT_CMap6;
+
+  typedef struct TT_CMapTable_  TT_CMapTable;
+
+  typedef
+  TT_UInt  (*TT_CharMap_Func)( TT_CMapTable*  charmap,
+                               TT_ULong       char_code );
+
+  /* charmap table */
+  struct  TT_CMapTable_
+  {
+    TT_UShort  platformID;
+    TT_UShort  platformEncodingID;
+    TT_UShort  format;
+    TT_UShort  length;
+    TT_UShort  version;
+
+    TT_Bool    loaded;
+    TT_ULong   offset;
+
+    union
+    {
+      TT_CMap0  cmap0;
+      TT_CMap2  cmap2;
+      TT_CMap4  cmap4;
+      TT_CMap6  cmap6;
+    } c;
+
+    TT_CharMap_Func  get_index;
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_CharMapRec                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*   The TrueType character map object type.                             */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    root :: The parent character map structure.                        */
+  /*    cmap :: The used character map.                                    */
+  /*                                                                       */
+  typedef struct  TT_CharMapRec_
+  {
+    FT_CharMapRec   root;
+    TT_CMapTable    cmap;
+    
+  } TT_CharMapRec;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***                  ORIGINAL TT_FACE CLASS DEFINITION                ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This structure/class is defined here because it is common to the      */
+  /* following formats: TTF, OpenType-TT, and OpenType-CFF.                */
+  /*                                                                       */
+  /* Note however that the classes TT_Size, TT_GlyphSlot, and TT_CharMap   */
+  /* are not shared between font drivers, and are thus defined normally in */
+  /* `drivers/truetype/ttobjs.h'.                                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Face                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a TrueType face/font object.  A TT_Face encapsulates   */
+  /*    the resolution and scaling independent parts of a TrueType font    */
+  /*    resource.                                                          */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The TT_Face structure is also used as a `parent class' for the     */
+  /*    OpenType-CFF class (T2_Face).                                      */
+  /*                                                                       */
+  typedef struct TT_FaceRec_*   TT_Face;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_CharMap                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a TrueType character mapping object.                   */
+  /*                                                                       */
+  typedef struct TT_CharMapRec_*  TT_CharMap;
+
+
+  /* a function type used for the truetype bytecode interpreter hooks */
+  typedef TT_Error  (*TT_Interpreter)( void*  exec_context );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TT_Goto_Table_Func                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Seeks a stream to the start of a given TrueType table.             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face      :: A handle to the target face object.                   */
+  /*    tag       :: a 4-byte tag used to name the table                   */
+  /*    stream    :: The input stream.                                     */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    length    :: length of table in bytes. Set to 0 when not needed    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The stream cursor must be at the font file's origin                */
+  /*                                                                       */
+  typedef
+  TT_Error  (*TT_Goto_Table_Func)( TT_Face    face,
+                                   TT_ULong   tag,
+                                   FT_Stream  stream,
+                                   TT_ULong  *length );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                         TrueType Face Type                            */
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_Face                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType face class.  These objects model the resolution and   */
+  /*    point-size independent data found in a TrueType font file.         */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    root              :: The base FT_Face structure, managed by the    */
+  /*                         base layer.                                   */
+  /*                                                                       */
+  /*    ttcHeader         :: The TrueType collection header, used when the */
+  /*                         file is a `ttc' rather than a `ttf'.  For     */
+  /*                         ordinary font files, the field                */
+  /*                         `ttcHeader.DirCount' is set to 0.             */
+  /*                                                                       */
+  /*    num_tables        :: The number of TrueType tables in this font    */
+  /*                         file.                                         */
+  /*                                                                       */
+  /*    dir_tables        :: The directory of TrueType tables for this     */
+  /*                         font file.                                    */
+  /*                                                                       */
+  /*    header            :: The font's font header (`head' table).  Read  */
+  /*                         on font opening.                              */
+  /*                                                                       */
+  /*    horizontal        :: The font's horizontal header (`hhea' table).  */
+  /*                         This field also contains the associated       */
+  /*                         horizontal metrics table (`hmtx').            */
+  /*                                                                       */
+  /*    max_profile       :: The font's maximum profile table.  Read on    */
+  /*                         font opening.  Note that some maximum values  */
+  /*                         cannot be taken directly from this table.  We */
+  /*                         thus define additional fields below to hold   */
+  /*                         the computed maxima.                          */
+  /*                                                                       */
+  /*    max_components    :: The maximum number of glyph components        */
+  /*                         required to load any composite glyph from     */
+  /*                         this font.  Used to size the load stack.      */
+  /*                                                                       */
+  /*    vertical_info     :: A boolean which is set when the font file     */
+  /*                         contains vertical metrics.  If not, the value */
+  /*                         of the `vertical' field is undefined.         */
+  /*                                                                       */
+  /*    vertical          :: The font's vertical header (`vhea' table).    */
+  /*                         This field also contains the associated       */
+  /*                         vertical metrics table (`vmtx'), if found.    */
+  /*                         IMPORTANT: The contents of this field is      */
+  /*                         undefined if the `verticalInfo' field is      */
+  /*                         unset.                                        */
+  /*                                                                       */
+  /*    num_names         :: The number of name records within this        */
+  /*                         TrueType font.                                */
+  /*                                                                       */
+  /*    name_table        :: The table of name records (`name').           */
+  /*                                                                       */
+  /*    os2               :: The font's OS/2 table (`OS/2').               */
+  /*                                                                       */
+  /*    postscript        :: The font's PostScript table (`post' table).   */
+  /*                         The PostScript glyph names are not loaded by  */
+  /*                         the driver on face opening.  See the `ttpost' */
+  /*                         module for more details.                      */
+  /*                                                                       */
+  /*    num_charmaps      :: The number of character mappings in the font. */
+  /*                                                                       */
+  /*    charmaps          :: The array of charmap objects for this font    */
+  /*                         file.  Note that this field is a typeless     */
+  /*                         pointer.  The Reason is that the format of    */
+  /*                         charmaps varies with the underlying font      */
+  /*                         format and cannot be determined here.         */
+  /*                                                                       */
+  /*    goto_face         :: a function called by each TrueType table      */
+  /*                         loader to position a stream's cursor to the   */
+  /*                         start of a given table according to its tag.  */
+  /*                         it defaults to TT_Goto_Face but can be        */
+  /*                         different for strange formats (e.g. Type 42)  */
+  /*                                                                       */
+  /*    sfnt              :: a pointer to the SFNT `driver' interface.     */
+  /*                                                                       */
+  /*    hdmx              :: The face's horizontal device metrics (`hdmx'  */
+  /*                         table).  This table is optional in            */
+  /*                         TrueType/OpenType fonts.                      */
+  /*                                                                       */
+  /*    gasp              :: The grid-fitting and scaling properties table */
+  /*                         (`gasp').  This table is optional in          */
+  /*                         TrueType/OpenType fonts.                      */
+  /*                                                                       */
+  /*    num_sbit_strikes  :: The number of sbit strikes, i.e., bitmap      */
+  /*                         sizes, embedded in this font.                 */
+  /*                                                                       */
+  /*    sbit_strikes      :: An array of sbit strikes embedded in this     */
+  /*                         font.  This table is optional in a            */
+  /*                         TrueType/OpenType font.                       */
+  /*                                                                       */
+  /*    num_sbit_scales   :: The number of sbit scales for this font.      */
+  /*                                                                       */
+  /*    sbit_scales       :: Array of sbit scales embedded in this font.   */
+  /*                         This table is optional in a TrueType/OpenType */
+  /*                         font.                                         */
+  /*                                                                       */
+  /*    postscript_names  :: A table used to store the Postscript names of */
+  /*                         the glyphs for this font.  See the file       */
+  /*                         `ttconfig.h' for comments on the              */
+  /*                         TT_CONFIG_OPTION_POSTSCRIPT_NAMES option.     */
+  /*                                                                       */
+  /*    num_locations     :: The number of glyph locations in this         */
+  /*                         TrueType file.  This should be identical to   */
+  /*                         the number of glyphs.  Ignored for Type 2     */
+  /*                         fonts.                                        */
+  /*                                                                       */
+  /*    glyph_locations   :: An array of longs.  These are offsets to      */
+  /*                         glyph data within the `glyf' table.  Ignored  */
+  /*                         for Type 2 font faces.                        */
+  /*                                                                       */
+  /*    font_program_size :: Size in bytecodes of the face's font program. */
+  /*                         0 if none defined.  Ignored for Type 2 fonts. */
+  /*                                                                       */
+  /*    font_program      :: The face's font program (bytecode stream)     */
+  /*                         executed at load time, also used during glyph */
+  /*                         rendering.  Comes from the `fpgm' table.      */
+  /*                         Ignored for Type 2 font fonts.                */
+  /*                                                                       */
+  /*    cvt_program_size  :: Size in bytecodes of the face's cvt program.  */
+  /*                         Ignored for Type 2 fonts.                     */
+  /*                                                                       */
+  /*    cvt_program       :: The face's cvt program (bytecode stream)      */
+  /*                         executed each time an instance/size is        */
+  /*                         changed/reset.  Comes from the `prep' table.  */
+  /*                         Ignored for Type 2 fonts.                     */
+  /*                                                                       */
+  /*    cvt_size          :: Size of the control value table (in entries). */
+  /*                         Ignored for Type 2 fonts.                     */
+  /*                                                                       */
+  /*    cvt               :: The face's original control value table.      */
+  /*                         Coordinates are expressed in unscaled font    */
+  /*                         units.  Comes from the `cvt ` table.  Ignored */
+  /*                         for Type 2 fonts.                             */
+  /*                                                                       */
+  /*    num_kern_pairs    :: The number of kerning pairs present in the    */
+  /*                         font file.  The engine only loads the first   */
+  /*                         horizontal format 0 kern table it finds in    */
+  /*                         the font file.  You should use the `ttxkern'  */
+  /*                         structures if you want to access other        */
+  /*                         kerning tables.  Ignored for Type 2 fonts.    */
+  /*                                                                       */
+  /*    kern_table_index  :: The index of the kerning table in the font    */
+  /*                         kerning directory.  Only used by the ttxkern  */
+  /*                         extension to avoid data duplication.  Ignored */
+  /*                         for Type 2 fonts.                             */
+  /*                                                                       */
+  /*    kern_pairs        :: Array of kerning pairs, if any.  Ignored for  */
+  /*                         Type 2 fonts.                                 */
+  /*                                                                       */
+  /*    interpreter       :: Pointer to the TrueType bytecode interpreter  */
+  /*                         this field is also used to hook the debugger  */
+  /*                         in `ttdebug'                                  */
+  /*                                                                       */
+  typedef struct  TT_FaceRec_
+  {
+    FT_FaceRec         root;
+
+    TTC_Header         ttc_header;
+
+    TT_UShort          num_tables;
+    TT_Table*          dir_tables;
+
+    TT_Header          header;       /* TrueType header table          */
+    TT_HoriHeader      horizontal;   /* TrueType horizontal header     */
+
+    TT_MaxProfile      max_profile;
+    TT_ULong           max_components;
+
+    TT_Bool            vertical_info;
+    TT_VertHeader      vertical;     /* TT Vertical header, if present */
+
+    TT_Int             num_names;    /* number of name records  */
+    TT_NameTable       name_table;   /* name table              */
+
+    TT_OS2             os2;          /* TrueType OS/2 table            */
+    TT_Postscript      postscript;   /* TrueType Postscript table      */
+
+    TT_Int             num_charmaps;
+    TT_CharMap         charmaps;     /* array of TT_CharMapRec */
+
+    /* a pointer to the function used to seek a stream to the start of */
+    /* a given TrueType table. This should default to the function     */
+    /* TT_Goto_Table defined in `ttload.h', but some font drivers      */
+    /* might need something different, e.g. Type 42 fonts              */
+    TT_Goto_Table_Func       goto_table;
+    
+    /* a typeless pointer to the SFNT_Interface table used to load     */
+    /* the basic TrueType tables in the face object                    */
+    void*              sfnt;
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* Optional TrueType/OpenType tables                                   */
+    /*                                                                     */
+    /***********************************************************************/
+
+    /* horizontal device metrics */
+    TT_Hdmx            hdmx;
+
+    /* grid-fitting and scaling table */
+    TT_Gasp            gasp;                 /* the `gasp' table */
+
+    /* embedded bitmaps support */
+    TT_Int             num_sbit_strikes;
+    TT_SBit_Strike*    sbit_strikes;
+
+    TT_Int             num_sbit_scales;
+    TT_SBit_Scale*     sbit_scales;
+
+    /* postscript names table */
+    TT_Post_Names      postscript_names;
+
+    /***********************************************************************/
+    /*                                                                     */
+    /* TrueType-specific fields (ignored by the OTF-Type2 driver)          */
+    /*                                                                     */
+    /***********************************************************************/
+
+    /* the glyph locations */
+    TT_UShort          num_locations;
+    TT_Long*           glyph_locations;
+
+    /* the font program, if any */
+    TT_ULong           font_program_size;
+    TT_Byte*           font_program;
+
+    /* the cvt program, if any */
+    TT_ULong           cvt_program_size;
+    TT_Byte*           cvt_program;
+
+    /* the original, unscaled, control value table */
+    TT_ULong           cvt_size;
+    TT_Short*          cvt;
+
+    /* the format 0 kerning table, if any */
+    TT_Int             num_kern_pairs;
+    TT_Int             kern_table_index;
+    TT_Kern_0_Pair*    kern_pairs;
+
+    /* a pointer to the bytecode interpreter to use. This is also */
+    /* used to hook the debugger for the `ttdebug' utility..      */
+    TT_Interpreter     interpreter;
+
+  } TT_FaceRec;
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif /* TTTYPES_H */
+
+
+/* END */
diff --git a/src/shared/type1/rules.mk b/src/shared/type1/rules.mk
new file mode 100644
index 0000000..d9c950e
--- /dev/null
+++ b/src/shared/type1/rules.mk
@@ -0,0 +1,54 @@
+#****************************************************************************
+#*                                                                          *
+#*  Shared/Type1 Makefile                                                   *
+#*                                                                          *
+#*  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.                                         *
+#*                                                                          *
+#****************************************************************************
+
+
+#****************************************************************************
+#*                                                                          *
+#*  IMPORTANT NOTE: This Makefile is intended for GNU Make!                 *
+#*                  If you provide Makefiles for other make utilities,      *
+#*                  please place them in `freetype/lib/arch/<system>'.      *
+#*                                                                          *
+#*                                                                          *
+#*  This file is to be included by the Makefiles of each driver that uses   *
+#*  the shared source code in `freetype2/lib/drivers/type1'.  This code     *
+#*  contains type definitions as well as interface which are common to all  *
+#*  supported Postscript font formats (i.e. Type1 and Type2).               *
+#*                                                                          *
+#*                                                                          *
+#*  The purpose of this Makefile is to define make variables that are used  *
+#*  directly by the parent Makefile.                                        *
+#*                                                                          *
+#****************************************************************************
+
+
+# T1SHARED_DIR is the directory to the `shared/type1' sources
+#
+T1SHARED_DIR  := $(SRC)/shared/type1
+T1SHARED_DIR_ := $(T1SHARED_DIR)$(SEP)
+
+
+# T1SHARED_H is the list of all header files on which the client drivers
+# depend
+#
+T1SHARED_H := $(T1SHARED_DIR_)t1types.h  \
+              $(T1SHARED_DIR_)t1encode.h
+
+# T1SHARED_SRC is the list of all shared source files that are included
+# by any client driver
+#
+T1SHARED_SRC := $(T1SHARED_DIR_)t1encode.c
+
+
+# END
diff --git a/src/shared/type1/t1encode.c b/src/shared/type1/t1encode.c
new file mode 100644
index 0000000..a1bf73d
--- /dev/null
+++ b/src/shared/type1/t1encode.c
@@ -0,0 +1,330 @@
+/***************************************************************************/
+/*                                                                         */
+/*  t1encode.c                                                             */
+/*                                                                         */
+/*    Type 1 standard encoding tables definitions (body).                  */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/*                                                                         */
+/*  This file is included by both the Type1 and Type2 driver.              */
+/*  It should never be compiled directly.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_standard_strings:                                                 */
+  /*                                                                       */
+  /*     This array contains the Adobe Standard Glyph Names ordered by     */
+  /*     SID.  It was taken from the CFF specification.                    */
+  /*                                                                       */
+  LOCAL_FUNC
+  const T1_String*  t1_standard_strings[] =
+  {
+  /*   0 */
+    ".notdef", "space", "exclam", "quotedbl", "numbersign",
+    "dollar", "percent", "ampersand", "quoteright", "parenleft",
+  /*  10 */
+    "parenright", "asterisk", "plus", "comma", "hyphen",
+    "period", "slash", "zero", "one", "two",
+  /*  20 */
+    "three", "four", "five", "six", "seven",
+    "height", "nine", "colon", "semicolon", "less",
+  /*  30 */
+    "equal", "greater", "question", "at", "A",
+    "B", "C", "D", "E", "F",
+  /*  40 */
+    "G", "H", "I", "J", "K",
+    "L", "M", "N", "O", "P",
+  /*  50 */
+    "Q", "R", "S", "T", "U",
+    "V", "W", "X", "Y", "Z",
+  /*  60 */
+    "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
+    "quoteleft", "a", "b", "c", "d",
+  /*  70 */
+    "e", "f", "g", "h", "i",
+    "j", "k", "l", "m", "n",
+  /*  80 */
+    "o", "p", "q", "r", "s",
+    "t", "u", "v", "w", "x",
+  /*  90 */
+    "y", "z", "braceleft", "bar", "braceright",
+    "asciitilde", "exclamdown", "cent", "sterling", "fraction",
+  /* 100 */
+    "yen", "florin", "section", "currency", "quotesingle",
+    "quotedblleft", "quillemotleft", "guilsinglleft", "guilsinglright", "fi",
+  /* 110 */
+    "fl", "endash", "dagger", "daggerdbl", "periodcenter",
+    "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright",
+  /* 120 */
+    "quillemotright", "ellipsis", "perthousand", "questiondown", "grave",
+    "acute", "circumflex", "tilde", "macron", "breve",
+  /* 130 */
+    "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut",
+    "ogonek", "caron", "emdash", "AE", "ordfeminine",
+  /* 140 */
+    "Lslash", "Oslash", "OE", "ordmasculine", "ae",
+   "dotlessi", "Islash", "oslash", "oe", "germandbls",
+  /* 150 */
+    "onesuperior", "logicalnot", "mu", "trademark", "Eth",
+    "onehalf", "plusminus", "Thorn", "onequarter", "divide",
+  /* 160 */
+    "brokenbar", "degree", "thorn", "threequarters", "twosuperior",
+    "regitered", "minus", "eth", "multiply", "threesuperior",
+  /* 170 */
+    "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
+    "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex",
+  /* 180 */
+    "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
+    "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis",
+  /* 190 */
+    "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex",
+    "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
+  /* 200 */
+    "aacute", "acircumflex", "adieresis", "agrave", "aring",
+    "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis",
+  /* 210 */
+    "egrave", "iacute", "icircumflex", "idieresis", "igrave",
+    "ntilde", "oacute", "ocircumflex", "odieresis", "ograve",
+  /* 220 */
+    "otilde", "scaron", "uacute", "ucircumflex", "udieresis",
+    "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
+  /* 230 */
+    "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
+      "Acutesmall",
+    "parenleftsuperior", "parenrightsuperior", "twodotenleader",
+      "onedotenleader", "zerooldstyle",
+  /* 240 */
+    "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle",
+      "fiveoldstyle",
+    "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle",
+      "commasuperior",
+  /* 250 */
+    "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
+      "bsuperior",
+    "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
+  /* 260 */
+    "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
+    "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
+  /* 270 */
+    "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
+      "Asmall",
+    "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
+  /* 280 */
+    "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall",
+    "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
+  /* 290 */
+    "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
+    "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall",
+  /* 300 */
+    "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall",
+    "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall",
+      "Dieresissmall",
+  /* 310 */
+    "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
+    "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
+      "questiondownsmall",
+  /* 320 */
+    "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird",
+    "twothirds", "zerosuperior", "foursuperior", "fivesuperior",
+      "sixsuperior",
+  /* 330 */
+    "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
+      "oneinferior",
+    "twoinferior", "threeinferior", "fourinferior", "fiveinferior",
+      "sixinferior",
+  /* 340 */
+    "seveninferior", "eightinferior", "nineinferior", "centinferior",
+      "dollarinferior",
+    "periodinferior", "commainferior", "Agravesmall", "Aacutesmall",
+      "Acircumflexsmall",
+  /* 350 */
+    "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
+    "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
+      "Igravesmall",
+  /* 360 */
+    "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall",
+      "Ntildesmall",
+    "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
+      "Odieresissmall",
+  /* 370 */
+    "OEsmall", "Oslashsmall", "Ugravesmall", "Uacautesmall",
+      "Ucircumflexsmall",
+    "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall",
+      "001.000",
+  /* 380 */
+    "001.001", "001.002", "001.003", "Black", "Bold",
+    "Book", "Light", "Medium", "Regular", "Roman",
+  /* 390 */
+    "Semibold"
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_standard_encoding:                                                */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe StandardEncoding.  The    */
+  /*     table values are the SID of the standard glyphs; the table index  */
+  /*     is the character code for the encoding.                           */
+  /*                                                                       */
+  /*     Example:                                                          */
+  /*                                                                       */
+  /*       t1_standard_encoding[33] == 2                                   */
+  /*                                                                       */
+  /*     which means that the glyph name for character code 32 is          */
+  /*                                                                       */
+  /*       t1_standard_strings[2] == "exclam"                              */
+  /*                                                                       */
+  /*     (this correspond to the exclamation mark `!').                    */
+  /*                                                                       */
+  LOCAL_FUNC
+  T1_Short  t1_standard_encoding[256] =
+  {
+  /*   0 */ 
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   1,   2,   3,   4,   5,   6,   7,   8,
+      9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
+  /*  50 */
+     19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
+     29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
+     39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
+     49,  50,  51,  52,  53,  54,  55,  56,  57,  58,
+     59,  60,  61,  62,  63,  64,  65,  66,  67,  68,
+  /* 100 */
+     69,  70,  71,  72,  73,  74,  75,  76,  77,  78,
+     79,  80,  81,  82,  83,  84,  85,  86,  87,  88,
+     89,  90,  91,  92,  93,  94,  95,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  /* 150 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,  96,  97,  98,  99, 100, 101, 102, 103, 104,
+    105, 106, 107, 108, 109, 110,   0, 111, 112, 113,
+    114,   0, 115, 116, 117, 118, 119, 120, 121, 122,
+      0, 123,   0, 124, 125, 126, 127, 128, 129, 130,
+  /* 200 */
+    131,   0, 132, 133,   0, 134, 135, 136, 137,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0, 138,   0, 139,   0,   0,
+      0,   0, 140, 141, 142, 143,   0,   0,   0,   0,
+      0, 144,   0,   0,   0, 145,   0,   0, 146, 147,
+  /* 250 */
+    148, 149,   0,   0,   0,   0
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_expert_encoding:                                                  */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe ExpertEncoding.  The      */
+  /*     table values are the SID of the standard glyphs; the table index  */
+  /*     is the character code for the encoding.                           */
+  /*                                                                       */
+  /*     Example:                                                          */
+  /*                                                                       */
+  /*       t1_expert_encoding[33] == 229                                   */
+  /*                                                                       */
+  /*     which means that the glyph name for character code 32 is          */
+  /*                                                                       */
+  /*       t1_standard_strings[229] == "exclamsmall"                       */
+  /*                                                                       */
+  LOCAL_FUNC
+  T1_Short  t1_expert_encoding[256] =
+  {
+  /*   0 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   1, 229, 230,   0, 231, 232, 233, 234,
+    235, 236, 237, 238,  13,  14,  15,  99, 239, 240,
+  /*  50 */
+    241, 242, 243, 244, 245, 246, 247, 248,  27,  28,
+    249, 250, 251, 252,   0, 253, 254, 255, 256, 257,
+      0,   0,   0, 258,   0,   0, 259, 260, 261, 262,
+      0,   0, 263, 264, 265,   0, 266, 109, 110, 267,
+    268, 269,   0, 270, 271, 272, 273, 274, 275, 276,
+  /* 100 */
+    277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
+    287, 288, 289, 290, 291, 292, 293, 294, 295, 296,
+    297, 298, 299, 300, 301, 302, 303,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  /* 150 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0, 304, 305, 306,   0,   0, 307, 308, 309, 310,
+    311,   0, 312,   0,   0, 312,   0,   0, 314, 315,
+      0,   0, 316, 317, 318,   0,   0,   0, 158, 155,
+    163, 319, 320, 321, 322, 323, 324, 325,   0,   0,
+  /* 200 */
+    326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+    333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+    343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
+    353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
+    363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
+  /* 250 */
+    373, 374, 375, 376, 377, 378
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_expert_subset_encoding:                                           */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe ExpertEncoding subset     */
+  /*     defined in the CFF specification.  It will probably evolve into   */
+  /*     another form sooner or later, as we deal with charsets            */
+  /*     differently than with encodings.                                  */
+  /*                                                                       */
+  LOCAL_FUNC
+  FT_Short  t1_expert_subset_encoding[256] =
+  {
+  /*   0 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   1,   0,   0,   0, 231, 232,   0,   0,
+    235, 236, 237, 238,  13,  14,  15,  99, 239, 240,
+  /*  50 */
+    241, 242, 243, 244, 245, 246, 247, 248,  27,  28,
+    249, 250, 251, 252,   0, 253, 254, 255, 256, 257,
+      0,   0,   0, 258,   0,   0, 259, 260, 261, 262,
+      0,   0, 263, 264, 265,   0, 266, 109, 110, 267,
+    268, 269,   0, 270,   0, 272,   0,   0,   0,   0,
+  /* 100 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0, 300, 301, 302, 303,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  /* 150 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0, 304, 305,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0, 314, 315,
+      0,   0,   0,   0,   0,   0,   0,   0, 158, 155,
+    163,   0, 320, 321, 322, 323, 324, 325,   0,   0,
+  /* 200 */
+    326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+    333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+    343, 344, 345, 346,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  /* 250 */
+      0,   0,   0,   0,   0,   0
+  };
+
+
+/* END */
diff --git a/src/shared/type1/t1encode.h b/src/shared/type1/t1encode.h
new file mode 100644
index 0000000..4a55acd
--- /dev/null
+++ b/src/shared/type1/t1encode.h
@@ -0,0 +1,98 @@
+/***************************************************************************/
+/*                                                                         */
+/*  t1encode.h                                                             */
+/*                                                                         */
+/*    Type 1 standard encoding tables definitions (specification).         */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/*                                                                         */
+/*  This file is included by both the Type1 and Type2 driver.              */
+/*  It should never be compiled directly.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef T1ENCODE_H
+#define T1ENCODE_H
+
+#include <t1types.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_standard_strings:                                                 */
+  /*                                                                       */
+  /*     This array contains the Adobe Standard Glyph Names ordered by     */
+  /*     SID.  It was taken from the CFF specification.                    */
+  /*                                                                       */
+  LOCAL_DEF
+  const T1_String*  t1_standard_strings[];
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_standard_encoding:                                                */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe StandardEncoding.  The    */
+  /*     table values are the SID of the standard glyphs; the table index  */
+  /*     is the character code for the encoding.                           */
+  /*                                                                       */
+  /*     Example:                                                          */
+  /*                                                                       */
+  /*       t1_standard_encoding[33] == 2                                   */
+  /*                                                                       */
+  /*     which means that the glyph name for character code 32 is          */
+  /*                                                                       */
+  /*       t1_standard_strings[2] == "exclam"                              */
+  /*                                                                       */
+  /*     (this correspond to the exclamation mark `!').                    */
+  /*                                                                       */
+  LOCAL_DEF
+  T1_Short  t1_standard_encoding[256];
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_expert_encoding:                                                  */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe ExpertEncoding.  The      */
+  /*     table values are the SID of the standard glyphs; the table index  */
+  /*     is the character code for the encoding.                           */
+  /*                                                                       */
+  /*     Example:                                                          */
+  /*                                                                       */
+  /*       t1_expert_encoding[33] == 229                                   */
+  /*                                                                       */
+  /*     which means that the glyph name for character code 32 is          */
+  /*                                                                       */
+  /*       t1_standard_strings[229] == "exclamsmall"                       */
+  /*                                                                       */
+  LOCAL_DEF
+  T1_Short  t1_expert_encoding[256];
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_expert_subset_encoding:                                           */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe ExpertEncoding subset     */
+  /*     defined in the CFF specification.  It will probably evolve into   */
+  /*     another form sooner or later, as we deal with charsets            */
+  /*     differently than with encodings.                                  */
+  /*                                                                       */
+  LOCAL_DEF
+  T1_Short  t1_expert_subset_encoding[256];
+
+
+#endif /* T1ENCODE_H */
+
+
+/* END */
diff --git a/src/shared/type1/t1types.h b/src/shared/type1/t1types.h
new file mode 100644
index 0000000..853b743
--- /dev/null
+++ b/src/shared/type1/t1types.h
@@ -0,0 +1,485 @@
+/*******************************************************************
+ *
+ *  t1types.h                                                   1.0
+ *
+ *    Basic Type1/Type2 type definitions and interface.
+ *
+ *  This code is shared by the Type1 and Type2 drivers
+ *
+ *
+ *  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 T1TYPES_H
+#define T1TYPES_H
+
+#include <freetype.h>
+
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/***                                                                   ***/
+/***                                                                   ***/
+/***                DEFINITIONS OF BASIC DATA TYPES                    ***/
+/***                                                                   ***/
+/***                                                                   ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+
+/* The REDEFINE macro is used to convert a FreeType generic type into    */
+/* a TrueType-specific one. It simply replaces the "FT_" prefix by "T1_" */
+/* in order to define compatible T1_Long, T1_Error, T1_Outline, etc..    */
+/*                                                                       */
+#undef  REDEFINE
+#define REDEFINE( type )   typedef FT_##type  T1_##type
+
+
+  /* <Type> T1_Bool                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    A simple typedef of unsigned char, used for simple booleans.      */
+  /*                                                                      */
+  REDEFINE( Bool );
+
+
+  /* <Type> T1_FWord                                                      */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a signed 16-bit integer used to store a distance in original      */
+  /*    font units.                                                       */
+  /*                                                                      */
+  REDEFINE( FWord );
+
+
+  /* <Type> T1_UFWord                                                     */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    an unsigned 16-bit integer used to store a distance in original   */
+  /*    font units.                                                       */
+  /*                                                                      */
+  REDEFINE( UFWord );
+
+
+  /* <Type> T1_Char                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a simple typedef for the _signed_ char type.                      */
+  /*                                                                      */
+  REDEFINE( Char );
+
+
+  /* <Type> T1_Byte                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a simple typedef for the _unsigned_ char type.                    */
+  /*                                                                      */
+  REDEFINE( Byte );
+
+
+  /* <Type> T1_String                                                     */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a simple typedef for the char type, used for strings usually.     */
+  /*                                                                      */
+  REDEFINE( String );
+
+
+  /* <Type> T1_Short                                                      */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for signed short                                        */
+  /*                                                                      */
+  REDEFINE( Short );
+
+
+  /* <Type> T1_UShort                                                     */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for unsigned short                                      */
+  /*                                                                      */
+  REDEFINE( UShort );
+
+
+  /* <Type> FT_Int                                                        */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for the int type                                        */
+  /*                                                                      */
+  REDEFINE( Int );
+
+
+  /* <Type> FT_UInt                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for the unsigned int type                               */
+  /*                                                                      */
+  REDEFINE( UInt );
+
+
+  /* <Type> T1_Long                                                       */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for signed long                                         */
+  /*                                                                      */
+  REDEFINE( Long );
+
+
+  /* <Type> T1_ULong                                                      */
+  /*                                                                      */
+  /* <Description>                                                        */
+  /*    a typedef for unsigned long                                       */
+  /*                                                                      */
+  REDEFINE( ULong );
+
+
+  /* <Type> T1_F2Dot14                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    a signed 2.14 fixed float used for unit vectors                    */
+  /*                                                                       */
+  REDEFINE( F2Dot14 );
+
+
+  /* <Type> T1_F26Dot6                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    a signed 26.6 fixed float used for vectorial pixel coordinates     */
+  /*                                                                       */
+  REDEFINE( F26Dot6 );
+
+
+  /* <Type> T1_Fixed                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*     This type is used to store 16.16 fixed float values, like         */
+  /*     scales or matrix coefficients..                                   */
+  /*                                                                       */
+  REDEFINE( Fixed );
+
+
+  /* <Type> T1_Pos                                                      */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     The type T1_Pos is a 32-bits integer used to store vectorial   */
+  /*     coordinates. Depending on the context, these can represent     */
+  /*     distances in integer font units, or 26.6 fixed float pixel     */
+  /*     coordinates..                                                  */
+  /*                                                                    */
+  REDEFINE( Pos );
+
+
+  /* <Struct> T1_Vector                                                 */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     A simple structure used to store a 2d vector, coordinates      */
+  /*     are of the T1_Pos type.                                        */
+  /*                                                                    */
+  /* <Fields>                                                           */
+  /*    x  ::  horizontal coordinate                                    */
+  /*    y  ::  vertical coordinate                                      */
+  /*                                                                    */
+  REDEFINE( Vector );
+
+  /* <Struct> T1_UnitVector                                             */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     A simple structure used to store a 2d vector unit vector.      */
+  /*     uses T1_F2Dot14 types.                                         */
+  /*                                                                    */
+  /* <Fields>                                                           */
+  /*    x  ::  horizontal coordinate                                    */
+  /*    y  ::  vertical coordinate                                      */
+  /*                                                                    */
+  REDEFINE( UnitVector );
+
+
+  /* <Struct> T1_Matrix                                                 */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     A simple structure used to store a 2x2 matrix. Coefficients    */
+  /*     are in 16.16 fixed float format. The computation performed     */
+  /*     is :                                                           */
+  /*             {                                                      */
+  /*               x' = x*xx + y*xy                                     */
+  /*               y' = x*yx + y*yy                                     */
+  /*             }                                                      */
+  /*                                                                    */
+  /* <Fields>                                                           */
+  /*     xx  :: matrix coefficient                                      */
+  /*     xy  :: matrix coefficient                                      */
+  /*     yx  :: matrix coefficient                                      */
+  /*     yy  :: matrix coefficient                                      */
+  /*                                                                    */
+  REDEFINE( Matrix );
+
+
+  /* <Struct> T1_BBox                                                   */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*     A structure used to hold an outline's bounding box, i.e.       */
+  /*     the coordinates of its extrema in the horizontal and vertical  */
+  /*     directions.                                                    */
+  /*                                                                    */
+  /* <Fields>                                                           */
+  /*     xMin   ::  the horizontal minimum  (left-most)                 */
+  /*     yMin   ::  the vertical minimum    (bottom-most)               */
+  /*     xMax   ::  the horizontal maximum  (right-most)                */
+  /*     yMax   ::  the vertical maximum    (top-most)                  */
+  /*                                                                    */
+  REDEFINE( BBox );
+
+
+  /* <Type> T1_Error                                                    */
+  /*                                                                    */
+  /* <Description>                                                      */
+  /*    The FreeType error code type. A value of 0 is always            */
+  /*    interpreted as a succesful operation.                           */
+  /*                                                                    */
+  REDEFINE( Error );
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/***                                                                   ***/
+/***                                                                   ***/
+/***                REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS            ***/
+/***                                                                   ***/
+/***                                                                   ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Struct> T1_FontInfo                                                */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    The FontInfo dictionary structure.                               */
+  /*                                                                     */
+  /* <Fields>                                                            */
+  /*    version             ::                                           */
+  /*    notice              ::                                           */
+  /*    full_name           ::                                           */
+  /*    family_name         ::                                           */
+  /*    weight              ::                                           */
+  /*    italic_angle        ::                                           */
+  /*    is_fixed_pitch      ::                                           */
+  /*    underline_position  ::                                           */
+  /*    underline_thickness ::                                           */
+  /*                                                                     */
+  typedef struct T1_FontInfo_
+  {
+    T1_String*     version;
+    T1_String*     notice;
+    T1_String*     full_name;
+    T1_String*     family_name;
+    T1_String*     weight;
+    T1_Long        italic_angle;
+    T1_Bool        is_fixed_pitch;
+    T1_Short       underline_position;
+    T1_UShort      underline_thickness;
+
+  } T1_FontInfo;
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Struct> T1_Private                                                 */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    The Private dictionary structure.                                */
+  /*                                                                     */
+  /* <Fields>                                                            */
+  /*    unique_id :: the font's unique id                                */
+  /*    lenIV     :: length of decrypt padding                           */
+  /*                                                                     */
+  /*    num_blues              :: number of blue values                  */
+  /*    num_other_blues        :: number of other blue values            */
+  /*    num_family_blues       :: number of family blue values           */
+  /*    num_family_other_blues :: number of family other blue values     */
+  /*                                                                     */
+  /*    blue_values        :: array of blue values                       */
+  /*    other_blues        :: array of other blue values                 */
+  /*    family_blues       :: array of family blue values                */
+  /*    family_other_blues :: array of family other blue values          */
+  /*                                                                     */
+  /*    blue_scale         ::                                            */
+  /*    blue_shift         ::                                            */
+  /*    blue_scale         ::                                            */
+  /*                                                                     */
+  /*    standard_width     ::                                            */
+  /*    standard_height    ::                                            */
+  /*                                                                     */
+  /*    num_snap_widths    ::                                            */
+  /*    num_snap_heights   ::                                            */
+  /*    force_bold         ::                                            */
+  /*    round_stem_up      ::                                            */
+  /*                                                                     */
+  /*    stem_snap_widths   ::                                            */
+  /*    stem_snap_heights  ::                                            */
+  /*                                                                     */
+  /*    language_group     ::                                            */
+  /*    password           ::                                            */
+  /*                                                                     */
+  /*    min_feature        ::                                            */
+  /*                                                                     */
+  /*                                                                     */
+  typedef struct T1_Private_
+  {
+    T1_Int       unique_id;
+    T1_Int       lenIV;
+
+    T1_Byte      num_blues;
+    T1_Byte      num_other_blues;
+    T1_Byte      num_family_blues;
+    T1_Byte      num_family_other_blues;
+
+    T1_Short     blue_values[14];
+    T1_Short     other_blues[10];
+
+    T1_Short     family_blues      [14];
+    T1_Short     family_other_blues[10];
+
+    T1_Fixed     blue_scale;
+    T1_Int       blue_shift;
+    T1_Int       blue_fuzz;
+
+    T1_UShort    standard_width;
+    T1_UShort    standard_height;
+
+    T1_Byte      num_snap_widths;
+    T1_Byte      num_snap_heights;
+    T1_Bool      force_bold;
+    T1_Bool      round_stem_up;
+
+    T1_Short     stem_snap_widths [13];  /* reserve one place for the std */
+    T1_Short     stem_snap_heights[13];  /* reserve one place for the std */
+
+    T1_Long      language_group;
+    T1_Long      password;
+
+    T1_Short     min_feature[2];
+
+  } T1_Private;
+
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* <Struct> T1_Private                                                 */
+  /*                                                                     */
+  /* <Description>                                                       */
+  /*    The Private dictionary structure.                                */
+  /*                                                                     */
+  /* <Fields>                                                            */
+  /*    num_chars   :: number of char codes in encoding. Usually 256     */
+  /*    code_first  :: lower char code in encoding                       */
+  /*    code_last   :: higher char code in encoding                      */
+  /*                                                                     */
+  /*    char_code   :: array of character codes                          */
+  /*    char_index  :: array of correpsonding glyph indices              */
+  /*    char_name   :: array of correpsonding glyph names                */
+  /*                                                                     */
+  typedef struct T1_Encoding_
+  {
+    T1_Int      num_chars;
+    T1_Int      code_first;
+    T1_Int      code_last;
+
+    T1_Short*   char_index;
+    T1_String** char_name;
+
+  } T1_Encoding;
+
+
+
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/***                                                                   ***/
+/***                                                                   ***/
+/***                  ORIGINAL TT_FACE CLASS DEFINITION                ***/
+/***                                                                   ***/
+/***                                                                   ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+/***                                                                   ***/
+/***                                                                   ***/
+/***    This structure/class is defined here because it is common      ***/
+/***    to the following formats : TTF, OpenType-TT and OpenType-CFF   ***/
+/***                                                                   ***/
+/***    Note however that the classes TT_Size, TT_GlyphSlot and        ***/
+/***    TT_CharMap are not shared between font drivers, and are        ***/
+/***    thus defined normally in "drivers/truetype/ttobjs.h"           ***/
+/***                                                                   ***/
+/***                                                                   ***/
+/*************************************************************************/
+/*************************************************************************/
+/*************************************************************************/
+
+
+  typedef struct T1_FaceRec_*   T1_Face;
+
+
+  /***************************************************/
+  /*                                                 */
+  /*  T1_Face :                                      */
+  /*                                                 */
+  /*    Type1 face record..                          */
+  /*                                                 */
+
+  typedef struct T1_FaceRec_
+  {
+    FT_FaceRec      root;
+
+    T1_FontInfo     font_info;
+    FT_String*      font_name;
+
+    T1_Encoding     encoding;
+
+    T1_Byte*        subrs_block;
+    T1_Byte*        charstrings_block;
+
+    T1_Int          num_subrs;
+    T1_Byte**       subrs;
+    T1_Int*         subrs_len;
+
+    T1_Int          num_glyphs;
+    T1_String**     glyph_names;       /* array of glyph names       */
+    T1_Byte**       charstrings;       /* array of glyph charstrings */
+    T1_Int*         charstrings_len;
+
+    T1_Byte         paint_type;
+    T1_Byte         font_type;
+    T1_Matrix       font_matrix;
+    T1_BBox         font_bbox;
+    T1_Long         unique_id;
+    T1_Long         font_id;
+
+    T1_Int          stroke_width;
+    T1_Private      private_dict;
+
+  } T1_FaceRec;
+
+
+#endif /* T1TYPES_H */
diff --git a/src/truetype/rules.mk b/src/truetype/rules.mk
new file mode 100644
index 0000000..cba7ac1
--- /dev/null
+++ b/src/truetype/rules.mk
@@ -0,0 +1,205 @@
+#****************************************************************************
+#*                                                                          *
+#*  TrueType driver Makefile                                                *
+#*                                                                          *
+#*  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.                                         *
+#*                                                                          *
+#****************************************************************************
+
+
+#****************************************************************************
+#*                                                                          *
+#*  IMPORTANT NOTE: This Makefile is intended for GNU Make!                 *
+#*                  If you provide Makefiles for other make utilities,      *
+#*                  please place them in `freetype/lib/arch/<system>'.      *
+#*                                                                          *
+#*                                                                          *
+#*  This file is to be included by the FreeType Makefile.lib, located in    *
+#*  the `freetype/lib' directory.  Here is the list of the variables that   *
+#*  must be defined to use it:                                              *
+#*                                                                          *
+#*                                                                          *
+#*     BASE_DIR:    The location of the base layer's directory.  This is    *
+#*                  usually `freetype/lib/base'.                            *
+#*                                                                          *
+#*     ARCH_DIR:    The location of the architecture-dependent directory.   *
+#*                  This is usually `freetype/lib/arch/<system>'.           *
+#*                                                                          *
+#*     DRIVERS_DIR: The location of the font driver sub-dirs, usually       *
+#*                  `freetype/lib/drivers'.                                 *
+#*                                                                          *
+#*     OBJ_DIR:     The location where the compiled object(s) file will be  *
+#*                  placed.                                                 *
+#*                                                                          *
+#*     BASE_H:      A list of pathnames to the base layer's header files on *
+#*                  which the driver depends.                               *
+#*                                                                          *
+#*     FT_CFLAGS:   A set of flags used for compilation of object files.    *
+#*                  This contains at least the include paths of the arch    *
+#*                  and base directories + optimization + warnings + ANSI   *
+#*                  compliance.                                             *
+#*                                                                          *
+#*     FT_IFLAG:    The flag used to specify an include path on the         *
+#*                  compiler command line.  For example, with GCC, this is  *
+#*                  `-I', while some other compilers use `/i=' or `-J',     *
+#*                  etc.                                                    *
+#*                                                                          *
+#*     FT_OBJ:      The suffix of an object file for the platform; can be   *
+#*                  `o', `obj', `coff', `tco', etc. depending on the        *
+#*                  platform.                                               *
+#*                                                                          *
+#*                                                                          *
+#*  It also updates the following variables defined and used in the main    *
+#*  Makefile:                                                               *
+#*                                                                          *
+#*     DRV_OBJ_S:            The list of driver object files in             *
+#*                           single-object mode.                            *
+#*                                                                          *
+#*     DRV_OBJ_M:            The list of driver object files in             *
+#*                           multiple-objects mode.                         *
+#*                                                                          *
+#*     FTINIT_DRIVER_PATHS:  The list of include paths used to compile the  *
+#*                           `ftinit' component which registers all font    *
+#*                            drivers in the FT_Init_FreeType() function.   *
+#*                                                                          *
+#*     FTINIT_DRIVER_H:      The list of header dependencies used to        *
+#*                           compile the `ftinit' component.                *
+#*                                                                          *
+#*     FTINIT_DRIVER_MACROS: The list of macros to be defined when          *
+#*                           compiling the `ftinit' component.              *
+#*                                                                          *
+#*  `Single-object compilation' means that each font driver is compiled     *
+#*  into a single object file.  This is useful to get rid of all            *
+#*  driver-specific entries.                                                *
+#*                                                                          *
+#****************************************************************************
+
+# include the rules defined for the SFNT driver, which is heavily used
+# by the TrueType one..
+#
+include $(SRC_)sfnt/rules.mk
+
+
+# TrueType driver directory
+#
+TT_DIR  := $(SRC_)truetype
+TT_DIR_ := $(TT_DIR)$(SEP)
+
+
+# location of all extensions to the driver, if any
+#
+TT_EXT_DIR  := $(TT_DIR_)extend
+TT_EXT_DIR_ := $(TT_EXT_DIR)$(SEP)
+
+# additional include flags used when compiling the driver
+#
+TT_INCLUDE := $(SFNT_INCLUDE) $(TT_DIR) $(TT_EXT_DIR)
+
+
+# compilation flags for the driver
+#
+TT_CFLAGS  := $(TT_INCLUDE:%=$I%)
+TT_COMPILE := $(FT_CC) $(TT_CFLAGS) 
+
+
+# TrueType driver sources (i.e., C files)
+#
+TT_DRV_SRC := $(TT_DIR_)ttobjs.c    \
+              $(TT_DIR_)ttpload.c   \
+              $(TT_DIR_)ttgload.c   \
+              $(TT_DIR_)ttinterp.c  \
+              $(TT_DIR_)ttdriver.c
+
+
+# TrueType driver headers
+#
+TT_DRV_H := $(SFNT_H)               \
+            $(TT_DIR_)ttconfig.h    \
+            $(TT_DRV_SRC:%.c=%.h)
+
+
+# default TrueType extensions sources
+#
+TT_EXT_SRC := $(TT_EXT_DIR_)ttxkern.c  \
+              $(TT_EXT_DIR_)ttxgasp.c  \
+              $(TT_EXT_DIR_)ttxpost.c  \
+              $(TT_EXT_DIR_)ttxcmap.c  \
+              $(TT_EXT_DIR_)ttxwidth.c
+
+
+# default TrueType extensions headers
+#
+TT_EXT_H := $(TT_EXT_SRC:.c=.h)
+
+
+# driver object(s)
+#
+#   TT_DRV_OBJ_M is used during `debug' builds
+#   TT_DRV_OBJ_S is used during `release' builds
+#
+TT_DRV_OBJ_M := $(TT_DRV_SRC:$(TT_DIR_)%.c=$(OBJ_)%.$O)
+TT_DRV_OBJ_S := $(OBJ_)truetype.$O
+
+
+# default extensions objects
+#
+TT_EXT_OBJ := $(TT_EXT_SRC:$(TT_EXT_DIR_)%.c=$(OBJ_)%.$O)
+
+
+
+# driver root source file(s)
+#
+TT_DRV_SRC_M := $(TT_DRV_SRC) $(SFNT_SRC)
+TT_DRV_SRC_S := $(TT_DIR_)truetype.c
+
+
+# driver - single object
+#
+#  the driver is recompiled if any of the header or source files is changed
+#  as well as any of the shared source files found in `shared/sfnt'
+#
+$(TT_DRV_OBJ_S): $(BASE_H) $(TT_DRV_H) $(TT_DRV_SRC) $(TT_DRV_SRC_S)
+	$(TT_COMPILE) $T$@ $(TT_DRV_SRC_S)
+
+
+
+# driver - multiple objects
+#
+#   All objects are recompiled if any of the header files is changed
+#
+$(OBJ_)tt%.$O: $(TT_DIR_)tt%.c $(BASE_H) $(TT_DRV_H)
+	$(TT_COMPILE) $T$@ $<
+
+$(OBJ_)ttx%.$O: $(TT_EXT_DIR_)ttx%.c $(BASE_H) $(SFNT_H) $(TT_EXT_H)
+	$(TT_COMPILE) $T$@ $<
+
+$(OBJ_)tt%.$O: $(SFNT_DIR_)tt%.c $(BASE_H) $(SFNT_H)
+	$(TT_COMPILE) $T$@ $<
+
+
+# treat `ttpload' as a special case, as it includes C files
+#
+$(OBJ_)ttpload.$O: $(TT_DIR_)ttpload.c $(BASE_H) $(SFNT_SRC) $(TT_DRV_H)
+	$(TT_COMPILE) $T$@ $<
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(TT_DRV_OBJ_S)
+DRV_OBJS_M += $(TT_DRV_OBJ_M)
+
+
+# update `ftinit' variables
+#
+FTINIT_DRIVER_PATHS  += $(SFNT_DIR) $(TT_DIR) $(TT_EXT_DIR)
+FTINIT_DRIVER_H      += $(SFNT_H) $(TT_DRV_H)
+FTINIT_DRIVER_MACROS += FT_SUPPORT_TRUETYPE
+
+# END
diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c
new file mode 100644
index 0000000..e5fe884
--- /dev/null
+++ b/src/truetype/truetype.c
@@ -0,0 +1,50 @@
+/***************************************************************************/
+/*                                                                         */
+/*  truetype.c                                                             */
+/*                                                                         */
+/*    FreeType TrueType driver component (body only).                      */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  This file is used to compile the FreeType TrueType font driver.  It  */
+  /*  relies on all components included in the `base' layer (see the file  */
+  /*  `ftbase.c').  The source code is located in `freetype/ttlib' and     */
+  /*  contains:                                                            */
+  /*                                                                       */
+  /*  - a driver interface                                                 */
+  /*  - an object manager                                                  */
+  /*  - a table loader                                                     */
+  /*  - a glyph loader                                                     */
+  /*  - a glyph hinter/bytecode interpreter                                */
+  /*  - a charmap processor                                                */
+  /*  - an extension manager (only used for some tools)                    */
+  /*                                                                       */
+  /*  Note that the engine extensions found in `freetype/ttlib/extend' are */
+  /*  reserved to specific tools and/or font servers; they're not part of  */
+  /*  the `core' TrueType driver, even though they are separately linkable */
+  /*  to it.                                                               */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+
+#include <ttdriver.c>    /* driver interface     */
+#include <ttpload.c>     /* tables loader        */
+#include <ttgload.c>     /* glyph loader         */
+#include <ttinterp.c>    /* bytecode interpreter */
+#include <ttobjs.c>      /* object manager       */
+
+/* END */
diff --git a/src/truetype/ttconfig.h b/src/truetype/ttconfig.h
new file mode 100644
index 0000000..cdb4f6e
--- /dev/null
+++ b/src/truetype/ttconfig.h
@@ -0,0 +1,66 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttconfig.h                                                             */
+/*                                                                         */
+/*    TrueType configuration file (specification only).                    */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This file is used to configure various aspects of the TrueType        */
+  /* driver.                                                               */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef TTCONFIG_H
+#define TTCONFIG_H
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType    */
+  /* bytecode interpreter with a huge switch statement, rather than a      */
+  /* call table.  This results in smaller and faster code for a number of  */
+  /* architectures.                                                        */
+  /*                                                                       */
+  /* Note however that on some compiler/processor combinations, undefining */
+  /* this macro will generate a faster, though larger, code.               */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_INTERPRETER_SWITCH
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support       */
+  /* embedded bitmaps in the TrueType/OpenType driver.                     */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to    */
+  /* load and enumerate the glyph Postscript names in a TrueType or        */
+  /* OpenType file.                                                        */
+  /*                                                                       */
+#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+
+
+#define  TT_USE_FIXED
+
+#endif /* TTCONFIG_H */
+
+
+/* END */
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
new file mode 100644
index 0000000..7dafb88
--- /dev/null
+++ b/src/truetype/ttdriver.c
@@ -0,0 +1,783 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttdriver.c                                                             */
+/*                                                                         */
+/*    TrueType font driver implementation (body).                          */
+/*                                                                         */
+/*  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 <ftdebug.h>
+#include <ftstream.h>
+#include <ttnameid.h>
+#include <sfnt.h>
+
+#include <ttdriver.h>
+#include <ttgload.h>
+
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_ttdriver
+
+
+  static
+  TT_Bool  string_compare( const TT_String*  s1,
+                           const TT_String*  s2 )
+  {
+    int  tries;
+
+
+    for ( tries = 128; tries > 0; tries-- )
+    {
+      if ( !*s1 )
+        return !*s2;
+
+      if ( *s1 != *s2 )
+        return 0;
+
+      s1++;
+      s2++;
+    }
+
+    return 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Get_Interface                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Some drivers can be compiled with extensions, special code used    */
+  /*    only for specific purposes (usually for system-specific uses).     */
+  /*    Each extension is registered through a simple name (e.g. `sfnt',   */
+  /*    `post_names', etc).                                                */
+  /*                                                                       */
+  /*    This function is used to return an extension's interface (i.e.,    */
+  /*    a table of pointers) when it is present in the driver.             */
+  /*                                                                       */
+  /*    If the driver wasn't compiled with the requested extension, it     */
+  /*    should return NULL.                                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver    :: A handle to the driver object.                        */
+  /*                                                                       */
+  /*    interface :: The interface's name string.                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    A typeless pointer to the extension's interface (normally a table  */
+  /*    of function pointers).  Returns NULL when the requested extension  */
+  /*    isn't available (i.e., wasn't compiled in the driver at build      */
+  /*    time).                                                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Note that unlike format-specific methods returned by               */
+  /*    getFormatInterface(), extensions can be format-independent.        */
+  /*                                                                       */
+  static
+  void*  Get_Interface( TT_Driver         driver,
+                        const TT_String*  interface )
+  {
+    /* `sfnt' returns a vtable of functions used to access the tables */
+    /* of a TrueType or OpenType font resource.                       */
+    if ( string_compare( interface, "sfnt" ) )
+      return (void*)NULL;
+
+    /* XXXX : For now, there is no extension support there */
+    UNUSED( driver );
+    UNUSED( interface );
+
+    return NULL;
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                          F A C E S                              ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+ /******************************************************************
+  *
+  * <Function>
+  *    find_encoding
+  *
+  * <Description>
+  *    return the FT_Encoding corresponding to a given 
+  *    (platform_id,encoding_id) pair, as found in TrueType charmaps
+  *
+  * <Input>
+  *   platform_id ::
+  *   encoding_id ::
+  *
+  * <Return>
+  *   the corresponding FT_Encoding tag. ft_encoding_none by default
+  *
+  *****************************************************************/
+  
+  static
+  FT_Encoding   find_encoding( int  platform_id,
+                               int  encoding_id )
+  {
+    typedef struct  TEncoding
+    {
+      int          platform_id;
+      int          encoding_id;
+      FT_Encoding  encoding;
+  
+    } TEncoding;
+
+    static
+    const TEncoding   tt_encodings[] =
+    {
+      { TT_PLATFORM_ISO,                         -1, ft_encoding_unicode },
+        
+      { TT_PLATFORM_APPLE_UNICODE,               -1, ft_encoding_unicode },
+      
+      { TT_PLATFORM_MACINTOSH,      TT_MAC_ID_ROMAN, ft_encoding_apple_roman },
+      
+      { TT_PLATFORM_MICROSOFT,  TT_MS_ID_UNICODE_CS, ft_encoding_unicode },
+      { TT_PLATFORM_MICROSOFT,  TT_MS_ID_SJIS,       ft_encoding_sjis },
+      { TT_PLATFORM_MICROSOFT,  TT_MS_ID_BIG_5,      ft_encoding_big5 }
+    };
+    
+    const TEncoding  *cur, *limit;
+   
+    cur   = tt_encodings;
+    limit = cur + sizeof(tt_encodings)/sizeof(tt_encodings[0]);
+    
+    for ( ; cur < limit; cur++ )
+    {
+      if (cur->platform_id == platform_id)
+      {
+        if (cur->encoding_id == encoding_id ||
+            cur->encoding_id == -1          )
+          return cur->encoding;
+      }
+    }
+    return ft_encoding_none;
+  }
+
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Init_Face                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to initialize a new TrueType face object.     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    resource       :: A handle to the source resource.                 */
+  /*                                                                       */
+  /*    typeface_index :: An index of the face in the font resource.  Used */
+  /*                      to access individual faces in font collections.  */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    face           :: A handle to the face object.                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The `typeface_index' parameter field will be set to -1 if the      */
+  /*    engine only wants to test the format of the resource.  This means  */
+  /*    that font drivers should simply check the font format, then return */
+  /*    immediately with an error code of 0 (meaning success).  The field  */
+  /*    `num_faces' should be set.                                         */
+  /*                                                                       */
+  /*    Done_Face() will be called subsequently, whatever the result was.  */
+  /*                                                                       */
+  static
+  TT_Error  Init_Face( FT_Stream  stream,
+                       TT_Long    typeface_index,
+                       TT_Face    face )
+  {
+    TT_Error     error;
+
+    /* initialize the TrueType face object */
+    error = TT_Init_Face( stream, typeface_index, face );
+
+    /* now set up root fields */
+    if ( !error && typeface_index >= 0 )
+    {
+      FT_Face     root = &face->root;
+      FT_Int      flags;
+      TT_CharMap  charmap;
+      TT_Int      n;
+      FT_Memory   memory;
+
+      memory = root->memory;
+
+      /*****************************************************************/
+      /*                                                               */
+      /* Compute face flags.                                           */
+      /*                                                               */
+      flags = FT_FACE_FLAG_SCALABLE  |    /* scalable outlines */
+              FT_FACE_FLAG_SFNT      |    /* SFNT file format  */
+              FT_FACE_FLAG_HORIZONTAL;    /* horizontal data   */
+
+      /* fixed width font ? */
+      if ( face->postscript.isFixedPitch )
+        flags |= FT_FACE_FLAG_FIXED_WIDTH;
+
+      /* vertical information ? */
+      if ( face->vertical_info )
+        flags |= FT_FACE_FLAG_VERTICAL;
+
+      /* kerning available ? */
+      if ( face->kern_pairs )
+        flags |= FT_FACE_FLAG_KERNING;
+
+      root->face_flags = flags;
+
+      /*****************************************************************/
+      /*                                                               */
+      /* Compute style flags.                                          */
+      /*                                                               */
+      flags = 0;
+
+      if ( face->os2.version != 0xFFFF )
+      {
+        /* We have an OS/2 table, use the `fsSelection' field */
+        if ( face->os2.fsSelection & 1 )
+          flags |= FT_STYLE_FLAG_ITALIC;
+
+        if ( face->os2.fsSelection & 32 )
+          flags |= FT_STYLE_FLAG_BOLD;
+      }
+      else
+      {
+        /* This is an old Mac font, use the header field */
+        if ( face->header.Mac_Style & 1 )
+          flags |= FT_STYLE_FLAG_BOLD;
+
+        if ( face->header.Mac_Style & 2 )
+          flags |= FT_STYLE_FLAG_ITALIC;
+      }
+
+      face->root.style_flags = flags;
+
+      /*****************************************************************/
+      /*                                                               */
+      /* Polish the charmaps.                                          */
+      /*                                                               */
+      /*   Try to set the charmap encoding according to the platform & */
+      /*   encoding ID of each charmap.                                */
+      /*                                                               */
+      charmap            = face->charmaps;
+      root->num_charmaps = face->num_charmaps;
+
+      /* allocate table of pointers */
+      if ( ALLOC_ARRAY( root->charmaps, root->num_charmaps, FT_CharMap ) )
+        return error;
+
+      for ( n = 0; n < root->num_charmaps; n++, charmap++ )
+      {
+        FT_Int  platform = charmap->cmap.platformID;
+        FT_Int  encoding = charmap->cmap.platformEncodingID;
+
+        charmap->root.face        = (FT_Face)face;
+        charmap->root.platform_id = platform;
+        charmap->root.encoding_id = encoding;
+        charmap->root.encoding    = find_encoding(platform,encoding);
+
+        /* now, set root->charmap with a unicode charmap wherever available */
+        if (!root->charmap && charmap->root.encoding == ft_encoding_unicode)
+          root->charmap = (FT_CharMap)charmap;
+        
+        root->charmaps[n] = (FT_CharMap)charmap;
+      }
+
+      root->num_fixed_sizes = 0;
+      root->available_sizes = 0;
+
+      /*****************************************************************/
+      /*                                                               */
+      /*  Set up metrics.                                              */
+      /*                                                               */
+      root->bbox.xMin    = face->header.xMin;
+      root->bbox.yMin    = face->header.yMin;
+      root->bbox.xMax    = face->header.xMax;
+      root->bbox.yMax    = face->header.yMax;
+      root->units_per_EM = face->header.Units_Per_EM;
+
+      /* The ascender/descender/height are computed from the OS/2 table   */
+      /* when found.  Otherwise, they're taken from the horizontal header */
+      if ( face->os2.version != 0xFFFF )
+      {
+        root->ascender  =  face->os2.sTypoAscender;
+        root->descender = -face->os2.sTypoDescender;
+        root->height    =  root->ascender + root->descender +
+                           face->os2.sTypoLineGap;
+      }
+      else
+      {
+        root->ascender  = face->horizontal.Ascender;
+        root->descender = face->horizontal.Descender;
+        root->height    = root->ascender + root->descender +
+                          face->horizontal.Line_Gap;
+      }
+
+      root->max_advance_width  = face->horizontal.advance_Width_Max;
+
+      root->max_advance_height = root->height;
+      if ( face->vertical_info )
+        root->max_advance_height = face->vertical.advance_Height_Max;
+
+      root->underline_position  = face->postscript.underlinePosition;
+      root->underline_thickness = face->postscript.underlineThickness;
+
+      /* root->max_points      - already set up */
+      /* root->max_contours    - already set up */
+
+    }
+    return error;
+  }
+
+
+#undef  PAIR_TAG
+#define PAIR_TAG( left, right )  ( ((TT_ULong)left << 16) | (TT_ULong)right )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <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
+  TT_Error  Get_Kerning( TT_Face     face,
+                         TT_UShort   left_glyph,
+                         TT_UShort   right_glyph,
+                         TT_Vector*  kerning )
+  {
+    TT_Kern_0_Pair*  pair;
+
+
+    if ( !face )
+      return TT_Err_Invalid_Face_Handle;
+
+    kerning->x = 0;
+    kerning->y = 0;
+
+    if ( face->kern_pairs )
+    {
+      /* there are some kerning pairs in this font file! */
+      TT_ULong  search_tag = PAIR_TAG( left_glyph, right_glyph );
+      TT_Long   left, right;
+
+
+      left  = 0;
+      right = face->num_kern_pairs - 1;
+
+      while ( left + 1 < right )
+      {
+        TT_Int    middle   = (left + right) >> 1;
+        TT_ULong  cur_pair;
+
+
+        pair     = face->kern_pairs + middle;
+        cur_pair = PAIR_TAG( pair->left, pair->right );
+
+        if ( cur_pair == search_tag )
+          goto Found;
+
+        if ( cur_pair < search_tag )
+          left = middle;
+        else
+          right = middle;
+      }
+
+      pair = face->kern_pairs + left;
+      if ( PAIR_TAG( pair->left, pair->right ) == search_tag )
+        goto Found;
+
+      pair = face->kern_pairs + right;
+      if ( PAIR_TAG( pair->left, pair->right ) == search_tag )
+        goto Found;
+    }
+
+  Exit:
+    return TT_Err_Ok;
+
+  Found:
+    kerning->x = pair->value;
+    goto Exit;
+  }
+
+
+#undef PAIR_TAG
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                           S I Z E S                             ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Set_Char_Sizes                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to reset a size's character sizes (horizontal */
+  /*    and vertical) expressed in fractional points.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    char_width  :: The character width expressed in 26.6 fractional    */
+  /*                   points.                                             */
+  /*    char_height :: The character height expressed in 26.6 fractional   */
+  /*                   points.                                             */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    size        :: A handle to the target size object.                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Set_Char_Sizes( TT_Size     size,
+                            TT_F26Dot6  char_width,
+                            TT_F26Dot6  char_height,
+                            TT_UInt     horz_resolution,
+                            TT_UInt     vert_resolution )
+  {
+    FT_Size_Metrics*  metrics = &size->root.metrics;
+    TT_Face           face    = (TT_Face)size->root.face;
+    TT_Long           dim_x, dim_y;
+
+
+    if ( char_width  < 1*64 ) char_width = 1*64;
+    if ( char_height < 1*64 ) char_height = 1*64;
+
+    /* Compute pixel sizes in 26.6 units */
+    dim_x = (char_width * horz_resolution) / 72;
+    dim_y = (char_height * vert_resolution) / 72;
+
+    /* Truncate to integer pixels if required by font - nearly all  */
+    /* TrueType fonts have this bit set, as hinting can really work */
+    /* with integer pixel sizes.                                    */
+    if ( face->header.Flags & 8 )
+    {
+      dim_x = (dim_x + 32) & -64;
+      dim_y = (dim_y + 32) & -64;
+    }
+
+    metrics->x_scale = FT_MulDiv( dim_x,
+                                  0x10000L,
+                                  face->root.units_per_EM );
+
+    metrics->y_scale = FT_MulDiv( dim_y,
+                                  0x10000L,
+                                  face->root.units_per_EM );
+
+    metrics->x_ppem    = (TT_UShort)(dim_x >> 6);
+    metrics->y_ppem    = (TT_UShort)(dim_y >> 6);
+
+    size->ttmetrics.valid = FALSE;
+
+    return TT_Reset_Size( size );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Set_Pixel_Sizes                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to reset a size's character sizes (horizontal */
+  /*    and vertical) expressed in integer pixels.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    pixel_width  :: The character width expressed in integer pixels.   */
+  /*                                                                       */
+  /*    pixel_height :: The character height expressed in integer pixels.  */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    size         :: A handle to the target size object.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code. 0 means success                               */
+  /*                                                                       */
+  static
+  TT_Error  Set_Pixel_Sizes( TT_Size  size,
+                             TT_UInt  pixel_width,
+                             TT_UInt  pixel_height )
+  {
+    FT_Size_Metrics*  metrics = &size->root.metrics;
+    TT_Face           face    = (TT_Face)size->root.face;
+
+
+    if ( pixel_width  < 1 ) pixel_width  = 1;
+    if ( pixel_height < 1 ) pixel_height = 1;
+
+    metrics->x_ppem = pixel_width;
+    metrics->y_ppem = pixel_height;
+
+    metrics->x_scale = FT_MulDiv( metrics->x_ppem << 6,
+                                  0x10000L,
+                                  face->root.units_per_EM );
+
+    metrics->y_scale = FT_MulDiv( metrics->y_ppem << 6,
+                                  0x10000L,
+                                  face->root.units_per_EM );
+
+    size->ttmetrics.valid = FALSE;
+
+    return TT_Reset_Size( size );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Load_Glyph                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A driver method used to load a glyph within a given glyph slot.    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    slot        :: A handle to the target slot object where the glyph  */
+  /*                   will be loaded.                                     */
+  /*                                                                       */
+  /*    size        :: A handle to the source face size at which the glyph */
+  /*                   must be scaled/loaded/etc.                          */
+  /*                                                                       */
+  /*    glyph_index :: The index of the glyph in the font file.            */
+  /*                                                                       */
+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
+  /*                   FTLOAD_??? constants can be used to control the     */
+  /*                   glyph loading process (e.g., whether the outline    */
+  /*                   should be scaled, whether to load bitmaps or not,   */
+  /*                   whether to hint the outline, etc).                  */
+  /* <Output>                                                              */
+  /*    result      :: A set of bit flags indicating the type of data that */
+  /*                   was loaded in the glyph slot (outline, bitmap,      */
+  /*                   pixmap, etc).                                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Load_Glyph( TT_GlyphSlot  slot,
+                        TT_Size       size,
+                        TT_UShort     glyph_index,
+                        TT_UInt       load_flags )
+  {
+    TT_Error  error;
+
+
+    if ( !slot )
+      return TT_Err_Invalid_Glyph_Handle;
+
+    /* check that we want a scaled outline or bitmap */
+    if ( !size )
+      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
+
+    if ( load_flags & FT_LOAD_NO_SCALE )
+      size = NULL;
+
+    /* reset the size object if necessary */
+    if ( size )
+    {
+      /* these two object must have the same parent */
+      if ( size->root.face != slot->face )
+        return TT_Err_Invalid_Face_Handle;
+
+      if ( !size->ttmetrics.valid )
+      {
+        if ( FT_SET_ERROR( TT_Reset_Size( size ) ) )
+          return error;
+      }
+    }
+
+    /* now load the glyph outline if necessary */
+    error = TT_Load_Glyph( size, slot, glyph_index, load_flags );
+
+    /* force drop-out mode to 2 */
+    slot->outline.dropout_mode = 2;
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****             C H A R A C T E R   M A P P I N G S                 ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <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( TT_CharMap  charmap,
+                           TT_Long     charcode )
+  {
+    TT_Error       error;
+    TT_Face        face;
+    TT_CMapTable*  cmap;
+    
+    cmap = &charmap->cmap;
+    face = (TT_Face)charmap->root.face;
+
+    /* Load table if needed */
+    if ( !cmap->loaded )
+    {
+      SFNT_Interface*  sfnt = (SFNT_Interface*)face->sfnt;
+      
+      error = sfnt->load_charmap( face, cmap, face->root.stream );
+      if (error)
+        return error;
+
+      cmap->loaded = TRUE;
+    }
+
+    if ( cmap->get_index )
+      return cmap->get_index( cmap, charcode );
+    else
+      return 0;
+  }
+
+
+  /* The FT_DriverInterface structure is defined in ftdriver.h. */
+
+  const FT_DriverInterface  tt_driver_interface =
+  {
+    sizeof ( TT_DriverRec ),
+    sizeof ( TT_FaceRec ),
+    sizeof ( TT_SizeRec ),
+    sizeof ( FT_GlyphSlotRec ),
+
+    "truetype",     /* driver name                         */
+    1,              /* driver version                      */
+    2,              /* driver requires FreeType 2 or above */
+
+    (void*)0,
+
+    (FTDriver_initDriver)        TT_Init_Driver,
+    (FTDriver_doneDriver)        TT_Done_Driver,
+    (FTDriver_getInterface)      Get_Interface,
+
+    (FTDriver_initFace)          Init_Face,
+    (FTDriver_doneFace)          TT_Done_Face,
+    (FTDriver_getKerning)        Get_Kerning,
+
+    (FTDriver_initSize)          TT_Init_Size,
+    (FTDriver_doneSize)          TT_Done_Size,
+    (FTDriver_setCharSizes)      Set_Char_Sizes,
+    (FTDriver_setPixelSizes)     Set_Pixel_Sizes,
+
+    (FTDriver_initGlyphSlot)     TT_Init_GlyphSlot,
+    (FTDriver_doneGlyphSlot)     TT_Done_GlyphSlot,
+    (FTDriver_loadGlyph)         Load_Glyph,
+
+    (FTDriver_getCharIndex)      Get_Char_Index,
+  };
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    getDriverInterface                                                 */
+  /*                                                                       */
+  /* <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>                                                              */
+  /*    The address of the TrueType's driver generic interface.  The       */
+  /*    format-specific interface can then be retrieved through the method */
+  /*    interface->get_format_interface.                                   */
+  /*                                                                       */
+#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
+
+  EXPORT_FUNC
+  FT_DriverInterface*  getDriverInterface( void )
+  {
+    return &truetype_driver_interface;
+  }
+
+#endif /* CONFIG_OPTION_DYNAMIC_DRIVERS */
+
+
+/* END */
diff --git a/src/truetype/ttdriver.h b/src/truetype/ttdriver.h
new file mode 100644
index 0000000..eba67b6
--- /dev/null
+++ b/src/truetype/ttdriver.h
@@ -0,0 +1,193 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttdriver.h                                                             */
+/*                                                                         */
+/*    High-level TrueType driver interface (specification).                */
+/*                                                                         */
+/*  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 TTDRIVER_H
+#define TTDRIVER_H
+
+#include <freetype.h>
+#include <ftdriver.h>
+#include <ttobjs.h>
+#include <tterrors.h>
+#include <ttnameid.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TTDriver_getFontData                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns either a single font table or the whole font file into     */
+  /*    caller's memory.  This function mimics the GetFontData() API       */
+  /*    function found in Windows.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the source TrueType face object.             */
+  /*                                                                       */
+  /*    tag    :: A 32-bit integer used to name the table you want to      */
+  /*              read.  Use the macro MAKE_TT_TAG (defined in freetype.h) */
+  /*              to create one.  Use the value 0 if you want to access    */
+  /*              the whole file instead.                                  */
+  /*                                                                       */
+  /*    offset :: The offset from the start of the table or file from      */
+  /*              which you want to read bytes.                            */
+  /*                                                                       */
+  /*    buffer :: The address of the target/read buffer where data will be */
+  /*              copied.                                                  */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    length :: The length in bytes of the data to read.  If it is set   */
+  /*              to 0 when this function is called, it will return        */
+  /*              immediately, setting the value of `length' to the        */
+  /*              requested table's size (or the whole font file if the    */
+  /*              tag is 0).  It is thus possible to allocate and read an  */
+  /*              arbitrary table in two successive calls.                 */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  typedef TT_Error  (*TTDriver_getFontData)( TT_Face   face,
+                                             TT_ULong  tag,
+                                             TT_ULong  offset,
+                                             void*     buffer,
+                                             TT_Long*  length );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    TTDriver_getFaceWidths                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the widths and/or heights of a given range of glyph from   */
+  /*    a face.                                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face        :: A handle to the source FreeType face object.        */
+  /*                                                                       */
+  /*    first_glyph :: The first glyph in the range.                       */
+  /*                                                                       */
+  /*    last_glyph  :: The last glyph in the range.                        */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    widths      :: The address of the table receiving the widths       */
+  /*                   expressed in font units (UShorts).  Set this        */
+  /*                   parameter to NULL if you're not interested in these */
+  /*                   values.                                             */
+  /*                                                                       */
+  /*    heights     :: The address of the table receiving the heights      */
+  /*                   expressed in font units (UShorts).  Set this        */
+  /*                   parameter to NULL if you're not interested in these */
+  /*                   values.                                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code.  0 means success.                                      */
+  /*                                                                       */
+  typedef TT_Error  (*TTDriver_getFaceWidths)( TT_Face     face,
+                                               TT_UShort   first_glyph,
+                                               TT_UShort   last_glyph,
+                                               TT_UShort*  widths,
+                                               TT_UShort*  heights );
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_DriverInterface                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType-specific interface of this driver.  Note that some of */
+  /*    the methods defined here are optional, as they're only used for    */
+  /*    for specific tasks of the driver.                                  */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    get_font_data   :: See the declaration of TTDriver_getFontData().  */
+  /*    get_face_widths :: See the declaration of                          */
+  /*                       TTDriver_getFaceWidths().                       */
+  /*                                                                       */
+  typedef struct  TT_DriverInterface_
+  {
+    TTDriver_getFontData    get_font_data;
+    TTDriver_getFaceWidths  get_face_widths;
+
+  } TT_DriverInterface;
+
+
+  EXPORT_DEF
+  const FT_DriverInterface  tt_driver_interface;
+
+
+  EXPORT_DEF
+  const TT_DriverInterface  tt_format_interface;
+
+
+
+/*************************************************************************
+ *
+ *  Here is a template of the code that should appear in each
+ *  font driver's _interface_ file (the one included by "ftinit.c").
+ *
+ *  It is used to build, at compile time, a simple linked list of
+ *  the interfaces of the drivers which have been #included in 
+ *  "ftinit.c". See the source code of the latter file for details
+ *
+ *  (Note that this is only required when you want your driver included
+ *   in the set of default drivers loaded by FT_Init_FreeType. Other
+ *   drivers can still be added manually at runtime with FT_Add_Driver.
+ *
+ * {
+ *   #ifdef FTINIT_DRIVER_CHAIN
+ *
+ *   static
+ *   const FT_DriverChain  ftinit_<FORMAT>_driver_chain =
+ *   {
+ *     FT_INIT_LAST_DRIVER_CHAIN,
+ *     &<FORMAT>_driver_interface
+ *   };
+ * 
+ *   #undef  FT_INIT_LAST_DRIVER_CHAIN
+ *   #define FT_INIT_LAST_DRIVER_CHAIN   &ftinit_<FORMAT>_driver_chain
+ *
+ *   #endif 
+ * }
+ *
+ *  replace <FORMAT> with your driver's prefix
+ *
+ *************************************************************************/
+
+
+#ifdef FTINIT_DRIVER_CHAIN
+
+  static
+  const FT_DriverChain  ftinit_tt_driver_chain =
+  {
+    FT_INIT_LAST_DRIVER_CHAIN,
+    &tt_driver_interface
+  };
+
+#undef  FT_INIT_LAST_DRIVER_CHAIN
+#define FT_INIT_LAST_DRIVER_CHAIN   &ftinit_tt_driver_chain
+
+#endif /* FTINIT_DRIVER_CHAIN */ 
+
+
+
+#endif /* TTDRIVER_H */
+
+
+/* END */
diff --git a/src/truetype/tterrors.h b/src/truetype/tterrors.h
new file mode 100644
index 0000000..90286e3
--- /dev/null
+++ b/src/truetype/tterrors.h
@@ -0,0 +1,124 @@
+/***************************************************************************/
+/*                                                                         */
+/*  tterrors.h                                                             */
+/*                                                                         */
+/*    TrueType error ID definitions (specification only).                  */
+/*                                                                         */
+/*  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 TTERRORS_H
+#define TTERRORS_H
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Error codes declaration                                               */
+  /*                                                                       */
+  /* The error codes are grouped in `classes' used to indicate the `level' */
+  /* at which the error happened.  The class is given by an error code's   */
+  /* high byte.                                                            */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /* Success is always 0. */
+
+#define  TT_Err_Ok                       FT_Err_Ok
+
+  /* High level API errors. */
+
+#define  TT_Err_Invalid_File_Format      FT_Err_Invalid_File_Format
+#define  TT_Err_Invalid_Argument         FT_Err_Invalid_Argument
+#define  TT_Err_Invalid_Driver_Handle    FT_Err_Invalid_Driver_Handle
+#define  TT_Err_Invalid_Face_Handle      FT_Err_Invalid_Face_Handle
+#define  TT_Err_Invalid_Instance_Handle  FT_Err_Invalid_Size_Handle
+#define  TT_Err_Invalid_Glyph_Handle     FT_Err_Invalid_Slot_Handle
+#define  TT_Err_Invalid_CharMap_Handle   FT_Err_Invalid_CharMap_Handle
+#define  TT_Err_Invalid_Glyph_Index      FT_Err_Invalid_Glyph_Index
+
+#define  TT_Err_Unimplemented_Feature    FT_Err_Unimplemented_Feature
+#define  TT_Err_Unavailable_Outline      FT_Err_Unavailable_Outline
+#define  TT_Err_Unavailable_Bitmap       FT_Err_Unavailable_Bitmap
+#define  TT_Err_Unavailable_Pixmap       FT_Err_Unavailable_Pixmap
+#define  TT_Err_File_Is_Not_Collection   FT_Err_File_Is_Not_Collection
+
+#define  TT_Err_Invalid_Engine           FT_Err_Invalid_Driver_Handle
+
+  /* Internal errors. */
+
+#define  TT_Err_Out_Of_Memory            FT_Err_Out_Of_Memory
+#define  TT_Err_Unlisted_Object          FT_Err_Unlisted_Object
+
+  /* General glyph outline errors. */
+
+#define  TT_Err_Too_Many_Points          FT_Err_Too_Many_Points
+#define  TT_Err_Too_Many_Contours        FT_Err_Too_Many_Contours
+#define  TT_Err_Too_Many_Ins             FT_Err_Too_Many_Hints
+#define  TT_Err_Invalid_Composite        FT_Err_Invalid_Composite
+
+  /* Bytecode interpreter error codes. */
+
+  /* These error codes are produced by the TrueType */
+  /* bytecode interpreter.  They usually indicate a */
+  /* broken font file, a broken glyph within a font */
+  /* file, or a bug in the interpreter!             */
+
+#define TT_Err_Invalid_Opcode           0x400
+#define TT_Err_Too_Few_Arguments        0x401
+#define TT_Err_Stack_Overflow           0x402
+#define TT_Err_Code_Overflow            0x403
+#define TT_Err_Bad_Argument             0x404
+#define TT_Err_Divide_By_Zero           0x405
+#define TT_Err_Storage_Overflow         0x406
+#define TT_Err_Cvt_Overflow             0x407
+#define TT_Err_Invalid_Reference        0x408
+#define TT_Err_Invalid_Distance         0x409
+#define TT_Err_Interpolate_Twilight     0x40A
+#define TT_Err_Debug_OpCode             0x40B
+#define TT_Err_ENDF_In_Exec_Stream      0x40C
+#define TT_Err_Out_Of_CodeRanges        0x40D
+#define TT_Err_Nested_DEFS              0x40E
+#define TT_Err_Invalid_CodeRange        0x40F
+#define TT_Err_Invalid_Displacement     0x410
+#define TT_Err_Execution_Too_Long       0x411
+
+  /* Other TrueType specific error codes. */
+
+#define TT_Err_Table_Missing            0x420
+#define TT_Err_Too_Many_Extensions      0x421
+#define TT_Err_Extensions_Unsupported   0x422
+#define TT_Err_Invalid_Extension_Id     0x423
+
+#define TT_Err_No_Vertical_Data         0x424
+
+#define TT_Err_Max_Profile_Missing      0x430
+#define TT_Err_Header_Table_Missing     0x431
+#define TT_Err_Horiz_Header_Missing     0x432
+#define TT_Err_Locations_Missing        0x433
+#define TT_Err_Name_Table_Missing       0x434
+#define TT_Err_CMap_Table_Missing       0x435
+#define TT_Err_Hmtx_Table_Missing       0x436
+#define TT_Err_OS2_Table_Missing        0x437
+#define TT_Err_Post_Table_Missing       0x438
+
+#define TT_Err_Invalid_Horiz_Metrics    0x440
+#define TT_Err_Invalid_CharMap_Format   0x441
+#define TT_Err_Invalid_PPem             0x442
+#define TT_Err_Invalid_Vert_Metrics     0x443
+
+#define TT_Err_Could_Not_Find_Context   0x450
+
+#endif /* FTERRID_H */
+
+
+/* END */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
new file mode 100644
index 0000000..0a78315
--- /dev/null
+++ b/src/truetype/ttgload.c
@@ -0,0 +1,1492 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttgload.c                                                              */
+/*                                                                         */
+/*    TrueType Glyph Loader (body).                                        */
+/*                                                                         */
+/*  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 <freetype.h>
+#include <ftdebug.h>
+#include <ftcalc.h>
+#include <ftstream.h>
+
+#include <sfnt.h>
+#include <ttgload.h>
+
+#include <tttags.h>
+#include <ttinterp.h>
+
+
+  /* required for the tracing mode */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_ttgload
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Composite font flags.                                                 */
+  /*                                                                       */
+#define ARGS_ARE_WORDS       0x001
+#define ARGS_ARE_XY_VALUES   0x002
+#define ROUND_XY_TO_GRID     0x004
+#define WE_HAVE_A_SCALE      0x008
+/* reserved                  0x010 */
+#define MORE_COMPONENTS      0x020
+#define WE_HAVE_AN_XY_SCALE  0x040
+#define WE_HAVE_A_2X2        0x080
+#define WE_HAVE_INSTR        0x100
+#define USE_MY_METRICS       0x200
+
+
+#undef  SCALE_X
+#define SCALE_X( distance )  FT_MulFix( distance, exec->metrics.x_scale )
+
+#undef  SCALE_Y
+#define SCALE_Y( distance )  FT_MulFix( distance, exec->metrics.y_scale )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Get_Metrics                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the horizontal or vertical metrics in font units for a     */
+  /*    given glyph.  The metrics are the left side bearing (resp. top     */
+  /*    side bearing) and advance width (resp. advance height).            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    header  :: A pointer to either the horizontal or vertical metrics  */
+  /*               structure.                                              */
+  /*                                                                       */
+  /*    index   :: The glyph index.                                        */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    bearing :: The bearing, either left side or top side.              */
+  /*                                                                       */
+  /*    advance :: The advance width resp. advance height.                 */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function will much probably move to another component in the  */
+  /*    near future, but I haven't decided which yet.                      */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  TT_Get_Metrics( TT_HoriHeader*  header,
+                        TT_UShort       index,
+                        TT_Short*       bearing,
+                        TT_UShort*      advance )
+  {
+    TT_LongMetrics*  longs_m;
+    TT_UShort        k = header->number_Of_HMetrics;
+
+
+    if ( index < k )
+    {
+      longs_m  = (TT_LongMetrics*)header->long_metrics + index;
+      *bearing = longs_m->bearing;
+      *advance = longs_m->advance;
+    }
+    else
+    {
+      *bearing = ((TT_ShortMetrics*)header->short_metrics)[index - k];
+      *advance = ((TT_LongMetrics*)header->long_metrics)[k - 1].advance;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Get_HMetrics                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the horizontal metrics in font units for a given glyph.    */
+  /*    If `check' is true, take care of monospaced fonts by returning the */
+  /*    advance width maximum.                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face  :: A handle to the target source face.                       */
+  /*                                                                       */
+  /*    index :: The glyph index.                                          */
+  /*                                                                       */
+  /*    check :: If set, handle monospaced fonts.                          */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    lsb   :: The left side bearing.                                    */
+  /*                                                                       */
+  /*    aw    :: The advance width.                                        */
+  /*                                                                       */
+  static
+  void Get_HMetrics( TT_Face     face,
+                     TT_UShort   index,
+                     TT_Bool     check,
+                     TT_Short*   lsb,
+                     TT_UShort*  aw )
+  {
+    TT_Get_Metrics( &face->horizontal, index, lsb, aw );
+
+    if ( check && face->postscript.isFixedPitch )
+      *aw = face->horizontal.advance_Width_Max;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Get_Advance_Widths                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the advance width table for a given pixel size if it is    */
+  /*    found in the font's `hdmx' table (if any).                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the target source face.                        */
+  /*                                                                       */
+  /*    ppem :: The pixel size.                                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   A pointer to the advance with table.  NULL if it doesn't exist.     */
+  /*                                                                       */
+  static
+  TT_Byte*  Get_Advance_Widths( TT_Face    face,
+                                TT_UShort  ppem )
+  {
+    TT_UShort  n;
+
+
+    for ( n = 0; n < face->hdmx.num_records; n++ )
+      if ( face->hdmx.records[n].ppem == ppem )
+        return face->hdmx.records[n].widths;
+
+    return NULL;
+  }
+
+
+#define cur_to_org( n, zone )  \
+          MEM_Copy( (zone)->org, (zone)->cur, n * sizeof ( TT_Vector ) )
+
+#define org_to_cur( n, zone )  \
+          MEM_Copy( (zone)->cur, (zone)->org, n * sizeof ( TT_Vector ) )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    translate_array                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Translates an array of coordinates.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    n       :: The number of points to translate.                      */
+  /*                                                                       */
+  /*    delta_x :: The horizontal coordinate of the shift vector.          */
+  /*                                                                       */
+  /*    delta_y :: The vertical coordinate of the shift vector.            */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    coords  :: The vector array to translate.                          */
+  /*                                                                       */
+  static
+  void  translate_array( TT_UShort   n,
+                         TT_Vector*  coords,
+                         TT_Pos      delta_x,
+                         TT_Pos      delta_y )
+  {
+    TT_UShort  k;
+
+
+    if ( delta_x )
+      for ( k = 0; k < n; k++ )
+        coords[k].x += delta_x;
+
+    if ( delta_y )
+      for ( k = 0; k < n; k++ )
+        coords[k].y += delta_y;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    mount_zone                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Mounts one glyph zone on top of another.  This is needed to        */
+  /*    assemble composite glyphs.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    source :: The source glyph zone.                                   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    target :: The target glyph zone.                                   */
+  /*                                                                       */
+  static
+  void  mount_zone( TT_GlyphZone*  source,
+                    TT_GlyphZone*  target )
+  {
+    TT_UShort  np;
+    TT_Short   nc;
+
+
+    np = source->n_points;
+    nc = source->n_contours;
+
+    target->org   = source->org + np;
+    target->cur   = source->cur + np;
+    target->touch = source->touch + np;
+
+    target->contours = source->contours + nc;
+
+    target->n_points   = 0;
+    target->n_contours = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Load_Simple_Glyph                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads a simple (i.e, non-composite) glyph.  This function is used  */
+  /*    for the `Load_Simple' state of TT_Load_Glyph().  All composite     */
+  /*    glyphs elements will be loaded with routine.                       */
+  /*                                                                       */
+  static
+  TT_Error  Load_Simple_Glyph( TT_ExecContext   exec,
+                               FT_Stream        stream,
+                               TT_ULong         byte_count,
+                               TT_Short         n_contours,
+                               TT_Short         left_contours,
+                               TT_UShort        left_points,
+                               TT_UInt          load_flags,
+                               TT_SubGlyphRec*  subg,
+                               TT_Bool          debug )
+  {
+    TT_Error       error;
+    TT_GlyphZone*  pts;
+    TT_Short       k;
+    TT_UShort      j;
+    TT_UShort      n_points, n_ins;
+    TT_Face        face;
+    TT_Byte*       flag;
+    TT_Vector*     vec;
+    TT_F26Dot6     x, y;
+
+    TT_Vector      *pp1, *pp2;
+        
+
+    face = exec->face;
+
+    /*********************************************************************/
+    /* simple check                                                      */
+    
+    if ( n_contours > left_contours )
+    {
+      FT_TRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n",
+                   subglyph.index,
+                   n_contours,
+                   left_contours ));
+      return TT_Err_Too_Many_Contours;
+    }
+
+    /* preparing the execution context */
+    mount_zone( &subg->zone, &exec->pts );
+
+
+    /*********************************************************************/
+    /* reading the contours endpoints                                    */
+    
+    if ( ACCESS_Frame( byte_count ) )
+      return error;
+
+    for ( k = 0; k < n_contours; k++ )
+      exec->pts.contours[k] = GET_UShort();
+
+    n_points = 0;
+    if ( n_contours > 0 )
+      n_points = exec->pts.contours[n_contours - 1] + 1;
+
+
+    /*********************************************************************/
+    /* reading the bytecode instructions                                 */
+    
+    n_ins = GET_UShort();
+
+    if ( n_points > left_points )
+    {
+      FT_TRACE0(( "ERROR: Too many points in glyph %ld\n", subg->index ));
+      error = TT_Err_Too_Many_Points;
+      goto Fail;
+    }
+
+    FT_TRACE4(( "Instructions size : %d\n", n_ins ));
+
+    if ( n_ins > face->max_profile.maxSizeOfInstructions )
+    {
+      FT_TRACE0(( "ERROR: Too many instructions!\n" ));
+      error = TT_Err_Too_Many_Ins;
+      goto Fail;
+    }
+
+    if (stream->cursor + n_ins > stream->limit)
+    {
+      FT_TRACE0(( "ERROR: Instruction count mismatch!\n" ));
+      error = TT_Err_Too_Many_Ins;
+      goto Fail;
+    }
+    MEM_Copy( exec->glyphIns, stream->cursor, n_ins );
+    stream->cursor += n_ins;
+
+    error = TT_Set_CodeRange( exec, tt_coderange_glyph,
+                              exec->glyphIns, n_ins );
+    if (error) goto Fail;
+
+    
+    /*********************************************************************/
+    /* reading the point flags                                           */
+    
+    j    = 0;
+    flag = exec->pts.touch;
+
+    while ( j < n_points )
+    {
+      TT_Byte  c, cnt;
+
+      flag[j] = c = GET_Byte();
+      j++;
+
+      if ( c & 8 )
+      {
+        cnt = GET_Byte();
+
+        while( cnt > 0 )
+        {
+          flag[j++] = c;
+          cnt--;
+        }
+      }
+    }
+
+    /*********************************************************************/
+    /* reading the X coordinates                                         */
+    
+    x    = 0;
+    vec  = exec->pts.org;
+
+    for ( j = 0; j < n_points; j++ )
+    {
+      if ( flag[j] & 2 )
+      {
+        if ( flag[j] & 16 )
+          x += GET_Byte();
+        else
+          x -= GET_Byte();
+      }
+      else
+      {
+        if ( (flag[j] & 16) == 0 )
+          x += GET_Short();
+      }
+
+      vec[j].x = x;
+    }
+
+
+    /*********************************************************************/
+    /* reading the YX coordinates                                         */
+    
+    y = 0;
+
+    for ( j = 0; j < n_points; j++ )
+    {
+      if ( flag[j] & 4 )
+      {
+        if ( flag[j] & 32 )
+          y += GET_Byte();
+        else
+          y -= GET_Byte();
+      }
+      else
+      {
+        if ( (flag[j] & 32) == 0 )
+          y += GET_Short();
+      }
+
+      vec[j].y = y;
+    }
+
+    FORGET_Frame();
+
+    /*********************************************************************/
+    /* Add shadow points                                                  */
+    
+    /* Now add the two shadow points at n and n + 1.    */
+    /* We need the left side bearing and advance width. */
+
+    /* pp1 = xMin - lsb */
+    pp1    = vec + n_points;
+    pp1->x = subg->bbox.xMin - subg->left_bearing;
+    pp1->y = 0;
+
+    /* pp2 = pp1 + aw */
+    pp2    = pp1 + 1;
+    pp2->x = pp1->x + subg->advance;
+    pp2->y = 0;
+        
+    /* clear the touch flags */
+    for ( j = 0; j < n_points; j++ )
+      exec->pts.touch[j] &= FT_Curve_Tag_On;
+
+    exec->pts.touch[n_points    ] = 0;
+    exec->pts.touch[n_points + 1] = 0;
+
+    /* Note that we return two more points that are not */
+    /* part of the glyph outline.                       */
+
+    n_points += 2;
+
+    /* now eventually scale and hint the glyph */
+
+    pts = &exec->pts;
+    pts->n_points   = n_points;
+    pts->n_contours = n_contours;
+
+    if (load_flags & FT_LOAD_NO_SCALE)
+    {
+      /* no scaling, just copy the orig arrays into the cur ones */
+      org_to_cur( n_points, pts );
+    }
+    else
+    {
+      /* first scale the glyph points */
+      for ( j = 0; j < n_points; j++ )
+      {
+        pts->org[j].x = SCALE_X( pts->org[j].x );
+        pts->org[j].y = SCALE_Y( pts->org[j].y );
+      }
+
+      /* if hinting, round pp1, and shift the glyph accordingly */
+      if ( subg->is_hinted )
+      {
+        x = pts->org[n_points - 2].x;
+        x = ((x + 32) & -64) - x;
+        translate_array( n_points, pts->org, x, 0 );
+
+        org_to_cur( n_points, pts );
+
+        pts->cur[n_points - 1].x = (pts->cur[n_points - 1].x + 32) & -64;
+
+        /* now consider hinting */
+        if ( n_ins > 0 )
+        {
+          exec->is_composite     = FALSE;
+          exec->pedantic_hinting = load_flags & FT_LOAD_PEDANTIC;
+
+          error = TT_Run_Context( exec, debug );
+          if ( error && exec->pedantic_hinting )
+            return error;
+        }
+      }
+      else
+        org_to_cur( n_points, pts );
+    }
+
+    /* save glyph phantom points */
+    if ( !subg->preserve_pps )
+    {
+      subg->pp1 = pts->cur[n_points - 2];
+      subg->pp2 = pts->cur[n_points - 1];
+    }
+
+    return TT_Err_Ok;
+    
+  Fail:
+    FORGET_Frame();
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Load_Composite_End                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finalizes the loading process of a composite glyph element.  This  */
+  /*    function is used for the `Load_End' state of TT_Load_Glyph().      */
+  /*                                                                       */
+  static
+  TT_Error  Load_Composite_End( TT_UShort        n_points,
+                                TT_Short         n_contours,
+                                TT_ExecContext   exec,
+                                TT_SubGlyphRec*  subg,
+                                FT_Stream        stream,
+                                TT_UInt          load_flags,
+                                TT_Bool          debug )
+  {
+    TT_Error       error;
+
+    TT_UShort      k, n_ins;
+    TT_GlyphZone*  pts;
+
+    if ( subg->is_hinted                    &&
+         subg->element_flag & WE_HAVE_INSTR )
+    {
+      if ( READ_UShort( n_ins ) )    /* read size of instructions */
+        return error;
+
+      FT_TRACE4(( "Instructions size = %d\n", n_ins ));
+
+      if ( n_ins > exec->face->max_profile.maxSizeOfInstructions )
+      {
+        FT_TRACE0(( "Too many instructions in composite glyph %ld\n",
+                  subg->index ));
+        return TT_Err_Too_Many_Ins;
+      }
+
+      if ( FILE_Read( exec->glyphIns, n_ins ) )
+        return error;
+
+      error = TT_Set_CodeRange( exec,
+                                tt_coderange_glyph,
+                                exec->glyphIns,
+                                n_ins );
+      if ( error )
+        return error;
+    }
+    else
+      n_ins = 0;
+
+
+    /* prepare the execution context */
+    n_points += 2;
+    exec->pts = subg->zone;
+    pts       = &exec->pts;
+
+    pts->n_points   = n_points;
+    pts->n_contours = n_contours;
+
+    /* add phantom points */
+    pts->cur[n_points - 2] = subg->pp1;
+    pts->cur[n_points - 1] = subg->pp2;
+
+    pts->touch[n_points - 1] = 0;
+    pts->touch[n_points - 2] = 0;
+
+    /* if hinting, round the phantom points */
+    if ( subg->is_hinted )
+    {
+      pts->cur[n_points - 2].x = ((subg->pp1.x + 32) & -64);
+      pts->cur[n_points - 1].x = ((subg->pp2.x + 32) & -64);
+    }
+
+    for ( k = 0; k < n_points; k++ )
+      pts->touch[k] &= FT_Curve_Tag_On;
+
+    cur_to_org( n_points, pts );
+
+    /* now consider hinting */
+    if ( subg->is_hinted && n_ins > 0 )
+    {
+      exec->is_composite     = TRUE;
+      exec->pedantic_hinting = load_flags & FT_LOAD_PEDANTIC;
+
+      error = TT_Run_Context( exec, debug );
+      if ( error && exec->pedantic_hinting )
+        return error;
+    }
+
+    /* save glyph origin and advance points */
+    subg->pp1 = pts->cur[n_points - 2];
+    subg->pp2 = pts->cur[n_points - 1];
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Init_Glyph_Component                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a glyph component for further processing.              */
+  /*                                                                       */
+  static
+  void  Init_Glyph_Component( TT_SubGlyphRec*  element,
+                              TT_SubGlyphRec*  original,
+                              TT_ExecContext   exec )
+  {
+    element->index     = -1;
+    element->is_scaled = FALSE;
+    element->is_hinted = FALSE;
+
+    if ( original )
+      mount_zone( &original->zone, &element->zone );
+    else
+      element->zone = exec->pts;
+
+    element->zone.n_contours = 0;
+    element->zone.n_points   = 0;
+
+    element->arg1 = 0;
+    element->arg2 = 0;
+
+    element->element_flag = 0;
+    element->preserve_pps = FALSE;
+
+    element->transform.xx = 1 << 16;
+    element->transform.xy = 0;
+    element->transform.yx = 0;
+    element->transform.yy = 1 << 16;
+
+    element->transform.ox = 0;
+    element->transform.oy = 0;
+
+    element->left_bearing = 0;
+    element->advance      = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Glyph                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function used to load a single glyph within a given glyph slot,  */
+  /*    for a given size.                                                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    glyph       :: A handle to a target slot object where the glyph    */
+  /*                   will be loaded.                                     */
+  /*                                                                       */
+  /*    size        :: A handle to the source face size at which the glyph */
+  /*                   must be scaled/loaded.                              */
+  /*                                                                       */
+  /*    glyph_index :: The index of the glyph in the font file.            */
+  /*                                                                       */
+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
+  /*                   FT_LOAD_XXX constants can be used to control the    */
+  /*                   glyph loading process (e.g., whether the outline    */
+  /*                   should be scaled, whether to load bitmaps or not,   */
+  /*                   whether to hint the outline, etc).                  */
+  /* <Output>                                                              */
+  /*    result      :: A set of bit flags indicating the type of data that */
+  /*                   was loaded in the glyph slot (outline or bitmap,    */
+  /*                   etc).                                               */
+  /*                                                                       */
+  /*                   You can set this field to 0 if you don't want this  */
+  /*                   information.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Glyph( TT_Size       size,
+                           TT_GlyphSlot  glyph,
+                           TT_UShort     glyph_index,
+                           TT_UInt       load_flags )
+  {
+    typedef enum  TPhases_
+    {
+      Load_Exit,
+      Load_Glyph,
+      Load_Header,
+      Load_Simple,
+      Load_Composite,
+      Load_End
+
+    } TPhases;
+
+    TT_Error   error = 0;
+    FT_Stream  stream;
+
+    TT_Face    face;
+
+    TT_UShort  num_points;
+    TT_Short   num_contours;
+    TT_UShort  left_points;
+    TT_Short   left_contours;
+
+    TT_ULong   load_top;
+    TT_Long    k, l;
+    TT_Int     new_flags;
+    TT_UShort  index;
+    TT_UShort  u;
+    TT_Long    count;
+
+    TT_Long  glyph_offset, offset;
+
+    TT_F26Dot6  x, y, nx, ny;
+
+    TT_Fixed  xx, xy, yx, yy;
+    TT_BBox   bbox;
+
+    TT_ExecContext  exec;
+
+    TT_SubGlyphRec *subglyph, *subglyph2;
+
+    TT_GlyphZone base_pts;
+
+    TPhases   phase;
+    TT_Byte*  widths;
+
+    SFNT_Interface*  sfnt;
+    
+    /* first of all, check arguments */
+    if ( !glyph )
+      return TT_Err_Invalid_Glyph_Handle;
+
+    face = (TT_Face)glyph->face;
+    if ( !face )
+      return TT_Err_Invalid_Glyph_Handle;
+
+    sfnt   = (SFNT_Interface*)face->sfnt;
+    stream = face->root.stream;
+    count  = 0;
+    
+    if ( glyph_index >= face->root.num_glyphs )
+      return TT_Err_Invalid_Glyph_Index;
+
+    if ( !size || (load_flags & FT_LOAD_NO_SCALE) )
+    {
+      size        = NULL;
+      load_flags |= FT_LOAD_NO_SCALE   |
+                    FT_LOAD_NO_HINTING |
+                    FT_LOAD_NO_BITMAP;
+    }
+
+    /* Try to load embedded bitmap if any */
+    if ( size && (load_flags & FT_LOAD_NO_BITMAP) == 0 && sfnt->load_sbits )
+    {
+      TT_SBit_Metrics  metrics;
+ 
+      error = sfnt->load_sbit_image( face,
+                                     size->root.metrics.x_ppem,
+                                     size->root.metrics.y_ppem,
+                                     glyph_index,
+                                     stream,
+                                     &glyph->bitmap,
+                                     &metrics );
+      if ( !error )
+      {
+        glyph->outline.n_points   = 0;
+        glyph->outline.n_contours = 0;
+
+        glyph->metrics.width  = (TT_Pos)metrics.width  << 6;
+        glyph->metrics.height = (TT_Pos)metrics.height << 6;
+
+        glyph->metrics.horiBearingX = (TT_Pos)metrics.horiBearingX << 6;
+        glyph->metrics.horiBearingY = (TT_Pos)metrics.horiBearingY << 6;
+        glyph->metrics.horiAdvance  = (TT_Pos)metrics.horiAdvance  << 6;
+
+        glyph->metrics.vertBearingX = (TT_Pos)metrics.vertBearingX << 6;
+        glyph->metrics.vertBearingY = (TT_Pos)metrics.vertBearingY << 6;
+        glyph->metrics.vertAdvance  = (TT_Pos)metrics.vertAdvance  << 6;
+
+        glyph->format = ft_glyph_format_bitmap;
+        return error;
+      }
+    }
+
+    if ( load_flags & FT_LOAD_NO_OUTLINE )
+      return ( error ? error : TT_Err_Unavailable_Bitmap );
+
+    error = face->goto_table( face, TTAG_glyf, stream, 0 );
+    if (error)
+    {
+      FT_ERROR(( "TT.GLoad: could not access glyph table\n" ));
+      return error;
+    }
+
+    glyph_offset = FILE_Pos();
+
+    /* query new execution context */
+
+    if ( size && size->debug )
+      exec = size->context;
+    else
+      exec = TT_New_Context( face );
+
+    if ( !exec )
+      return TT_Err_Could_Not_Find_Context;
+
+    TT_Load_Context( exec, face, size );
+
+    if ( size )
+    {
+      /* load default graphics state - if needed */
+      if ( size->GS.instruct_control & 2 )
+        exec->GS = tt_default_graphics_state;
+
+      glyph->outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+    }
+
+    /* save its critical pointers, as they'll be modified during load */
+    base_pts = exec->pts;
+
+    /* init variables */
+    left_points   = face->root.max_points;    /* remove phantom points */
+    left_contours = face->root.max_contours;
+
+    num_points   = 0;
+    num_contours = 0;
+
+    load_top = 0;
+    subglyph = exec->loadStack;
+
+    Init_Glyph_Component( subglyph, NULL, exec );
+
+    subglyph->index     = glyph_index;
+    subglyph->is_hinted = !(load_flags & FT_LOAD_NO_HINTING);
+
+    /* when the cvt program has disabled hinting, the argument */
+    /* is ignored.                                             */
+    if ( size && (size->GS.instruct_control & 1) )
+      subglyph->is_hinted = FALSE;
+
+    /* Main loading loop */
+
+    phase = Load_Glyph;
+    index = 0;
+
+    while ( phase != Load_Exit )
+    {
+      subglyph = exec->loadStack + load_top;
+
+      switch ( phase )
+      {
+
+        /************************************************************/
+        /*                                                          */
+        /* Load_Glyph state                                         */
+        /*                                                          */
+        /*   reading a glyph's generic data, checking whether the   */
+        /*   glyph is cached already (not implemented yet)          */
+        /*                                                          */
+        /* exit states: Load_Header and Load_End                    */
+        /*                                                          */
+      case Load_Glyph:
+        /* check glyph index and table */
+
+        index = (TT_UInt)subglyph->index;
+        if ( index >= face->root.num_glyphs )
+        {
+          error = TT_Err_Invalid_Glyph_Index;
+          goto Fail;
+        }
+
+        /* get horizontal metrics */
+        {
+          TT_Short   left_bearing;
+          TT_UShort  advance_width;
+
+
+          Get_HMetrics( face, index, TRUE,
+                        &left_bearing,
+                        &advance_width );
+
+          subglyph->left_bearing = left_bearing;
+          subglyph->advance      = advance_width;
+        }
+
+        phase = Load_Header;
+        break;
+
+        /************************************************************/
+        /*                                                          */
+        /* Load_Header state                                        */
+        /*                                                          */
+        /*   reading a glyph's generic header to determine whether  */
+        /*   it is a simple or composite glyph                      */
+        /*                                                          */
+        /* exit states: Load_Simple and Load_Composite              */
+        /*                                                          */
+      case Load_Header:
+        /* load glyph */
+
+        offset = face->glyph_locations[index];
+        count  = 0;
+        if (index < face->num_locations-1)
+          count = face->glyph_locations[index+1] - offset;
+
+        if ( index < ( face->num_locations - 1 ) && count == 0 )
+        {
+          /* as described by Frederic Loyer, these are spaces, and */
+          /* not the unknown glyph.                                */
+
+          num_contours = 0;
+          num_points   = 0;
+
+          subglyph->bbox.xMin = 0;
+          subglyph->bbox.xMax = 0;
+          subglyph->bbox.yMin = 0;
+          subglyph->bbox.yMax = 0;
+
+          subglyph->pp1.x = 0;
+          subglyph->pp2.x = subglyph->advance;
+
+          if ( !(load_flags & FT_LOAD_NO_SCALE) )
+            subglyph->pp2.x = SCALE_X( subglyph->pp2.x );
+
+          exec->glyphSize = 0;
+          phase = Load_End;
+          break;
+        }
+
+        offset = glyph_offset + offset;
+
+        /* read first glyph header */
+        if ( FILE_Seek( offset ) ||
+             ACCESS_Frame( 10L ) )
+          goto Fail_File;
+
+        num_contours = GET_Short();
+
+        subglyph->bbox.xMin = GET_Short();
+        subglyph->bbox.yMin = GET_Short();
+        subglyph->bbox.xMax = GET_Short();
+        subglyph->bbox.yMax = GET_Short();
+
+        FORGET_Frame();
+
+        FT_TRACE6(( "Glyph %ld\n", index ));
+        FT_TRACE6(( " # of contours : %d\n", num_contours ));
+        FT_TRACE6(( " xMin: %4d  xMax: %4d\n",
+                     subglyph->bbox.xMin,
+                     subglyph->bbox.xMax ));
+        FT_TRACE6(( " yMin: %4d  yMax: %4d\n",
+                     subglyph->bbox.yMin,
+                     subglyph->bbox.yMax ));
+        FT_TRACE6(( "-" ));
+
+        count -= 10;
+
+        if ( num_contours > left_contours )
+        {
+          FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index ));
+          error = TT_Err_Too_Many_Contours;
+          goto Fail;
+        }
+
+        subglyph->pp1.x = subglyph->bbox.xMin - subglyph->left_bearing;
+        subglyph->pp1.y = 0;
+        subglyph->pp2.x = subglyph->pp1.x + subglyph->advance;
+        if (!(load_flags & FT_LOAD_NO_SCALE))
+        {
+          subglyph->pp1.x = SCALE_X( subglyph->pp1.x );
+          subglyph->pp2.x = SCALE_X( subglyph->pp2.x );
+        }
+
+        /* is it a simple glyph ? */
+        if ( num_contours > 0 )
+          phase = Load_Simple;
+        else
+          phase = Load_Composite;
+
+        break;
+
+        /************************************************************/
+        /*                                                          */
+        /* Load_Simple state                                        */
+        /*                                                          */
+        /*   reading a simple glyph (num_contours must be set to    */
+        /*   the glyph's number of contours.)                       */
+        /*                                                          */
+        /* exit state: Load_End                                     */
+        /*                                                          */
+      case Load_Simple:
+        new_flags = load_flags;
+
+        /* disable hinting when scaling */
+        if ( !subglyph->is_hinted )
+          new_flags |= FT_LOAD_NO_HINTING;
+
+        error = Load_Simple_Glyph( exec,
+                                   stream,
+                                   count,
+                                   num_contours,
+                                   left_contours,
+                                   left_points,
+                                   new_flags,
+                                   subglyph,
+                                   (TT_Bool)(size && size->debug &&
+                                             load_top == 0) );
+        if ( error )
+          goto Fail;
+
+        /* Note: We could have put the simple loader source there */
+        /*       but the code is fat enough already :-)           */
+
+        num_points = exec->pts.n_points - 2;
+
+        phase = Load_End;
+
+        break;
+
+        /************************************************************/
+        /*                                                          */
+        /* Load_Composite state                                     */
+        /*                                                          */
+        /*   reading a composite glyph header and pushing a new     */
+        /*   load element on the stack.                             */
+        /*                                                          */
+        /* exit state: Load_Glyph                                  */
+        /*                                                          */
+      case Load_Composite:
+
+        /* create a new element on the stack */
+        load_top++;
+
+        if ( load_top > face->max_components )
+        {
+          error = TT_Err_Invalid_Composite;
+          goto Fail;
+        }
+
+        subglyph2 = exec->loadStack + load_top;
+
+        Init_Glyph_Component( subglyph2, subglyph, NULL );
+        subglyph2->is_hinted = subglyph->is_hinted;
+
+        /* now read composite header */
+
+        if ( ACCESS_Frame( 4L ) )
+          goto Fail_File;
+
+        subglyph->element_flag = new_flags = GET_UShort();
+
+        subglyph2->index = GET_UShort();
+
+        FORGET_Frame();
+
+        k = 1+1;
+
+        if ( new_flags & ARGS_ARE_WORDS )
+          k *= 2;
+
+        if ( new_flags & WE_HAVE_A_SCALE )
+          k += 2;
+
+        else if ( new_flags & WE_HAVE_AN_XY_SCALE )
+          k += 4;
+
+        else if ( new_flags & WE_HAVE_A_2X2 )
+          k += 8;
+
+        if ( ACCESS_Frame( k ) )
+          goto Fail_File;
+
+        if ( new_flags & ARGS_ARE_WORDS )
+        {
+          k = GET_Short();
+          l = GET_Short();
+        }
+        else
+        {
+          k = GET_Char();
+          l = GET_Char();
+        }
+
+        subglyph->arg1 = k;
+        subglyph->arg2 = l;
+
+        if ( new_flags & ARGS_ARE_XY_VALUES )
+        {
+          subglyph->transform.ox = k;
+          subglyph->transform.oy = l;
+        }
+
+        xx = 1 << 16;
+        xy = 0;
+        yx = 0;
+        yy = 1 << 16;
+
+        if ( new_flags & WE_HAVE_A_SCALE )
+        {
+          xx = (TT_Fixed)GET_Short() << 2;
+          yy = xx;
+          subglyph2->is_scaled = TRUE;
+        }
+        else if ( new_flags & WE_HAVE_AN_XY_SCALE )
+        {
+          xx = (TT_Fixed)GET_Short() << 2;
+          yy = (TT_Fixed)GET_Short() << 2;
+          subglyph2->is_scaled = TRUE;
+        }
+        else if ( new_flags & WE_HAVE_A_2X2 )
+        {
+          xx = (TT_Fixed)GET_Short() << 2;
+          xy = (TT_Fixed)GET_Short() << 2;
+          yx = (TT_Fixed)GET_Short() << 2;
+          yy = (TT_Fixed)GET_Short() << 2;
+          subglyph2->is_scaled = TRUE;
+        }
+
+        FORGET_Frame();
+
+        subglyph->transform.xx = xx;
+        subglyph->transform.xy = xy;
+        subglyph->transform.yx = yx;
+        subglyph->transform.yy = yy;
+
+        k = FT_MulFix( xx, yy ) -  FT_MulFix( xy, yx );
+
+        /* disable hinting in case of scaling/slanting */
+        if ( ABS( k ) != (1 << 16) )
+          subglyph2->is_hinted = FALSE;
+
+        subglyph->file_offset = FILE_Pos();
+
+        phase = Load_Glyph;
+
+        break;
+
+        /************************************************************/
+        /*                                                          */
+        /* Load_End state                                           */
+        /*                                                          */
+        /*   after loading a glyph, apply transformation and offset */
+        /*   where necessary, pop element and continue or stop      */
+        /*   process.                                               */
+        /*                                                          */
+        /* exit states: Load_Composite and Load_Exit                */
+        /*                                                          */
+      case Load_End:
+        if ( load_top > 0 )
+        {
+          subglyph2 = subglyph;
+
+          load_top--;
+          subglyph = exec->loadStack + load_top;
+
+          /* check advance width and left side bearing */
+
+          if ( !subglyph->preserve_pps &&
+               subglyph->element_flag & USE_MY_METRICS )
+          {
+            subglyph->left_bearing = subglyph2->left_bearing;
+            subglyph->advance      = subglyph2->advance;
+
+            subglyph->pp1 = subglyph2->pp1;
+            subglyph->pp2 = subglyph2->pp2;
+
+            subglyph->preserve_pps = TRUE;
+          }
+
+          /* apply scale */
+
+          if ( subglyph2->is_scaled )
+          {
+            TT_Vector*  cur = subglyph2->zone.cur;
+            TT_Vector*  org = subglyph2->zone.org;
+
+
+            for ( u = 0; u < num_points; u++ )
+            {
+              nx = FT_MulFix( cur->x, subglyph->transform.xx ) +
+                   FT_MulFix( cur->y, subglyph->transform.yx );
+
+              ny = FT_MulFix( cur->x, subglyph->transform.xy ) +
+                   FT_MulFix( cur->y, subglyph->transform.yy );
+
+              cur->x = nx;
+              cur->y = ny;
+
+              nx = FT_MulFix( org->x, subglyph->transform.xx ) +
+                   FT_MulFix( org->y, subglyph->transform.yx );
+
+              ny = FT_MulFix( org->x, subglyph->transform.xy ) +
+                   FT_MulFix( org->y, subglyph->transform.yy );
+
+              org->x = nx;
+              org->y = ny;
+
+              cur++;
+              org++;
+            }
+          }
+
+          /* adjust counts */
+
+          for ( k = 0; k < num_contours; k++ )
+            subglyph2->zone.contours[k] += subglyph->zone.n_points;
+
+          subglyph->zone.n_points   += num_points;
+          subglyph->zone.n_contours += num_contours;
+
+          left_points   -= num_points;
+          left_contours -= num_contours;
+
+          /* apply offset */
+
+          if ( !(subglyph->element_flag & ARGS_ARE_XY_VALUES) )
+          {
+            k = subglyph->arg1;
+            l = subglyph->arg2;
+
+            if ( k >= subglyph->zone.n_points ||
+                 l >= num_points )
+            {
+              error = TT_Err_Invalid_Composite;
+              goto Fail;
+            }
+
+            l += subglyph->zone.n_points; 
+	    
+            x = subglyph->zone.cur[k].x - subglyph->zone.cur[l].x;
+            y = subglyph->zone.cur[k].y - subglyph->zone.cur[l].y;
+          }
+          else
+          {
+            x = subglyph->transform.ox;
+            y = subglyph->transform.oy;
+
+            if (!(load_flags & FT_LOAD_NO_SCALE))
+            {
+              x = SCALE_X( x );
+              y = SCALE_Y( y );
+            }
+          }
+
+          if ( subglyph->element_flag & ROUND_XY_TO_GRID )
+	  {
+	    x = (x + 32) & -64;
+	    y = (y + 32) & -64;
+	  }
+
+          translate_array( num_points, subglyph2->zone.cur, x, y );
+
+          cur_to_org( num_points, &subglyph2->zone );
+
+          num_points   = subglyph->zone.n_points;
+          num_contours = subglyph->zone.n_contours;
+
+          /* check for last component */
+
+          if ( FILE_Seek( subglyph->file_offset ) )
+            goto Fail_File;
+
+          if ( subglyph->element_flag & MORE_COMPONENTS )
+            phase = Load_Composite;
+          else
+          {
+            error = Load_Composite_End( num_points,
+                                        num_contours,
+                                        exec,
+                                        subglyph,
+                                        stream,
+                                        load_flags,
+                                        (TT_Bool)(size && size->debug &&
+                                                  load_top == 0) );
+            if ( error )
+              goto Fail;
+
+            phase = Load_End;
+          }
+        }
+        else
+          phase = Load_Exit;
+
+        break;
+
+      case Load_Exit:
+        break;
+      }
+    }
+
+    /* finally, copy the points arrays to the glyph object */
+
+    exec->pts = base_pts;
+
+    for ( u = 0; u < num_points; u++ )
+    {
+      glyph->outline.points[u] = exec->pts.cur[u];
+      glyph->outline.flags [u] = exec->pts.touch[u];
+    }
+
+    for ( k = 0; k < num_contours; k++ )
+      glyph->outline.contours[k] = exec->pts.contours[k];
+
+    glyph->outline.n_points    = num_points;
+    glyph->outline.n_contours  = num_contours;
+    glyph->outline.second_pass = TRUE;
+
+    /* translate array so that (0,0) is the glyph's origin */
+    translate_array( num_points, glyph->outline.points,
+                     -subglyph->pp1.x, 0 );
+
+    FT_Get_Outline_CBox( &glyph->outline, &bbox );
+
+    if ( subglyph->is_hinted )
+    {
+      /* grid-fit the bounding box */
+      bbox.xMin &= -64;
+      bbox.yMin &= -64;
+      bbox.xMax  = (bbox.xMax + 63) & -64;
+      bbox.yMax  = (bbox.yMax + 63) & -64;
+    }
+
+    /* get the device-independent scaled horizontal metrics */
+    /* take care of fixed-pitch fonts...                    */
+    {
+      TT_Pos  left_bearing;
+      TT_Pos  advance;
+
+
+      left_bearing = subglyph->left_bearing;
+      advance      = subglyph->advance;
+
+      if ( face->postscript.isFixedPitch )
+        advance = face->horizontal.advance_Width_Max;
+
+      if ( !(load_flags & FT_LOAD_NO_SCALE) )
+      {
+        left_bearing = SCALE_X( left_bearing );
+        advance      = SCALE_X( advance );
+      }
+
+      glyph->metrics2.horiBearingX = left_bearing;
+      glyph->metrics2.horiAdvance  = advance;
+    }
+
+    glyph->metrics.horiBearingX = bbox.xMin;
+    glyph->metrics.horiBearingY = bbox.yMax;
+    glyph->metrics.horiAdvance  = subglyph->pp2.x - subglyph->pp1.x;
+
+    /* Now take care of vertical metrics.  In the case where there is    */
+    /* no vertical information within the font (relatively common), make */
+    /* up some metrics by `hand'...                                      */
+
+    {
+      TT_Short   top_bearing;    /* vertical top side bearing (EM units) */
+      TT_UShort  advance_height; /* vertical advance height   (EM units) */
+
+      TT_Pos  left;     /* scaled vertical left side bearing  */
+      TT_Pos  top;      /* scaled vertical top side bearing   */
+      TT_Pos  advance;  /* scaled vertical advance height     */
+
+
+      /* Get the unscaled `tsb' and `ah' */
+      if ( face->vertical_info                   &&
+           face->vertical.number_Of_VMetrics > 0 )
+      {
+        /* Don't assume that both the vertical header and vertical */
+        /* metrics are present in the same font :-)                */
+
+        TT_Get_Metrics( (TT_HoriHeader*)&face->vertical,
+                        glyph_index,
+                        &top_bearing,
+                        &advance_height );
+      }
+      else
+      {
+        /* Make up the distances from the horizontal header..     */
+
+        /* NOTE: The OS/2 values are the only `portable' ones,    */
+        /*       which is why we use them, when there is an       */
+        /*       OS/2 table in the font. Otherwise, we use the    */
+        /*       values defined in the horizontal header..        */
+        /*                                                        */
+        /* NOTE2: The sTypoDescender is negative, which is why    */
+        /*        we compute the baseline-to-baseline distance    */
+        /*        here with:                                      */
+        /*             ascender - descender + linegap             */
+        /*                                                        */
+        if ( face->os2.version != 0xFFFF )
+        {
+          top_bearing    = face->os2.sTypoLineGap / 2;
+          advance_height = (TT_UShort)(face->os2.sTypoAscender -
+                                       face->os2.sTypoDescender +
+                                       face->os2.sTypoLineGap);
+        }
+        else
+        {
+          top_bearing    = face->horizontal.Line_Gap / 2;
+          advance_height = (TT_UShort)(face->horizontal.Ascender  +
+                                       face->horizontal.Descender +
+                                       face->horizontal.Line_Gap);
+        }
+      }
+
+      /* scale the metrics */
+      if ( !(load_flags & FT_LOAD_NO_SCALE) )
+      {
+        top     = SCALE_Y( top_bearing );
+        advance = SCALE_X( advance_height );
+      }
+      else
+      {
+        top     = top_bearing;
+        advance = advance_height;
+      }
+
+      glyph->metrics2.vertBearingY = top;
+      glyph->metrics2.vertAdvance  = advance;
+
+      /* XXX: for now, we have no better algorithm for the lsb, but it    */
+      /*      should work fine.                                           */
+      /*                                                                  */
+      left = ( bbox.xMin - bbox.xMax ) / 2;
+
+      /* grid-fit them if necessary */
+      if ( subglyph->is_hinted )
+      {
+        left   &= -64;
+        top     = (top + 63) & -64;
+        advance = (advance + 32) & -64;
+      }
+
+      glyph->metrics.vertBearingX = left;
+      glyph->metrics.vertBearingY = top;
+      glyph->metrics.vertAdvance  = advance;
+    }
+
+    /* Adjust advance width to the value contained in the hdmx table. */
+    if ( !exec->face->postscript.isFixedPitch && size &&
+         subglyph->is_hinted )
+    {
+      widths = Get_Advance_Widths( exec->face,
+                                   exec->size->root.metrics.x_ppem );
+      if ( widths )
+        glyph->metrics.horiAdvance = widths[glyph_index] << 6;
+    }
+
+    glyph->outline.dropout_mode = (TT_Char)exec->GS.scan_type;
+
+    /* set glyph dimensions */
+    glyph->metrics.width  = bbox.xMax - bbox.xMin;
+    glyph->metrics.height = bbox.yMax - bbox.yMin;
+
+    glyph->format = ft_glyph_format_outline;
+
+    error = TT_Err_Ok;
+
+  Fail_File:
+  Fail:
+
+    /* reset the execution context */
+    exec->pts = base_pts;
+
+    if ( !size || !size->debug )
+      TT_Done_Context( exec );
+
+    return error;
+  }
+
+
+/* END */
diff --git a/src/truetype/ttgload.h b/src/truetype/ttgload.h
new file mode 100644
index 0000000..d544cee
--- /dev/null
+++ b/src/truetype/ttgload.h
@@ -0,0 +1,109 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttgload.h                                                              */
+/*                                                                         */
+/*    TrueType Glyph Loader (specification).                               */
+/*                                                                         */
+/*  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 TTGLOAD_H
+#define TTGLOAD_H
+
+#include <ttobjs.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Get_Metrics                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the horizontal or vertical metrics in font units for a     */
+  /*    given glyph.  The metrics are the left side bearing (resp. top     */
+  /*    side bearing) and advance width (resp. advance height).            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    header  :: A pointer to either the horizontal or vertical metrics  */
+  /*               structure.                                              */
+  /*                                                                       */
+  /*    index   :: The glyph index.                                        */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    bearing :: The bearing, either left side or top side.              */
+  /*                                                                       */
+  /*    advance :: The advance width resp. advance height.                 */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This function will much probably move to another component in the  */
+  /*    near future, but I haven't decided which yet.                      */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Get_Metrics( TT_HoriHeader*  header,
+                        TT_UShort       index,
+                        TT_Short*       bearing,
+                        TT_UShort*      advance );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Glyph                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function used to load a single glyph within a given glyph slot,  */
+  /*    for a given size.                                                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    glyph       :: A handle to a target slot object where the glyph    */
+  /*                   will be loaded.                                     */
+  /*                                                                       */
+  /*    size        :: A handle to the source face size at which the glyph */
+  /*                   must be scaled/loaded.                              */
+  /*                                                                       */
+  /*    glyph_index :: The index of the glyph in the font file.            */
+  /*                                                                       */
+  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
+  /*                   FT_LOAD_XXX constants can be used to control the    */
+  /*                   glyph loading process (e.g., whether the outline    */
+  /*                   should be scaled, whether to load bitmaps or not,   */
+  /*                   whether to hint the outline, etc).                  */
+  /* <Output>                                                              */
+  /*    result      :: A set of bit flags indicating the type of data that */
+  /*                   was loaded in the glyph slot (outline or bitmap,    */
+  /*                   etc).                                               */
+  /*                                                                       */
+  /*                   You can set this field to 0 if you don't want this  */
+  /*                   information.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Glyph( TT_Size       size,
+                           TT_GlyphSlot  glyph,
+                           TT_UShort     glyph_index,
+                           TT_UInt       load_flags );
+
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif /* TTGLOAD_H */
+
+
+/* END */
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
new file mode 100644
index 0000000..c9be4f2
--- /dev/null
+++ b/src/truetype/ttinterp.c
@@ -0,0 +1,7954 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttinterp.c                                                             */
+/*                                                                         */
+/*    TrueType bytecode intepreter (body).                                 */
+/*                                                                         */
+/*  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 <ftdebug.h>
+#include <ftsystem.h>
+#include <ftcalc.h>
+
+#include <ttinterp.h>
+
+#define TT_MULFIX   FT_MulFix
+#define TT_MULDIV   FT_MulDiv
+
+#define TT_INT64    FT_Int64
+
+/* required by the tracing mode */
+#undef  FT_COMPONENT
+#define FT_COMPONENT      trace_ttinterp
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* In order to detect infinite loops in the code, we set-up a counter    */
+  /* within the run loop. a single stroke of interpretation is now limited */
+  /* to a maximum number of opcodes defined below.                         */
+  /*                                                                       */
+#define MAX_RUNNABLE_OPCODES  1000000
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* There are two kinds of implementations:                               */
+  /*                                                                       */
+  /* a. static implementation:                                             */
+  /*                                                                       */
+  /*    The current execution context is a static variable, which fields   */
+  /*    are accessed directly by the interpreter during execution.  The    */
+  /*    context is named `cur'.                                            */
+  /*                                                                       */
+  /*    This version is non-reentrant, of course.                          */
+  /*                                                                       */
+  /* b. indirect implementation:                                           */
+  /*                                                                       */
+  /*    The current execution context is passed to _each_ function as its  */
+  /*    first argument, and each field is thus accessed indirectly.        */
+  /*                                                                       */
+  /*    This version is fully re-entrant.                                  */
+  /*                                                                       */
+  /* The idea is that an indirect implementation may be slower to execute  */
+  /* on low-end processors that are used in some systems (like 386s or     */
+  /* even 486s).                                                           */
+  /*                                                                       */
+  /* As a consequence, the indirect implementation is now the default, as  */
+  /* its performance costs can be considered negligible in our context.    */
+  /* Note, however, that we kept the same source with macros because:      */
+  /*                                                                       */
+  /* - The code is kept very close in design to the Pascal code used for   */
+  /*   development.                                                        */
+  /*                                                                       */
+  /* - It's much more readable that way!                                   */
+  /*                                                                       */
+  /* - It's still open to experimentation and tuning.                      */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef TT_CONFIG_OPTION_STATIC_INTERPRETER      /* indirect implementation */
+
+#define CUR (*exc)                 /* see ttobjs.h */
+
+#else                              /* static implementation */
+
+#define CUR cur
+
+  static
+  TT_ExecContextRec  cur;   /* static exec. context variable */
+
+  /* apparently, we have a _lot_ of direct indexing when accessing  */
+  /* the static `cur', which makes the code bigger (due to all the  */
+  /* four bytes addresses).                                         */
+
+#endif /* TT_CONFIG_OPTION_STATIC_INTERPRETER */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Most of FreeType builds don't use engine compensations.  We thus      */
+  /* introduce a macro, FT_CONFIG_OPTION_INTERPRETER_QUICK, which controls */
+  /* the use of these values.                                              */
+  /*                                                                       */
+#define INS_ARG  EXEC_OP_ TT_Long*  args  /* see ttobjs.h for EXEC_OP_ */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This macro is used whenever `exec' is unused in a function, to avoid  */
+  /* stupid warnings from pedantic compilers.                              */
+  /*                                                                       */
+#define UNUSED_EXEC  (void)CUR
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This macro is used whenever `args' is unused in a function, to avoid  */
+  /* stupid warnings from pedantic compilers.                              */
+  /*                                                                       */
+#define UNUSED_ARG  UNUSED_EXEC; (void)args;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The following macros hide the use of EXEC_ARG and EXEC_ARG_ to        */
+  /* increase readabiltyof the code.                                       */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#define SKIP_Code() \
+          SkipCode( EXEC_ARG )
+
+#define GET_ShortIns() \
+          GetShortIns( EXEC_ARG )
+
+#define NORMalize( x, y, v ) \
+          Normalize( EXEC_ARG_ x, y, v )
+
+#define SET_SuperRound( scale, flags ) \
+          SetSuperRound( EXEC_ARG_ scale, flags )
+
+#define ROUND_None( d, c ) \
+          Round_None( EXEC_ARG_ d, c )
+
+#define INS_Goto_CodeRange( range, ip ) \
+          Ins_Goto_CodeRange( EXEC_ARG_ range, ip )
+
+#define CUR_Func_project( x, y ) \
+          CUR.func_project( EXEC_ARG_ x, y )
+
+#define CUR_Func_move( z, p, d ) \
+          CUR.func_move( EXEC_ARG_ z, p, d )
+
+#define CUR_Func_dualproj( x, y ) \
+          CUR.func_dualproj( EXEC_ARG_ x, y )
+
+#define CUR_Func_freeProj( x, y ) \
+          CUR.func_freeProj( EXEC_ARG_ x, y )
+
+#define CUR_Func_round( d, c ) \
+          CUR.func_round( EXEC_ARG_ d, c )
+
+#define CUR_Func_read_cvt( index ) \
+          CUR.func_read_cvt( EXEC_ARG_ index )
+
+#define CUR_Func_write_cvt( index, val ) \
+          CUR.func_write_cvt( EXEC_ARG_ index, val )
+
+#define CUR_Func_move_cvt( index, val ) \
+          CUR.func_move_cvt( EXEC_ARG_ index, val )
+
+#define CURRENT_Ratio() \
+          Current_Ratio( EXEC_ARG )
+
+#define CURRENT_Ppem() \
+          Current_Ppem( EXEC_ARG )
+
+#define CUR_Ppem() \
+          Cur_PPEM( EXEC_ARG )
+
+#define CALC_Length() \
+          Calc_Length( EXEC_ARG )
+
+#define INS_SxVTL( a, b, c, d ) \
+          Ins_SxVTL( EXEC_ARG_ a, b, c, d )
+
+#define COMPUTE_Funcs() \
+          Compute_Funcs( EXEC_ARG )
+
+#define COMPUTE_Round( a ) \
+          Compute_Round( EXEC_ARG_ a )
+
+#define COMPUTE_Point_Displacement( a, b, c, d ) \
+          Compute_Point_Displacement( EXEC_ARG_ a, b, c, d )
+
+#define MOVE_Zp2_Point( a, b, c, t ) \
+          Move_Zp2_Point( EXEC_ARG_ a, b, c, t )
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Instruction dispatch function, as used by the interpreter.            */
+  /*                                                                       */
+  typedef void  (*TInstruction_Function)( INS_ARG );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* A simple bounds-checking macro.                                       */
+  /*                                                                       */
+#define BOUNDS( x, n )  ((TT_UInt)(x) >= (TT_UInt)(n))
+
+
+#undef   SUCCESS
+#define  SUCCESS   0
+
+#undef    FAILURE
+#define   FAILURE 1
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                        CODERANGE FUNCTIONS                            */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Goto_CodeRange                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Switches to a new code range (updates the code related elements in */
+  /*    `exec', and `IP').                                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range :: The new execution code range.                             */
+  /*    IP    :: The  new IP in the new code range.                        */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    exec  :: The target execution context.                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   TrueType error code.  0 means success.                              */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error  TT_Goto_CodeRange( TT_ExecContext  exec,
+                               TT_Int          range,
+                               TT_Long         IP )
+  {
+    TT_CodeRange*  coderange;
+
+
+    FT_Assert( range >= 1 && range <= 3 );
+
+    coderange = &exec->codeRangeTable[range - 1];
+
+    FT_Assert( coderange->base != NULL );
+
+    /* NOTE: Because the last instruction of a program may be a CALL */
+    /*       which will return to the first byte *after* the code    */
+    /*       range, we test for IP <= Size, instead of IP < Size.    */
+    /*                                                               */
+    FT_Assert( (TT_ULong)IP <= coderange->size );
+
+    exec->code     = coderange->base;
+    exec->codeSize = coderange->size;
+    exec->IP       = IP;
+    exec->curRange = range;
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Set_CodeRange                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets a code range.                                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range  :: The code range index.                                    */
+  /*    base   :: The new code base.                                       */
+  /*    length :: The range size in bytes.                                 */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    exec   :: The target execution context.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   TrueType error code.  0 means success.                              */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error  TT_Set_CodeRange( TT_ExecContext  exec,
+                              TT_Int          range,
+                              void*           base,
+                              TT_Long         length )
+  {
+    FT_Assert( range >= 1 && range <= 3 );
+
+    exec->codeRangeTable[range - 1].base = (TT_Byte*)base;
+    exec->codeRangeTable[range - 1].size = length;
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Clear_CodeRange                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Clears a code range.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range :: The code range index.                                     */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    exec  :: The target execution context.                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   TrueType error code.  0 means success.                              */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Does not set the Error variable.                                   */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error  TT_Clear_CodeRange( TT_ExecContext  exec,
+                                TT_Int          range )
+  {
+    FT_Assert( range >= 1 && range <= 3 );
+
+    exec->codeRangeTable[range - 1].base = NULL;
+    exec->codeRangeTable[range - 1].size = 0;
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                   EXECUTION CONTEXT ROUTINES                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Destroy_Context                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given context.                                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec   :: A handle to the target execution context.                */
+  /*    system :: A handle to the parent system object.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Destroy_Context( TT_ExecContext  exec,
+                                FT_Memory       memory )
+  {
+    /* free composite load stack */
+    FREE( exec->loadStack );
+    exec->loadSize = 0;
+
+    /* points zone */
+    TT_Done_GlyphZone( exec->memory, &exec->pts );
+    exec->maxPoints   = 0;
+    exec->maxContours = 0;
+
+    /* free stack */
+    FREE( exec->stack );
+    exec->stackSize = 0;
+
+    /* free call stack */
+    FREE( exec->callStack );
+    exec->callSize = 0;
+    exec->callTop  = 0;
+
+    /* free glyph code range */
+    FREE( exec->glyphIns );
+    exec->glyphSize = 0;
+
+    exec->size = NULL;
+    exec->face = NULL;
+
+    FREE( exec );
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Init_Context                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a context object.                                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to the parent memory object.                    */
+  /*                                                                       */
+  /*    face   :: A handle to the source TrueType face object.             */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    exec   :: A handle to the target execution context.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Init_Context( TT_ExecContext  exec,
+                          TT_Face         face,
+                          FT_Memory       memory )
+  {
+    TT_Error  error;
+
+
+    FT_TRACE1(( "TT.Create_Create: new object at 0x%08lx, parent = 0x%08lx\n",
+              (long)exec, (long)face ));
+
+    /* XXX: We don't reserve arrays anymore, this is done automatically */
+    /*      during a call to Context_Load().                            */
+
+    exec->memory   = memory;
+    exec->callSize = 32;
+
+    if ( ALLOC_ARRAY( exec->callStack, exec->callSize, TT_CallRec ) )
+      goto Fail_Memory;
+
+    /* all values in the context are set to 0 already, but this is */
+    /* here as a remainder                                         */
+    exec->maxPoints   = 0;
+    exec->maxContours = 0;
+
+    exec->stackSize = 0;
+    exec->loadSize  = 0;
+    exec->glyphSize = 0;
+
+    exec->stack     = NULL;
+    exec->loadStack = NULL;
+    exec->glyphIns  = NULL;
+
+    exec->face = face;
+    exec->size = NULL;
+
+    return TT_Err_Ok;
+
+  Fail_Memory:
+    FT_ERROR(( "TT.Context_Create: not enough memory for 0x%08lx\n",
+             (long)exec ));
+    TT_Destroy_Context( exec, memory );
+
+    return error;
+ }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Update_Max                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Checks the size of a buffer and reallocates it if necessary.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    multiplier :: The size in bytes of each element in the buffer.     */
+  /*                                                                       */
+  /*    new_max    :: The new capacity (size) of the buffer.               */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    size       :: The address of the buffer's current size expressed   */
+  /*                  in elements.                                         */
+  /*                                                                       */
+  /*    buff       :: The address of the buffer base pointer.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  static
+  TT_Error  Update_Max( FT_Memory  memory,
+                        TT_ULong*  size,
+                        TT_Long    multiplier,
+                        void**     buff,
+                        TT_ULong   new_max )
+  {
+    TT_Error  error;
+
+
+    if ( *size < new_max )
+    {
+      FREE( *buff );
+      if ( ALLOC( *buff, new_max * multiplier ) )
+        return error;
+      *size = new_max;
+    }
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Update_Zone                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Checks the size of a zone and reallocates it if necessary.         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    newPoints   :: The new capacity for points.  We add two slots for  */
+  /*                   phantom points.                                     */
+  /*                                                                       */
+  /*    newContours :: The new capacity for contours.                      */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    zone        :: The address of the target zone.                     */
+  /*                                                                       */
+  /*    maxPoints   :: The address of the zone's current capacity for      */
+  /*                   points.                                             */
+  /*                                                                       */
+  /*    maxContours :: The address of the zone's current capacity for      */
+  /*                   contours.                                           */
+  /*                                                                       */
+  static
+  TT_Error  Update_Zone( FT_Memory      memory,
+                         TT_GlyphZone*  zone,
+                         TT_UShort*     maxPoints,
+                         TT_Short*      maxContours,
+                         TT_UShort      newPoints,
+                         TT_Short       newContours )
+  {
+    newPoints += 2;
+
+    if ( *maxPoints < newPoints || *maxContours < newContours )
+    {
+      TT_Error  error;
+
+
+      TT_Done_GlyphZone( memory, zone );
+
+      error = TT_New_GlyphZone( memory, zone, newPoints, newContours );
+      if ( error )
+        return error;
+
+      *maxPoints   = newPoints;
+      *maxContours = newContours;
+    }
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Context                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Prepare an execution context for glyph hinting.                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the source face object.                        */
+  /*    size :: A handle to the source size object.                        */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    exec :: A handle to the target execution context.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error  TT_Load_Context( TT_ExecContext  exec,
+                             TT_Face         face,
+                             TT_Size         size )
+  {
+    TT_Int          i;
+    TT_ULong        tmp;
+    TT_MaxProfile*  maxp;
+    TT_Error        error;
+
+
+    exec->face = face;
+    maxp       = &face->max_profile;
+    exec->size = size;
+
+    if ( size )
+    {
+      exec->numFDefs   = size->num_function_defs;
+      exec->maxFDefs   = size->max_function_defs;
+      exec->numIDefs   = size->num_instruction_defs;
+      exec->maxIDefs   = size->max_instruction_defs;
+      exec->FDefs      = size->function_defs;
+      exec->IDefs      = size->instruction_defs;
+      exec->tt_metrics = size->ttmetrics;
+      exec->metrics    = size->root.metrics;
+
+      exec->maxFunc    = size->max_func;
+      exec->maxIns     = size->max_ins;
+
+      for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
+        exec->codeRangeTable[i] = size->codeRangeTable[i];
+
+      /* set graphics state */
+      exec->GS = size->GS;
+
+      exec->cvtSize = size->cvt_size;
+      exec->cvt     = size->cvt;
+
+      exec->storeSize = size->storage_size;
+      exec->storage   = size->storage;
+
+      exec->twilight  = size->twilight;
+    }
+
+    error = Update_Max( exec->memory,
+                        &exec->loadSize,
+                        sizeof ( TT_SubGlyphRec ),
+                        (void**)&exec->loadStack,
+                        exec->face->max_components + 1 );
+    if ( error )
+      return error;
+
+    /* XXX: We reserve a little more elements on the stack to deal safely */
+    /*      with broken fonts like arialbs, courbs, timesbs, etc.         */
+    tmp = exec->stackSize;
+    error = Update_Max( exec->memory,
+                        &tmp,
+                        sizeof ( TT_F26Dot6 ),
+                        (void**)&exec->stack,
+                        maxp->maxStackElements + 32 );
+    exec->stackSize = (TT_UInt)tmp;
+    if ( error )
+      return error;
+
+    tmp = exec->glyphSize;
+    error = Update_Max( exec->memory,
+                        &tmp,
+                        sizeof ( TT_Byte ),
+                        (void**)&exec->glyphIns,
+                        maxp->maxSizeOfInstructions );
+    exec->glyphSize = (TT_UShort)tmp;
+    if ( error )
+      return error;
+
+    /* XXX: Update_Zone() reserves two positions for the phantom points! */
+    error = Update_Zone( exec->memory,
+                         &exec->pts,
+                         &exec->maxPoints,
+                         &exec->maxContours,
+                         exec->face->root.max_points,
+                         exec->face->root.max_contours );
+    if ( error )
+      return error;
+
+    exec->pts.n_points   = 0;
+    exec->pts.n_contours = 0;
+
+    exec->instruction_trap = FALSE;
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Save_Context                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Saves the code ranges in a `size' object.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec :: A handle to the source execution context.                  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    ins  :: A handle to the target size object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error  TT_Save_Context( TT_ExecContext  exec,
+                             TT_Size         size )
+  {
+    TT_Int  i;
+
+    /* XXXX: Will probably disappear soon with all the code range */
+    /*       management, which is now rather obsolete.            */
+    /*                                                            */
+    size->num_function_defs    = exec->numFDefs;
+    size->num_instruction_defs = exec->numIDefs;
+
+    size->max_func = exec->maxFunc;
+    size->max_ins  = exec->maxIns;
+
+    for ( i = 0; i < TT_MAX_CODE_RANGES; i++ )
+      size->codeRangeTable[i] = exec->codeRangeTable[i];
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Run_Context                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Executes one or more instructions in the execution context.        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    debug :: A Boolean flag.  If set, the function sets some internal  */
+  /*             variables and returns immediately, otherwise TT_RunIns()  */
+  /*             is called.                                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec  :: A handle to the target execution context.                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueTyoe error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error  TT_Run_Context( TT_ExecContext  exec,
+                            TT_Bool         debug )
+  {
+    TT_Error  error;
+
+    if ( (error = TT_Goto_CodeRange( exec, tt_coderange_glyph, 0 ))
+           != TT_Err_Ok )
+      return error;
+
+    exec->zp0 = exec->pts;
+    exec->zp1 = exec->pts;
+    exec->zp2 = exec->pts;
+
+    exec->GS.gep0 = 1;
+    exec->GS.gep1 = 1;
+    exec->GS.gep2 = 1;
+
+    exec->GS.projVector.x = 0x4000;
+    exec->GS.projVector.y = 0x0000;
+
+    exec->GS.freeVector = exec->GS.projVector;
+    exec->GS.dualVector = exec->GS.projVector;
+
+    exec->GS.round_state = 1;
+    exec->GS.loop        = 1;
+
+    /* some glyphs leave something on the stack. so we clean it */
+    /* before a new execution.                                  */
+    exec->top     = 0;
+    exec->callTop = 0;
+
+#if 1
+    return exec->face->interpreter( exec );
+#else
+    if ( !debug )
+      return TT_RunIns( exec );
+    else
+      return TT_Err_Ok;
+#endif
+  }
+
+
+  LOCAL_FUNC
+  const TT_GraphicsState  tt_default_graphics_state =
+  {
+    0, 0, 0,
+    { 0x4000, 0 },
+    { 0x4000, 0 },
+    { 0x4000, 0 },
+    1, 64, 1,
+    TRUE, 68, 0, 0, 9, 3,
+    0, FALSE, 2, 1, 1, 1
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_New_Context                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Queries the face context for a given font.  Note that there is     */
+  /*    now a _single_ execution context in the TrueType driver which is   */
+  /*    shared among faces.                                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the source face object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    A handle to the execution context.  Initialized for `face'.        */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_ExecContext  TT_New_Context( TT_Face  face )
+  {
+    TT_Driver       driver = (TT_Driver)face->root.driver;
+    TT_ExecContext  exec;
+    FT_Memory       memory = driver->root.memory;
+
+
+    exec = driver->context;
+
+    if ( !driver->context )
+    {
+      TT_Error   error;
+
+
+      /* allocate object */
+      if ( ALLOC( exec, sizeof ( *exec ) ) )
+        goto Exit;
+
+      /* initialize it */
+      error = Init_Context( exec, face, memory );
+      if ( error )
+        goto Fail;
+
+      /* store it into the driver */
+      driver->context = exec;
+    }
+
+  Exit:
+    return driver->context;
+
+  Fail:
+    FREE( exec );
+
+    return 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_Context                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards an execution context.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec :: A handle to the target execution context.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  EXPORT_FUNC
+  TT_Error  TT_Done_Context( TT_ExecContext  exec )
+  {
+    /* Nothing at all for now */
+    UNUSED( exec );
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Before an opcode is executed, the interpreter verifies that there are */
+  /* enough arguments on the stack, with the help of the Pop_Push_Count    */
+  /* table.                                                                */
+  /*                                                                       */
+  /* For each opcode, the first column gives the number of arguments that  */
+  /* are popped from the stack; the second one gives the number of those   */
+  /* that are pushed in result.                                            */
+  /*                                                                       */
+  /* Note that for opcodes with a varying number of parameters, either 0   */
+  /* or 1 arg is verified before execution, depending on the nature of the */
+  /* instruction:                                                          */
+  /*                                                                       */
+  /* - if the number of arguments is given by the bytecode stream or the   */
+  /*   loop variable, 0 is chosen.                                         */
+  /*                                                                       */
+  /* - if the first argument is a count n that is followed by arguments    */
+  /*   a1 .. an, then 1 is chosen.                                         */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#undef  PACK
+#define PACK( x, y )  ((x << 4) | y)
+
+
+  static
+  const TT_Byte  Pop_Push_Count[256] =
+  {
+    /* opcodes are gathered in groups of 16 */
+    /* please keep the spaces as they are   */
+
+    /*  SVTCA  y  */  PACK( 0, 0 ),
+    /*  SVTCA  x  */  PACK( 0, 0 ),
+    /*  SPvTCA y  */  PACK( 0, 0 ),
+    /*  SPvTCA x  */  PACK( 0, 0 ),
+    /*  SFvTCA y  */  PACK( 0, 0 ),
+    /*  SFvTCA x  */  PACK( 0, 0 ),
+    /*  SPvTL //  */  PACK( 2, 0 ),
+    /*  SPvTL +   */  PACK( 2, 0 ),
+    /*  SFvTL //  */  PACK( 2, 0 ),
+    /*  SFvTL +   */  PACK( 2, 0 ),
+    /*  SPvFS     */  PACK( 2, 0 ),
+    /*  SFvFS     */  PACK( 2, 0 ),
+    /*  GPV       */  PACK( 0, 2 ),
+    /*  GFV       */  PACK( 0, 2 ),
+    /*  SFvTPv    */  PACK( 0, 0 ),
+    /*  ISECT     */  PACK( 5, 0 ),
+
+    /*  SRP0      */  PACK( 1, 0 ),
+    /*  SRP1      */  PACK( 1, 0 ),
+    /*  SRP2      */  PACK( 1, 0 ),
+    /*  SZP0      */  PACK( 1, 0 ),
+    /*  SZP1      */  PACK( 1, 0 ),
+    /*  SZP2      */  PACK( 1, 0 ),
+    /*  SZPS      */  PACK( 1, 0 ),
+    /*  SLOOP     */  PACK( 1, 0 ),
+    /*  RTG       */  PACK( 0, 0 ),
+    /*  RTHG      */  PACK( 0, 0 ),
+    /*  SMD       */  PACK( 1, 0 ),
+    /*  ELSE      */  PACK( 0, 0 ),
+    /*  JMPR      */  PACK( 1, 0 ),
+    /*  SCvTCi    */  PACK( 1, 0 ),
+    /*  SSwCi     */  PACK( 1, 0 ),
+    /*  SSW       */  PACK( 1, 0 ),
+
+    /*  DUP       */  PACK( 1, 2 ),
+    /*  POP       */  PACK( 1, 0 ),
+    /*  CLEAR     */  PACK( 0, 0 ),
+    /*  SWAP      */  PACK( 2, 2 ),
+    /*  DEPTH     */  PACK( 0, 1 ),
+    /*  CINDEX    */  PACK( 1, 1 ),
+    /*  MINDEX    */  PACK( 1, 0 ),
+    /*  AlignPTS  */  PACK( 2, 0 ),
+    /*  INS_$28   */  PACK( 0, 0 ),
+    /*  UTP       */  PACK( 1, 0 ),
+    /*  LOOPCALL  */  PACK( 2, 0 ),
+    /*  CALL      */  PACK( 1, 0 ),
+    /*  FDEF      */  PACK( 1, 0 ),
+    /*  ENDF      */  PACK( 0, 0 ),
+    /*  MDAP[0]   */  PACK( 1, 0 ),
+    /*  MDAP[1]   */  PACK( 1, 0 ),
+
+    /*  IUP[0]    */  PACK( 0, 0 ),
+    /*  IUP[1]    */  PACK( 0, 0 ),
+    /*  SHP[0]    */  PACK( 0, 0 ),
+    /*  SHP[1]    */  PACK( 0, 0 ),
+    /*  SHC[0]    */  PACK( 1, 0 ),
+    /*  SHC[1]    */  PACK( 1, 0 ),
+    /*  SHZ[0]    */  PACK( 1, 0 ),
+    /*  SHZ[1]    */  PACK( 1, 0 ),
+    /*  SHPIX     */  PACK( 1, 0 ),
+    /*  IP        */  PACK( 0, 0 ),
+    /*  MSIRP[0]  */  PACK( 2, 0 ),
+    /*  MSIRP[1]  */  PACK( 2, 0 ),
+    /*  AlignRP   */  PACK( 0, 0 ),
+    /*  RTDG      */  PACK( 0, 0 ),
+    /*  MIAP[0]   */  PACK( 2, 0 ),
+    /*  MIAP[1]   */  PACK( 2, 0 ),
+
+    /*  NPushB    */  PACK( 0, 0 ),
+    /*  NPushW    */  PACK( 0, 0 ),
+    /*  WS        */  PACK( 2, 0 ),
+    /*  RS        */  PACK( 1, 1 ),
+    /*  WCvtP     */  PACK( 2, 0 ),
+    /*  RCvt      */  PACK( 1, 1 ),
+    /*  GC[0]     */  PACK( 1, 1 ),
+    /*  GC[1]     */  PACK( 1, 1 ),
+    /*  SCFS      */  PACK( 2, 0 ),
+    /*  MD[0]     */  PACK( 2, 1 ),
+    /*  MD[1]     */  PACK( 2, 1 ),
+    /*  MPPEM     */  PACK( 0, 1 ),
+    /*  MPS       */  PACK( 0, 1 ),
+    /*  FlipON    */  PACK( 0, 0 ),
+    /*  FlipOFF   */  PACK( 0, 0 ),
+    /*  DEBUG     */  PACK( 1, 0 ),
+
+    /*  LT        */  PACK( 2, 1 ),
+    /*  LTEQ      */  PACK( 2, 1 ),
+    /*  GT        */  PACK( 2, 1 ),
+    /*  GTEQ      */  PACK( 2, 1 ),
+    /*  EQ        */  PACK( 2, 1 ),
+    /*  NEQ       */  PACK( 2, 1 ),
+    /*  ODD       */  PACK( 1, 1 ),
+    /*  EVEN      */  PACK( 1, 1 ),
+    /*  IF        */  PACK( 1, 0 ),
+    /*  EIF       */  PACK( 0, 0 ),
+    /*  AND       */  PACK( 2, 1 ),
+    /*  OR        */  PACK( 2, 1 ),
+    /*  NOT       */  PACK( 1, 1 ),
+    /*  DeltaP1   */  PACK( 1, 0 ),
+    /*  SDB       */  PACK( 1, 0 ),
+    /*  SDS       */  PACK( 1, 0 ),
+
+    /*  ADD       */  PACK( 2, 1 ),
+    /*  SUB       */  PACK( 2, 1 ),
+    /*  DIV       */  PACK( 2, 1 ),
+    /*  MUL       */  PACK( 2, 1 ),
+    /*  ABS       */  PACK( 1, 1 ),
+    /*  NEG       */  PACK( 1, 1 ),
+    /*  FLOOR     */  PACK( 1, 1 ),
+    /*  CEILING   */  PACK( 1, 1 ),
+    /*  ROUND[0]  */  PACK( 1, 1 ),
+    /*  ROUND[1]  */  PACK( 1, 1 ),
+    /*  ROUND[2]  */  PACK( 1, 1 ),
+    /*  ROUND[3]  */  PACK( 1, 1 ),
+    /*  NROUND[0] */  PACK( 1, 1 ),
+    /*  NROUND[1] */  PACK( 1, 1 ),
+    /*  NROUND[2] */  PACK( 1, 1 ),
+    /*  NROUND[3] */  PACK( 1, 1 ),
+
+    /*  WCvtF     */  PACK( 2, 0 ),
+    /*  DeltaP2   */  PACK( 1, 0 ),
+    /*  DeltaP3   */  PACK( 1, 0 ),
+    /*  DeltaCn[0] */ PACK( 1, 0 ),
+    /*  DeltaCn[1] */ PACK( 1, 0 ),
+    /*  DeltaCn[2] */ PACK( 1, 0 ),
+    /*  SROUND    */  PACK( 1, 0 ),
+    /*  S45Round  */  PACK( 1, 0 ),
+    /*  JROT      */  PACK( 2, 0 ),
+    /*  JROF      */  PACK( 2, 0 ),
+    /*  ROFF      */  PACK( 0, 0 ),
+    /*  INS_$7B   */  PACK( 0, 0 ),
+    /*  RUTG      */  PACK( 0, 0 ),
+    /*  RDTG      */  PACK( 0, 0 ),
+    /*  SANGW     */  PACK( 1, 0 ),
+    /*  AA        */  PACK( 1, 0 ),
+
+    /*  FlipPT    */  PACK( 0, 0 ),
+    /*  FlipRgON  */  PACK( 2, 0 ),
+    /*  FlipRgOFF */  PACK( 2, 0 ),
+    /*  INS_$83   */  PACK( 0, 0 ),
+    /*  INS_$84   */  PACK( 0, 0 ),
+    /*  ScanCTRL  */  PACK( 1, 0 ),
+    /*  SDVPTL[0] */  PACK( 2, 0 ),
+    /*  SDVPTL[1] */  PACK( 2, 0 ),
+    /*  GetINFO   */  PACK( 1, 1 ),
+    /*  IDEF      */  PACK( 1, 0 ),
+    /*  ROLL      */  PACK( 3, 3 ),
+    /*  MAX       */  PACK( 2, 1 ),
+    /*  MIN       */  PACK( 2, 1 ),
+    /*  ScanTYPE  */  PACK( 1, 0 ),
+    /*  InstCTRL  */  PACK( 2, 0 ),
+    /*  INS_$8F   */  PACK( 0, 0 ),
+
+    /*  INS_$90  */   PACK( 0, 0 ),
+    /*  INS_$91  */   PACK( 0, 0 ),
+    /*  INS_$92  */   PACK( 0, 0 ),
+    /*  INS_$93  */   PACK( 0, 0 ),
+    /*  INS_$94  */   PACK( 0, 0 ),
+    /*  INS_$95  */   PACK( 0, 0 ),
+    /*  INS_$96  */   PACK( 0, 0 ),
+    /*  INS_$97  */   PACK( 0, 0 ),
+    /*  INS_$98  */   PACK( 0, 0 ),
+    /*  INS_$99  */   PACK( 0, 0 ),
+    /*  INS_$9A  */   PACK( 0, 0 ),
+    /*  INS_$9B  */   PACK( 0, 0 ),
+    /*  INS_$9C  */   PACK( 0, 0 ),
+    /*  INS_$9D  */   PACK( 0, 0 ),
+    /*  INS_$9E  */   PACK( 0, 0 ),
+    /*  INS_$9F  */   PACK( 0, 0 ),
+
+    /*  INS_$A0  */   PACK( 0, 0 ),
+    /*  INS_$A1  */   PACK( 0, 0 ),
+    /*  INS_$A2  */   PACK( 0, 0 ),
+    /*  INS_$A3  */   PACK( 0, 0 ),
+    /*  INS_$A4  */   PACK( 0, 0 ),
+    /*  INS_$A5  */   PACK( 0, 0 ),
+    /*  INS_$A6  */   PACK( 0, 0 ),
+    /*  INS_$A7  */   PACK( 0, 0 ),
+    /*  INS_$A8  */   PACK( 0, 0 ),
+    /*  INS_$A9  */   PACK( 0, 0 ),
+    /*  INS_$AA  */   PACK( 0, 0 ),
+    /*  INS_$AB  */   PACK( 0, 0 ),
+    /*  INS_$AC  */   PACK( 0, 0 ),
+    /*  INS_$AD  */   PACK( 0, 0 ),
+    /*  INS_$AE  */   PACK( 0, 0 ),
+    /*  INS_$AF  */   PACK( 0, 0 ),
+
+    /*  PushB[0]  */  PACK( 0, 1 ),
+    /*  PushB[1]  */  PACK( 0, 2 ),
+    /*  PushB[2]  */  PACK( 0, 3 ),
+    /*  PushB[3]  */  PACK( 0, 4 ),
+    /*  PushB[4]  */  PACK( 0, 5 ),
+    /*  PushB[5]  */  PACK( 0, 6 ),
+    /*  PushB[6]  */  PACK( 0, 7 ),
+    /*  PushB[7]  */  PACK( 0, 8 ),
+    /*  PushW[0]  */  PACK( 0, 1 ),
+    /*  PushW[1]  */  PACK( 0, 2 ),
+    /*  PushW[2]  */  PACK( 0, 3 ),
+    /*  PushW[3]  */  PACK( 0, 4 ),
+    /*  PushW[4]  */  PACK( 0, 5 ),
+    /*  PushW[5]  */  PACK( 0, 6 ),
+    /*  PushW[6]  */  PACK( 0, 7 ),
+    /*  PushW[7]  */  PACK( 0, 8 ),
+
+    /*  MDRP[00]  */  PACK( 1, 0 ),
+    /*  MDRP[01]  */  PACK( 1, 0 ),
+    /*  MDRP[02]  */  PACK( 1, 0 ),
+    /*  MDRP[03]  */  PACK( 1, 0 ),
+    /*  MDRP[04]  */  PACK( 1, 0 ),
+    /*  MDRP[05]  */  PACK( 1, 0 ),
+    /*  MDRP[06]  */  PACK( 1, 0 ),
+    /*  MDRP[07]  */  PACK( 1, 0 ),
+    /*  MDRP[08]  */  PACK( 1, 0 ),
+    /*  MDRP[09]  */  PACK( 1, 0 ),
+    /*  MDRP[10]  */  PACK( 1, 0 ),
+    /*  MDRP[11]  */  PACK( 1, 0 ),
+    /*  MDRP[12]  */  PACK( 1, 0 ),
+    /*  MDRP[13]  */  PACK( 1, 0 ),
+    /*  MDRP[14]  */  PACK( 1, 0 ),
+    /*  MDRP[15]  */  PACK( 1, 0 ),
+
+    /*  MDRP[16]  */  PACK( 1, 0 ),
+    /*  MDRP[17]  */  PACK( 1, 0 ),
+    /*  MDRP[18]  */  PACK( 1, 0 ),
+    /*  MDRP[19]  */  PACK( 1, 0 ),
+    /*  MDRP[20]  */  PACK( 1, 0 ),
+    /*  MDRP[21]  */  PACK( 1, 0 ),
+    /*  MDRP[22]  */  PACK( 1, 0 ),
+    /*  MDRP[23]  */  PACK( 1, 0 ),
+    /*  MDRP[24]  */  PACK( 1, 0 ),
+    /*  MDRP[25]  */  PACK( 1, 0 ),
+    /*  MDRP[26]  */  PACK( 1, 0 ),
+    /*  MDRP[27]  */  PACK( 1, 0 ),
+    /*  MDRP[28]  */  PACK( 1, 0 ),
+    /*  MDRP[29]  */  PACK( 1, 0 ),
+    /*  MDRP[30]  */  PACK( 1, 0 ),
+    /*  MDRP[31]  */  PACK( 1, 0 ),
+
+    /*  MIRP[00]  */  PACK( 2, 0 ),
+    /*  MIRP[01]  */  PACK( 2, 0 ),
+    /*  MIRP[02]  */  PACK( 2, 0 ),
+    /*  MIRP[03]  */  PACK( 2, 0 ),
+    /*  MIRP[04]  */  PACK( 2, 0 ),
+    /*  MIRP[05]  */  PACK( 2, 0 ),
+    /*  MIRP[06]  */  PACK( 2, 0 ),
+    /*  MIRP[07]  */  PACK( 2, 0 ),
+    /*  MIRP[08]  */  PACK( 2, 0 ),
+    /*  MIRP[09]  */  PACK( 2, 0 ),
+    /*  MIRP[10]  */  PACK( 2, 0 ),
+    /*  MIRP[11]  */  PACK( 2, 0 ),
+    /*  MIRP[12]  */  PACK( 2, 0 ),
+    /*  MIRP[13]  */  PACK( 2, 0 ),
+    /*  MIRP[14]  */  PACK( 2, 0 ),
+    /*  MIRP[15]  */  PACK( 2, 0 ),
+
+    /*  MIRP[16]  */  PACK( 2, 0 ),
+    /*  MIRP[17]  */  PACK( 2, 0 ),
+    /*  MIRP[18]  */  PACK( 2, 0 ),
+    /*  MIRP[19]  */  PACK( 2, 0 ),
+    /*  MIRP[20]  */  PACK( 2, 0 ),
+    /*  MIRP[21]  */  PACK( 2, 0 ),
+    /*  MIRP[22]  */  PACK( 2, 0 ),
+    /*  MIRP[23]  */  PACK( 2, 0 ),
+    /*  MIRP[24]  */  PACK( 2, 0 ),
+    /*  MIRP[25]  */  PACK( 2, 0 ),
+    /*  MIRP[26]  */  PACK( 2, 0 ),
+    /*  MIRP[27]  */  PACK( 2, 0 ),
+    /*  MIRP[28]  */  PACK( 2, 0 ),
+    /*  MIRP[29]  */  PACK( 2, 0 ),
+    /*  MIRP[30]  */  PACK( 2, 0 ),
+    /*  MIRP[31]  */  PACK( 2, 0 )
+  };
+
+
+  static
+  const TT_Char  opcode_length[256] =
+  {
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+
+   -1,-1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    2, 3, 4, 5,  6, 7, 8, 9,  3, 5, 7, 9, 11,13,15,17,
+
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,
+    1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1
+  };
+
+  static
+  const TT_Vector  Null_Vector = {0,0};
+
+
+#undef  PACK
+
+
+#undef  NULL_Vector
+#define NULL_Vector (TT_Vector*)&Null_Vector
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Current_Ratio                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns the current aspect ratio scaling factor depending on the   */
+  /*    projection vector's state and device resolutions.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The aspect ratio in 16.16 format, always <= 1.0 .                  */
+  /*                                                                       */
+  static
+  TT_Long  Current_Ratio( EXEC_OP )
+  {
+    if ( CUR.tt_metrics.ratio )
+      return CUR.tt_metrics.ratio;
+
+    if ( CUR.GS.projVector.y == 0 )
+      CUR.tt_metrics.ratio = CUR.tt_metrics.x_ratio;
+
+    else if ( CUR.GS.projVector.x == 0 )
+      CUR.tt_metrics.ratio = CUR.tt_metrics.y_ratio;
+
+    else
+    {
+      TT_Long  x, y;
+#if 0
+      x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x4000 );
+      y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x4000 );
+      CUR.tt_metrics.ratio = Norm( x, y );
+#else
+      x = TT_MULDIV( CUR.GS.projVector.x, CUR.tt_metrics.x_ratio, 0x8000 );
+      y = TT_MULDIV( CUR.GS.projVector.y, CUR.tt_metrics.y_ratio, 0x8000 );
+      CUR.tt_metrics.ratio = FT_Sqrt32( x*x+y*y ) << 1;
+#endif
+    }
+
+    return CUR.tt_metrics.ratio;
+  }
+
+
+  static
+  TT_Long  Current_Ppem( EXEC_OP )
+  {
+    return TT_MULFIX( CUR.tt_metrics.ppem, CURRENT_Ratio() );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Functions related to the control value table (CVT).                   */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  static
+  TT_F26Dot6  Read_CVT( EXEC_OP_ TT_ULong  index )
+  {
+    return CUR.cvt[index];
+  }
+
+
+  static
+  TT_F26Dot6  Read_CVT_Stretched( EXEC_OP_ TT_ULong  index )
+  {
+    return TT_MULFIX( CUR.cvt[index], CURRENT_Ratio() );
+  }
+
+
+  static
+  void  Write_CVT( EXEC_OP_ TT_ULong    index,
+                            TT_F26Dot6  value )
+  {
+    CUR.cvt[index] = value;
+  }
+
+  static
+  void  Write_CVT_Stretched( EXEC_OP_ TT_ULong    index,
+                                      TT_F26Dot6  value )
+  {
+    CUR.cvt[index] = FT_DivFix( value, CURRENT_Ratio() );
+  }
+
+
+  static
+  void  Move_CVT( EXEC_OP_ TT_ULong    index,
+                           TT_F26Dot6  value )
+  {
+    CUR.cvt[index] += value;
+  }
+
+
+  static
+  void  Move_CVT_Stretched( EXEC_OP_ TT_ULong    index,
+                                     TT_F26Dot6  value )
+  {
+    CUR.cvt[index] += FT_DivFix( value, CURRENT_Ratio() );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    GetShortIns                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns a short integer taken from the instruction stream at       */
+  /*    address IP.                                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Short read at code[IP].                                            */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This one could become a macro.                                     */
+  /*                                                                       */
+  static TT_Short  GetShortIns( EXEC_OP )
+  {
+    /* Reading a byte stream so there is no endianess (DaveP) */
+    CUR.IP += 2;
+    return (TT_Short)((CUR.code[CUR.IP - 2] << 8) + CUR.code[CUR.IP - 1]);
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Ins_Goto_CodeRange                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Goes to a certain code range in the instruction stream.            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    aRange :: The index of the code range.                             */
+  /*                                                                       */
+  /*    aIP    :: The new IP address in the code range.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS or FAILURE.                                                */
+  /*                                                                       */
+  static
+  TT_Bool  Ins_Goto_CodeRange( EXEC_OP_ TT_Int    aRange,
+                                        TT_ULong  aIP )
+  {
+    TT_CodeRange*  range;
+
+
+    if ( aRange < 1 || aRange > 3 )
+    {
+      CUR.error = TT_Err_Bad_Argument;
+      return FAILURE;
+    }
+
+    range = &CUR.codeRangeTable[aRange - 1];
+
+    if ( range->base == NULL )     /* invalid coderange */
+    {
+      CUR.error = TT_Err_Invalid_CodeRange;
+      return FAILURE;
+    }
+
+    /* NOTE: Because the last instruction of a program may be a CALL */
+    /*       which will return to the first byte *after* the code    */
+    /*       range, we test for AIP <= Size, instead of AIP < Size.  */
+
+    if ( aIP > range->size )
+    {
+      CUR.error = TT_Err_Code_Overflow;
+      return FAILURE;
+    }
+
+    CUR.code     = range->base;
+    CUR.codeSize = range->size;
+    CUR.IP       = aIP;
+    CUR.curRange = aRange;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Direct_Move                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Moves a point by a given distance along the freedom vector.  The   */
+  /*    point will be `touched'.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    point    :: The index of the point to move.                        */
+  /*    distance :: The distance to apply.                                 */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    zone     :: The affected glyph zone.                               */
+  /*                                                                       */
+  static
+  void  Direct_Move( EXEC_OP_ TT_GlyphZone*  zone,
+                              TT_UShort      point,
+                              TT_F26Dot6     distance )
+  {
+    TT_F26Dot6 v;
+
+
+    v = CUR.GS.freeVector.x;
+
+    if ( v != 0 )
+    {
+      zone->cur[point].x += TT_MULDIV( distance,
+                                       v * 0x10000L,
+                                       CUR.F_dot_P );
+
+      zone->touch[point] |= FT_Curve_Tag_Touch_X;
+    }
+
+    v = CUR.GS.freeVector.y;
+
+    if ( v != 0 )
+    {
+      zone->cur[point].y += TT_MULDIV( distance,
+                                       v * 0x10000L,
+                                       CUR.F_dot_P );
+
+      zone->touch[point] |= FT_Curve_Tag_Touch_Y;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Special versions of Direct_Move()                                     */
+  /*                                                                       */
+  /*   The following versions are used whenever both vectors are both      */
+  /*   along one of the coordinate unit vectors, i.e. in 90% cases.        */
+  /*                                                                       */
+  /*************************************************************************/
+
+  static
+  void  Direct_Move_X( EXEC_OP_ TT_GlyphZone*  zone,
+                                TT_UShort      point,
+                                TT_F26Dot6     distance )
+  {
+    UNUSED_EXEC;
+
+    zone->cur[point].x += distance;
+    zone->touch[point] |= FT_Curve_Tag_Touch_X;
+  }
+
+
+  static
+  void  Direct_Move_Y( EXEC_OP_ TT_GlyphZone*  zone,
+                                TT_UShort      point,
+                                TT_F26Dot6     distance )
+  {
+    UNUSED_EXEC;
+
+    zone->cur[point].y += distance;
+    zone->touch[point] |= FT_Curve_Tag_Touch_Y;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Round_None                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Does not round, but adds engine compensation.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    distance     :: The distance (not) to round.                       */
+  /*    compensation :: The engine compensation.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The compensated distance.                                          */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The TrueType specification says very few about the relationship    */
+  /*    between rounding and engine compensation.  However, it seems from  */
+  /*    the description of super round that we should add the compensation */
+  /*    before rounding.                                                   */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Round_None( EXEC_OP_ TT_F26Dot6  distance,
+                                   TT_F26Dot6  compensation )
+  {
+    TT_F26Dot6  val;
+
+
+    UNUSED_EXEC;
+
+    if ( distance >= 0 )
+    {
+      val = distance + compensation;
+      if ( val < 0 )
+        val = 0;
+    }
+    else {
+      val = distance - compensation;
+      if ( val > 0 )
+        val = 0;
+    }
+    return val;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Round_To_Grid                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Rounds value to grid after adding engine compensation.             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    distance     :: The distance to round.                             */
+  /*    compensation :: The engine compensation.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Rounded distance.                                                  */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Round_To_Grid( EXEC_OP_ TT_F26Dot6  distance,
+                                      TT_F26Dot6  compensation )
+  {
+    TT_F26Dot6  val;
+
+
+    UNUSED_EXEC;
+
+    if ( distance >= 0 )
+    {
+      val = distance + compensation + 32;
+      if ( val > 0 )
+        val &= ~63;
+      else
+        val = 0;
+    }
+    else
+    {
+      val = -( (compensation - distance + 32) & (-64) );
+      if ( val > 0 )
+        val = 0;
+    }
+    return  val;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Round_To_Half_Grid                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Rounds value to half grid after adding engine compensation.        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    distance     :: The distance to round.                             */
+  /*    compensation :: The engine compensation.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Rounded distance.                                                  */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Round_To_Half_Grid( EXEC_OP_ TT_F26Dot6  distance,
+                                           TT_F26Dot6  compensation )
+  {
+    TT_F26Dot6  val;
+
+ 
+   UNUSED_EXEC;
+
+    if ( distance >= 0 )
+    {
+      val = ((distance + compensation) & (-64)) + 32;
+      if ( val < 0 )
+        val = 0;
+    }
+    else
+    {
+      val = -( ((compensation - distance) & (-64)) + 32 );
+      if ( val > 0 )
+        val = 0;
+    }
+    return val;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Round_Down_To_Grid                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Rounds value down to grid after adding engine compensation.        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    distance     :: The distance to round.                             */
+  /*    compensation :: The engine compensation.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Rounded distance.                                                  */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Round_Down_To_Grid( EXEC_OP_ TT_F26Dot6  distance,
+                                           TT_F26Dot6  compensation )
+  {
+    TT_F26Dot6  val;
+
+
+    UNUSED_EXEC;
+
+    if ( distance >= 0 )
+    {
+      val = distance + compensation;
+      if ( val > 0 )
+        val &= ~63;
+      else
+        val = 0;
+    }
+    else
+    {
+      val = -( (compensation - distance) & (-64) );
+      if ( val > 0 )
+        val = 0;
+    }
+    return val;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Round_Up_To_Grid                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Rounds value up to grid after adding engine compensation.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    distance     :: The distance to round.                             */
+  /*    compensation :: The engine compensation.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Rounded distance.                                                  */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Round_Up_To_Grid( EXEC_OP_ TT_F26Dot6  distance,
+                                         TT_F26Dot6  compensation )
+  {
+    TT_F26Dot6  val;
+
+
+    UNUSED_EXEC;
+
+    if ( distance >= 0 )
+    {
+      val = distance + compensation + 63;
+      if ( val > 0 )
+        val &= ~63;
+      else
+        val = 0;
+    }
+    else
+    {
+      val = -( (compensation - distance + 63) & (-64) );
+      if ( val > 0 )
+        val = 0;
+    }
+    return val;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Round_To_Double_Grid                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Rounds value to double grid after adding engine compensation.      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    distance     :: The distance to round.                             */
+  /*    compensation :: The engine compensation.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Rounded distance.                                                  */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Round_To_Double_Grid( EXEC_OP_ TT_F26Dot6  distance,
+                                             TT_F26Dot6  compensation )
+  {
+    TT_F26Dot6 val;
+
+    UNUSED_EXEC;
+
+    if ( distance >= 0 )
+    {
+      val = distance + compensation + 16;
+      if ( val > 0 )
+        val &= ~31;
+      else
+        val = 0;
+    }
+    else
+    {
+      val = -( (compensation - distance + 16) & (-32) );
+      if ( val > 0 )
+        val = 0;
+    }
+    return val;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Round_Super                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Super-rounds value to grid after adding engine compensation.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    distance     :: The distance to round.                             */
+  /*    compensation :: The engine compensation.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Rounded distance.                                                  */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The TrueType specification says very few about the relationship    */
+  /*    between rounding and engine compensation.  However, it seems from  */
+  /*    the description of super round that we should add the compensation */
+  /*    before rounding.                                                   */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Round_Super( EXEC_OP_ TT_F26Dot6  distance,
+                                    TT_F26Dot6  compensation )
+  {
+    TT_F26Dot6  val;
+
+
+    if ( distance >= 0 )
+    {
+      val = (distance - CUR.phase + CUR.threshold + compensation) &
+              (-CUR.period);
+      if ( val < 0 )
+        val = 0;
+      val += CUR.phase;
+    }
+    else
+    {
+      val = -( (CUR.threshold - CUR.phase - distance + compensation) &
+               (-CUR.period) );
+      if ( val > 0 )
+        val = 0;
+      val -= CUR.phase;
+    }
+    return val;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Round_Super_45                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Super-rounds value to grid after adding engine compensation.       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    distance     :: The distance to round.                             */
+  /*    compensation :: The engine compensation.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Rounded distance.                                                  */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    There is a separate function for Round_Super_45() as we may need   */
+  /*    greater precision.                                                 */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Round_Super_45( EXEC_OP_ TT_F26Dot6  distance,
+                                       TT_F26Dot6  compensation )
+  {
+    TT_F26Dot6  val;
+
+
+    if ( distance >= 0 )
+    {
+      val = ( (distance - CUR.phase + CUR.threshold + compensation) /
+                CUR.period ) * CUR.period;
+      if ( val < 0 )
+        val = 0;
+      val += CUR.phase;
+    }
+    else
+    {
+      val = -( ( (CUR.threshold - CUR.phase - distance + compensation) /
+                   CUR.period ) * CUR.period );
+      if ( val > 0 )
+        val = 0;
+      val -= CUR.phase;
+    }
+
+    return val;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Compute_Round                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets the rounding mode.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    round_mode :: The rounding mode to be used.                        */
+  /*                                                                       */
+  static
+  void  Compute_Round( EXEC_OP_ TT_Byte  round_mode )
+  {
+    switch ( round_mode )
+    {
+    case TT_Round_Off:
+      CUR.func_round = (TT_Round_Func)Round_None;
+      break;
+
+    case TT_Round_To_Grid:
+      CUR.func_round = (TT_Round_Func)Round_To_Grid;
+      break;
+
+    case TT_Round_Up_To_Grid:
+      CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
+      break;
+
+    case TT_Round_Down_To_Grid:
+      CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
+      break;
+
+    case TT_Round_To_Half_Grid:
+      CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
+      break;
+
+    case TT_Round_To_Double_Grid:
+      CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
+      break;
+
+    case TT_Round_Super:
+      CUR.func_round = (TT_Round_Func)Round_Super;
+      break;
+
+    case TT_Round_Super_45:
+      CUR.func_round = (TT_Round_Func)Round_Super_45;
+      break;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    SetSuperRound                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets Super Round parameters.                                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    GridPeriod :: Grid period                                          */
+  /*    selector   :: SROUND opcode                                        */
+  /*                                                                       */
+  static
+  void  SetSuperRound( EXEC_OP_ TT_F26Dot6  GridPeriod,
+                                TT_Long     selector )
+  {
+    switch ( (TT_Int)(selector & 0xC0) )
+    {
+      case 0:
+        CUR.period = GridPeriod / 2;
+        break;
+
+      case 0x40:
+        CUR.period = GridPeriod;
+        break;
+
+      case 0x80:
+        CUR.period = GridPeriod * 2;
+        break;
+
+      /* This opcode is reserved, but... */
+
+      case 0xC0:
+        CUR.period = GridPeriod;
+        break;
+    }
+
+    switch ( (TT_Int)(selector & 0x30) )
+    {
+    case 0:
+      CUR.phase = 0;
+      break;
+
+    case 0x10:
+      CUR.phase = CUR.period / 4;
+      break;
+
+    case 0x20:
+      CUR.phase = CUR.period / 2;
+      break;
+
+    case 0x30:
+      CUR.phase = GridPeriod * 3 / 4;
+      break;
+    }
+
+    if ( (selector & 0x0F) == 0 )
+      CUR.threshold = CUR.period - 1;
+    else
+      CUR.threshold = ( (TT_Int)(selector & 0x0F) - 4 ) * CUR.period / 8;
+
+    CUR.period    /= 256;
+    CUR.phase     /= 256;
+    CUR.threshold /= 256;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Project                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the projection of vector given by (v2-v1) along the       */
+  /*    current projection vector.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    v1 :: First input vector.                                          */
+  /*    v2 :: Second input vector.                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The distance in F26dot6 format.                                    */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Project( EXEC_OP_ TT_Vector*  v1,
+                                TT_Vector*  v2 )
+  {
+    return TT_MULDIV( v1->x - v2->x, CUR.GS.projVector.x, 0x4000 ) +
+           TT_MULDIV( v1->y - v2->y, CUR.GS.projVector.y, 0x4000 );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Dual_Project                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the projection of the vector given by (v2-v1) along the   */
+  /*    current dual vector.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    v1 :: First input vector.                                          */
+  /*    v2 :: Second input vector.                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The distance in F26dot6 format.                                    */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Dual_Project( EXEC_OP_ TT_Vector*  v1,
+                                     TT_Vector*  v2 )
+  {
+    return TT_MULDIV( v1->x - v2->x, CUR.GS.dualVector.x, 0x4000 ) +
+           TT_MULDIV( v1->y - v2->y, CUR.GS.dualVector.y, 0x4000 );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Free_Project                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the projection of the vector given by (v2-v1) along the   */
+  /*    current freedom vector.                                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    v1 :: First input vector.                                          */
+  /*    v2 :: Second input vector.                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The distance in F26dot6 format.                                    */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Free_Project( EXEC_OP_ TT_Vector*  v1,
+                                     TT_Vector*  v2 )
+  {
+    return TT_MULDIV( v1->x - v2->x, CUR.GS.freeVector.x, 0x4000 ) +
+           TT_MULDIV( v1->y - v2->y, CUR.GS.freeVector.y, 0x4000 );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Project_x                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the projection of the vector given by (v2-v1) along the   */
+  /*    horizontal axis.                                                   */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    v1 :: First input vector.                                          */
+  /*    v2 :: Second input vector.                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The distance in F26dot6 format.                                    */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Project_x( EXEC_OP_ TT_Vector*  v1,
+                                  TT_Vector*  v2 )
+  {
+    UNUSED_EXEC;
+
+    return (v1->x - v2->x);
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Project_y                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the projection of the vector given by (v2-v1) along the   */
+  /*    vertical axis.                                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    v1 :: First input vector.                                          */
+  /*    v2 :: Second input vector.                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The distance in F26dot6 format.                                    */
+  /*                                                                       */
+  static
+  TT_F26Dot6  Project_y( EXEC_OP_ TT_Vector*  v1,
+                                  TT_Vector*  v2 )
+  {
+    UNUSED_EXEC;
+ 
+   return (v1->y - v2->y);
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Compute_Funcs                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the projection and movement function pointers according   */
+  /*    to the current graphics state.                                     */
+  /*                                                                       */
+  static
+  void  Compute_Funcs( EXEC_OP )
+  {
+    if ( CUR.GS.freeVector.x == 0x4000 )
+    {
+      CUR.func_freeProj = (TT_Project_Func)Project_x;
+      CUR.F_dot_P       = CUR.GS.projVector.x * 0x10000L;
+    }
+    else
+    {
+      if ( CUR.GS.freeVector.y == 0x4000 )
+      {
+        CUR.func_freeProj = (TT_Project_Func)Project_y;
+        CUR.F_dot_P       = CUR.GS.projVector.y * 0x10000L;
+      }
+      else
+      {
+        CUR.func_freeProj = (TT_Project_Func)Free_Project;
+        CUR.F_dot_P = (TT_Long)CUR.GS.projVector.x * CUR.GS.freeVector.x * 4 +
+                      (TT_Long)CUR.GS.projVector.y * CUR.GS.freeVector.y * 4;
+      }
+    }
+
+    if ( CUR.GS.projVector.x == 0x4000 )
+      CUR.func_project = (TT_Project_Func)Project_x;
+    else
+    {
+      if ( CUR.GS.projVector.y == 0x4000 )
+        CUR.func_project = (TT_Project_Func)Project_y;
+      else
+        CUR.func_project = (TT_Project_Func)Project;
+    }
+
+    if ( CUR.GS.dualVector.x == 0x4000 )
+      CUR.func_dualproj = (TT_Project_Func)Project_x;
+    else
+    {
+      if ( CUR.GS.dualVector.y == 0x4000 )
+        CUR.func_dualproj = (TT_Project_Func)Project_y;
+      else
+        CUR.func_dualproj = (TT_Project_Func)Dual_Project;
+    }
+
+    CUR.func_move = (TT_Move_Func)Direct_Move;
+
+    if ( CUR.F_dot_P == 0x40000000L )
+    {
+      if ( CUR.GS.freeVector.x == 0x4000 )
+        CUR.func_move = (TT_Move_Func)Direct_Move_X;
+      else
+      {
+        if ( CUR.GS.freeVector.y == 0x4000 )
+          CUR.func_move = (TT_Move_Func)Direct_Move_Y;
+      }
+    }
+
+    /* at small sizes, F_dot_P can become too small, resulting   */
+    /* in overflows and `spikes' in a number of glyphs like `w'. */
+
+    if ( ABS( CUR.F_dot_P ) < 0x4000000L )
+      CUR.F_dot_P = 0x40000000L;
+
+    /* Disable cached aspect ratio */
+    CUR.tt_metrics.ratio = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Normalize                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Norms a vector.                                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    Vx :: The horizontal input vector coordinate.                      */
+  /*    Vy :: The vertical input vector coordinate.                        */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    R  :: The normed unit vector.                                      */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Returns FAILURE if a vector parameter is zero.                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    In case Vx and Vy are both zero, Normalize() returns SUCCESS, and  */
+  /*    R is undefined.                                                    */
+  /*                                                                       */
+  static
+  TT_Bool  Normalize( EXEC_OP_ TT_F26Dot6      Vx,
+                               TT_F26Dot6      Vy,
+                               TT_UnitVector*  R )
+  {
+    TT_F26Dot6  u, v, d;
+    TT_Int      shift;
+    TT_ULong    H, L, L2, hi, lo, med;
+
+    u = ABS(Vx);
+    v = ABS(Vy);
+
+    if (u < v)
+    {
+      d = u;
+      u = v;
+      v = d;
+    }
+
+    R->x = 0;
+    R->y = 0;
+    
+    /* check that we're not trying to normalise zero !! */
+    if (u==0) return SUCCESS;
+
+    /* compute (u*u+v*v) on 64 bits with two 32-bit registers [H:L] */
+    hi  = (TT_ULong)u >> 16;
+    lo  = (TT_ULong)u & 0xFFFF;
+    med = hi*lo;
+    
+    H     = hi*hi + (med >> 15);
+    med <<= 17;
+    L     = lo*lo + med;
+    if (L < med) H++;
+    
+    hi  = (TT_ULong)v >> 16;
+    lo  = (TT_ULong)v & 0xFFFF;
+    med = hi*lo;
+    
+    H    += hi*hi + (med >> 15);
+    med <<= 17;
+    L2    = lo*lo + med;
+    if (L2 < med) H++;
+    
+    L += L2;
+    if (L < L2) H++;
+
+    /* if the value is smaller than 32-bits */
+    if (H == 0)
+    {
+      shift = 0;
+      while ((L & 0xC0000000) == 0)
+      {
+        L <<= 2;
+        shift++;
+      }
+      
+      d = FT_Sqrt32(L);
+      R->x = (TT_F2Dot14)TT_MULDIV( Vx << shift, 0x4000, d );
+      R->y = (TT_F2Dot14)TT_MULDIV( Vy << shift, 0x4000, d );
+    }
+    /* if the value is greater than 64-bits */
+    else
+    {
+      shift = 0;
+      while (H)
+      {
+        L   = (L >> 2) | (H << 30);
+        H >>= 2;
+        shift++;
+      }
+      
+      d = FT_Sqrt32(L);
+      R->x = (TT_F2Dot14)TT_MULDIV( Vx >> shift, 0x4000, d );
+      R->y = (TT_F2Dot14)TT_MULDIV( Vy >> shift, 0x4000, d );
+    }
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Here we start with the implementation of the various opcodes.         */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  static
+  TT_Bool  Ins_SxVTL( EXEC_OP_ TT_UShort       aIdx1,
+                               TT_UShort       aIdx2,
+                               TT_Int          aOpc,
+                               TT_UnitVector*  Vec )
+  {
+    TT_Long     A, B, C;
+    TT_Vector*  p1;
+    TT_Vector*  p2;
+
+
+    if ( BOUNDS( aIdx1, CUR.zp2.n_points ) ||
+         BOUNDS( aIdx2, CUR.zp1.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return FAILURE;
+    }
+
+    p1 = CUR.zp1.cur + aIdx2;
+    p2 = CUR.zp2.cur + aIdx1;
+
+    A = p1->x - p2->x;
+    B = p1->y - p2->y;
+
+    if ( (aOpc & 1) != 0 )
+    {
+      C =  B;   /* CounterClockwise rotation */
+      B =  A;
+      A = -C;
+    }
+
+    NORMalize( A, B, Vec );
+
+    return SUCCESS;
+  }
+
+
+  /* When not using the big switch statements, the interpreter uses a */
+  /* call table defined later below in this source.  Each opcode must */
+  /* thus have a corresponding function, even trivial ones.           */
+  /*                                                                  */
+  /* They're all defined there.                                       */
+
+#define DO_SVTCA                          \
+  {                                       \
+    TT_Short  A, B;                       \
+                                          \
+                                          \
+    A = (TT_Short)(CUR.opcode & 1) << 14; \
+    B = A ^ (TT_Short)0x4000;             \
+                                          \
+    CUR.GS.freeVector.x = A;              \
+    CUR.GS.projVector.x = A;              \
+    CUR.GS.dualVector.x = A;              \
+                                          \
+    CUR.GS.freeVector.y = B;              \
+    CUR.GS.projVector.y = B;              \
+    CUR.GS.dualVector.y = B;              \
+                                          \
+    COMPUTE_Funcs();                      \
+  }
+
+
+#define DO_SPVTCA                         \
+  {                                       \
+    TT_Short  A, B;                       \
+                                          \
+                                          \
+    A = (TT_Short)(CUR.opcode & 1) << 14; \
+    B = A ^ (TT_Short)0x4000;             \
+                                          \
+    CUR.GS.projVector.x = A;              \
+    CUR.GS.dualVector.x = A;              \
+                                          \
+    CUR.GS.projVector.y = B;              \
+    CUR.GS.dualVector.y = B;              \
+                                          \
+    COMPUTE_Funcs();                      \
+  }
+
+
+#define DO_SFVTCA                         \
+  {                                       \
+    TT_Short  A, B;                       \
+                                          \
+                                          \
+    A = (TT_Short)(CUR.opcode & 1) << 14; \
+    B = A ^ (TT_Short)0x4000;             \
+                                          \
+    CUR.GS.freeVector.x = A;              \
+    CUR.GS.freeVector.y = B;              \
+                                          \
+    COMPUTE_Funcs();                      \
+  }
+
+
+#define DO_SPVTL                                     \
+    if ( INS_SxVTL( (TT_UShort)args[1],              \
+                    (TT_UShort)args[0],              \
+                    CUR.opcode,                      \
+                    &CUR.GS.projVector) == SUCCESS ) \
+    {                                                \
+      CUR.GS.dualVector = CUR.GS.projVector;         \
+      COMPUTE_Funcs();                               \
+    }
+
+
+#define DO_SFVTL                                     \
+    if ( INS_SxVTL( (TT_UShort)(args[1]),            \
+                    (TT_UShort)(args[0]),            \
+                    CUR.opcode,                      \
+                    &CUR.GS.freeVector) == SUCCESS ) \
+      COMPUTE_Funcs();
+
+
+#define DO_SFVTPV                          \
+    CUR.GS.freeVector = CUR.GS.projVector; \
+    COMPUTE_Funcs();
+
+
+#define DO_SPVFS                                \
+  {                                             \
+    TT_Short  S;                                \
+    TT_Long   X, Y;                             \
+                                                \
+                                                \
+    /* Only use low 16bits, then sign extend */ \
+    S = (TT_Short)args[1];                      \
+    Y = (TT_Long)S;                             \
+    S = (TT_Short)args[0];                      \
+    X = (TT_Long)S;                             \
+                                                \
+    NORMalize( X, Y, &CUR.GS.projVector );      \
+                                                \
+    CUR.GS.dualVector = CUR.GS.projVector;      \
+    COMPUTE_Funcs();                            \
+  }
+
+
+#define DO_SFVFS                                \
+  {                                             \
+    TT_Short  S;                                \
+    TT_Long   X, Y;                             \
+                                                \
+                                                \
+    /* Only use low 16bits, then sign extend */ \
+    S = (TT_Short)args[1];                      \
+    Y = (TT_Long)S;                             \
+    S = (TT_Short)args[0];                      \
+    X = S;                                      \
+                                                \
+    NORMalize( X, Y, &CUR.GS.freeVector );      \
+    COMPUTE_Funcs();                            \
+  }
+
+
+#define DO_GPV                     \
+    args[0] = CUR.GS.projVector.x; \
+    args[1] = CUR.GS.projVector.y;
+
+
+#define DO_GFV                     \
+    args[0] = CUR.GS.freeVector.x; \
+    args[1] = CUR.GS.freeVector.y;
+
+
+#define DO_SRP0                        \
+    CUR.GS.rp0 = (TT_UShort)(args[0]);
+
+
+#define DO_SRP1                        \
+    CUR.GS.rp1 = (TT_UShort)(args[0]);
+
+
+#define DO_SRP2                        \
+    CUR.GS.rp2 = (TT_UShort)(args[0]);
+
+
+#define DO_RTHG                                         \
+    CUR.GS.round_state = TT_Round_To_Half_Grid;         \
+    CUR.func_round = (TT_Round_Func)Round_To_Half_Grid;
+
+
+#define DO_RTG                                     \
+    CUR.GS.round_state = TT_Round_To_Grid;         \
+    CUR.func_round = (TT_Round_Func)Round_To_Grid;
+
+
+#define DO_RTDG                                           \
+    CUR.GS.round_state = TT_Round_To_Double_Grid;         \
+    CUR.func_round = (TT_Round_Func)Round_To_Double_Grid;
+
+
+#define DO_RUTG                                       \
+    CUR.GS.round_state = TT_Round_Up_To_Grid;         \
+    CUR.func_round = (TT_Round_Func)Round_Up_To_Grid;
+
+
+#define DO_RDTG                                         \
+    CUR.GS.round_state = TT_Round_Down_To_Grid;         \
+    CUR.func_round = (TT_Round_Func)Round_Down_To_Grid;
+
+
+#define DO_ROFF                                 \
+    CUR.GS.round_state = TT_Round_Off;          \
+    CUR.func_round = (TT_Round_Func)Round_None;
+
+
+#define DO_SROUND                                \
+    SET_SuperRound( 0x4000, args[0] );           \
+    CUR.GS.round_state = TT_Round_Super;         \
+    CUR.func_round = (TT_Round_Func)Round_Super;
+
+
+#define DO_S45ROUND                                 \
+    SET_SuperRound( 0x2D41, args[0] );              \
+    CUR.GS.round_state = TT_Round_Super_45;         \
+    CUR.func_round = (TT_Round_Func)Round_Super_45;
+
+
+#define DO_SLOOP                       \
+    if ( args[0] < 0 )                 \
+      CUR.error = TT_Err_Bad_Argument; \
+    else                               \
+      CUR.GS.loop = args[0];
+
+
+#define DO_SMD                         \
+    CUR.GS.minimum_distance = args[0];
+
+
+#define DO_SCVTCI                                     \
+    CUR.GS.control_value_cutin = (TT_F26Dot6)args[0];
+
+
+#define DO_SSWCI                                     \
+    CUR.GS.single_width_cutin = (TT_F26Dot6)args[0];
+
+
+    /* XXX: UNDOCUMENTED! or bug in the Windows engine? */
+    /*                                                  */
+    /* It seems that the value that is read here is     */
+    /* expressed in 16.16 format rather than in font    */
+    /* units..    .                                     */
+    /*                                                  */
+#define DO_SSW                                               \
+    CUR.GS.single_width_value = (TT_F26Dot6)(args[0] >> 10);
+
+
+#define DO_FLIPON            \
+    CUR.GS.auto_flip = TRUE;
+
+
+#define DO_FLIPOFF            \
+    CUR.GS.auto_flip = FALSE;
+
+
+#define DO_SDB                             \
+    CUR.GS.delta_base = (TT_Short)args[0];
+
+
+#define DO_SDS                              \
+    CUR.GS.delta_shift = (TT_Short)args[0];
+
+
+#define DO_MD  /* nothing */
+
+
+#define DO_MPPEM              \
+    args[0] = CURRENT_Ppem();
+
+
+/* Note: the pointSize should be irrelevant in a given font program */
+/*       we thus decide to return only the ppem                     */
+#if 0
+#define DO_MPS                       \
+    args[0] = CUR.metrics.pointSize;
+#else
+#define DO_MPS                       \
+    args[0] = CURRENT_Ppem();
+#endif
+
+#define DO_DUP         \
+    args[1] = args[0];
+
+
+#define DO_CLEAR     \
+    CUR.new_top = 0;
+
+
+#define DO_SWAP        \
+  {                    \
+    TT_Long  L;        \
+                       \
+    L       = args[0]; \
+    args[0] = args[1]; \
+    args[1] = L;       \
+  }
+
+
+#define DO_DEPTH       \
+    args[0] = CUR.top;
+
+
+#define DO_CINDEX                           \
+  {                                         \
+    TT_Long  L;                             \
+                                            \
+                                            \
+    L = args[0];                            \
+                                            \
+    if ( L <= 0 || L > CUR.args )           \
+      CUR.error = TT_Err_Invalid_Reference; \
+    else                                    \
+      args[0] = CUR.stack[CUR.args - L];    \
+  }
+
+
+#define DO_JROT               \
+    if ( args[1] != 0 )       \
+    {                         \
+      CUR.IP      += args[0]; \
+      CUR.step_ins = FALSE;   \
+    }
+
+
+#define DO_JMPR             \
+    CUR.IP      += args[0]; \
+    CUR.step_ins = FALSE;
+
+
+#define DO_JROF               \
+    if ( args[1] == 0 )       \
+    {                         \
+      CUR.IP      += args[0]; \
+      CUR.step_ins = FALSE;   \
+    }
+
+
+#define DO_LT                      \
+    args[0] = (args[0] < args[1]);
+
+
+#define DO_LTEQ                     \
+    args[0] = (args[0] <= args[1]);
+
+
+#define DO_GT                      \
+    args[0] = (args[0] > args[1]);
+
+
+#define DO_GTEQ                     \
+    args[0] = (args[0] >= args[1]);
+
+
+#define DO_EQ                       \
+    args[0] = (args[0] == args[1]);
+
+
+#define DO_NEQ                      \
+    args[0] = (args[0] != args[1]);
+
+
+#define DO_ODD                                                \
+    args[0] = ( (CUR_Func_round( args[0], 0 ) & 127) == 64 );
+
+
+#define DO_EVEN                                              \
+    args[0] = ( (CUR_Func_round( args[0], 0 ) & 127) == 0 );
+
+
+#define DO_AND                        \
+    args[0] = ( args[0] && args[1] );
+
+
+#define DO_OR                         \
+    args[0] = ( args[0] || args[1] );
+
+
+#define DO_NOT          \
+    args[0] = !args[0];
+
+
+#define DO_ADD          \
+    args[0] += args[1];
+
+
+#define DO_SUB          \
+    args[0] -= args[1];
+
+
+#define DO_DIV                                      \
+    if ( args[1] == 0 )                             \
+      CUR.error = TT_Err_Divide_By_Zero;            \
+    else                                            \
+      args[0] = TT_MULDIV( args[0], 64L, args[1] );
+
+
+#define DO_MUL                                    \
+    args[0] = TT_MULDIV( args[0], args[1], 64L );
+
+
+#define DO_ABS                \
+    args[0] = ABS( args[0] );
+
+
+#define DO_NEG          \
+    args[0] = -args[0];
+
+
+#define DO_FLOOR    \
+    args[0] &= -64;
+
+
+#define DO_CEILING                    \
+    args[0] = (args[0] + 63) & (-64);
+
+
+#define DO_RS                          \
+   {                                   \
+     TT_ULong  I = (TT_ULong)args[0];  \
+                                       \
+                                       \
+     if ( BOUNDS( I, CUR.storeSize ) ) \
+     {                                 \
+       if ( CUR.pedantic_hinting )     \
+       {                               \
+         ARRAY_BOUND_ERROR;            \
+       }                               \
+       else                            \
+         args[0] = 0;                  \
+     }                                 \
+     else                              \
+       args[0] = CUR.storage[I];       \
+   }
+
+
+#define DO_WS                          \
+   {                                   \
+     TT_ULong  I = (TT_ULong)args[0];  \
+                                       \
+                                       \
+     if ( BOUNDS( I, CUR.storeSize ) ) \
+     {                                 \
+       if ( CUR.pedantic_hinting )     \
+       {                               \
+         ARRAY_BOUND_ERROR;            \
+       }                               \
+     }                                 \
+     else                              \
+       CUR.storage[I] = args[1];       \
+   }
+
+
+#define DO_RCVT                        \
+   {                                   \
+     TT_ULong  I = (TT_ULong)args[0];  \
+                                       \
+                                       \
+     if ( BOUNDS( I, CUR.cvtSize ) )   \
+     {                                 \
+       if ( CUR.pedantic_hinting )     \
+       {                               \
+         ARRAY_BOUND_ERROR;            \
+       }                               \
+       else                            \
+         args[0] = 0;                  \
+     }                                 \
+     else                              \
+       args[0] = CUR_Func_read_cvt(I); \
+   }
+
+
+#define DO_WCVTP                         \
+   {                                     \
+     TT_ULong  I = (TT_ULong)args[0];    \
+                                         \
+                                         \
+     if ( BOUNDS( I, CUR.cvtSize ) )     \
+     {                                   \
+       if ( CUR.pedantic_hinting )       \
+       {                                 \
+         ARRAY_BOUND_ERROR;              \
+       }                                 \
+     }                                   \
+     else                                \
+       CUR_Func_write_cvt( I, args[1] ); \
+   }
+
+
+#define DO_WCVTF                                                \
+   {                                                            \
+     TT_ULong  I = (TT_ULong)args[0];                           \
+                                                                \
+                                                                \
+     if ( BOUNDS( I, CUR.cvtSize ) )                            \
+     {                                                          \
+       if ( CUR.pedantic_hinting )                              \
+       {                                                        \
+         ARRAY_BOUND_ERROR;                                     \
+       }                                                        \
+     }                                                          \
+     else                                                       \
+       CUR.cvt[I] = TT_MULFIX( args[1], CUR.tt_metrics.scale ); \
+   }
+
+
+#define DO_DEBUG                     \
+    CUR.error = TT_Err_Debug_OpCode;
+
+
+#define DO_ROUND                                                   \
+    args[0] = CUR_Func_round(                                      \
+                args[0],                                           \
+                CUR.tt_metrics.compensations[CUR.opcode - 0x68] );
+
+
+#define DO_NROUND                                                            \
+    args[0] = ROUND_None( args[0],                                           \
+                          CUR.tt_metrics.compensations[CUR.opcode - 0x6C] );
+
+
+#define DO_MAX               \
+    if ( args[1] > args[0] ) \
+      args[0] = args[1];
+
+
+#define DO_MIN               \
+    if ( args[1] < args[0] ) \
+      args[0] = args[1];
+
+
+#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
+
+
+#undef  ARRAY_BOUND_ERROR
+#define ARRAY_BOUND_ERROR                    \
+     {                                       \
+       CUR.error = TT_Err_Invalid_Reference; \
+       return;                               \
+     }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SVTCA[a]:     Set (F and P) Vectors to Coordinate Axis                */
+  /* Opcode range: 0x00-0x01                                               */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_SVTCA( INS_ARG )
+  {
+    DO_SVTCA
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SPVTCA[a]:    Set PVector to Coordinate Axis                          */
+  /* Opcode range: 0x02-0x03                                               */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_SPVTCA( INS_ARG )
+  {
+    DO_SPVTCA
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SFVTCA[a]:    Set FVector to Coordinate Axis                          */
+  /* Opcode range: 0x04-0x05                                               */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_SFVTCA( INS_ARG )
+  {
+    DO_SFVTCA
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SPVTL[a]:     Set PVector To Line                                     */
+  /* Opcode range: 0x06-0x07                                               */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_SPVTL( INS_ARG )
+  {
+    DO_SPVTL
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SFVTL[a]:     Set FVector To Line                                     */
+  /* Opcode range: 0x08-0x09                                               */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_SFVTL( INS_ARG )
+  {
+    DO_SFVTL
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SFVTPV[]:     Set FVector To PVector                                  */
+  /* Opcode range: 0x0E                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_SFVTPV( INS_ARG )
+  {
+    DO_SFVTPV
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SPVFS[]:      Set PVector From Stack                                  */
+  /* Opcode range: 0x0A                                                    */
+  /* Stack:        f2.14 f2.14 -->                                         */
+  /*                                                                       */
+  static
+  void  Ins_SPVFS( INS_ARG )
+  {
+    DO_SPVFS
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SFVFS[]:      Set FVector From Stack                                  */
+  /* Opcode range: 0x0B                                                    */
+  /* Stack:        f2.14 f2.14 -->                                         */
+  /*                                                                       */
+  static
+  void  Ins_SFVFS( INS_ARG )
+  {
+    DO_SFVFS
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GPV[]:        Get Projection Vector                                   */
+  /* Opcode range: 0x0C                                                    */
+  /* Stack:        ef2.14 --> ef2.14                                       */
+  /*                                                                       */
+  static
+  void  Ins_GPV( INS_ARG )
+  {
+    DO_GPV
+  }
+
+
+  /*************************************************************************/
+  /* GFV[]:        Get Freedom Vector                                      */
+  /* Opcode range: 0x0D                                                    */
+  /* Stack:        ef2.14 --> ef2.14                                       */
+  /*                                                                       */
+  static
+  void  Ins_GFV( INS_ARG )
+  {
+    DO_GFV
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SRP0[]:       Set Reference Point 0                                   */
+  /* Opcode range: 0x10                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SRP0( INS_ARG )
+  {
+    DO_SRP0
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SRP1[]:       Set Reference Point 1                                   */
+  /* Opcode range: 0x11                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SRP1( INS_ARG )
+  {
+    DO_SRP1
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SRP2[]:       Set Reference Point 2                                   */
+  /* Opcode range: 0x12                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SRP2( INS_ARG )
+  {
+    DO_SRP2
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* RTHG[]:       Round To Half Grid                                      */
+  /* Opcode range: 0x19                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_RTHG( INS_ARG )
+  {
+    DO_RTHG
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* RTG[]:        Round To Grid                                           */
+  /* Opcode range: 0x18                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_RTG( INS_ARG )
+  {
+    DO_RTG
+  }
+
+
+  /*************************************************************************/
+  /* RTDG[]:       Round To Double Grid                                    */
+  /* Opcode range: 0x3D                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_RTDG( INS_ARG )
+  {
+    DO_RTDG
+  }
+
+
+  /*************************************************************************/
+  /* RUTG[]:       Round Up To Grid                                        */
+  /* Opcode range: 0x7C                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_RUTG( INS_ARG )
+  {
+    DO_RUTG
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* RDTG[]:       Round Down To Grid                                      */
+  /* Opcode range: 0x7D                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_RDTG( INS_ARG )
+  {
+    DO_RDTG
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ROFF[]:       Round OFF                                               */
+  /* Opcode range: 0x7A                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_ROFF( INS_ARG )
+  {
+    DO_ROFF
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SROUND[]:     Super ROUND                                             */
+  /* Opcode range: 0x76                                                    */
+  /* Stack:        Eint8 -->                                               */
+  /*                                                                       */
+  static
+  void  Ins_SROUND( INS_ARG )
+  {
+    DO_SROUND
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* S45ROUND[]:   Super ROUND 45 degrees                                  */
+  /* Opcode range: 0x77                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_S45ROUND( INS_ARG )
+  {
+    DO_S45ROUND
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SLOOP[]:      Set LOOP variable                                       */
+  /* Opcode range: 0x17                                                    */
+  /* Stack:        int32? -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SLOOP( INS_ARG )
+  {
+    DO_SLOOP
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SMD[]:        Set Minimum Distance                                    */
+  /* Opcode range: 0x1A                                                    */
+  /* Stack:        f26.6 -->                                               */
+  /*                                                                       */
+  static
+  void  Ins_SMD( INS_ARG )
+  {
+    DO_SMD
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SCVTCI[]:     Set Control Value Table Cut In                          */
+  /* Opcode range: 0x1D                                                    */
+  /* Stack:        f26.6 -->                                               */
+  /*                                                                       */
+  static
+  void  Ins_SCVTCI( INS_ARG )
+  {
+    DO_SCVTCI
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SSWCI[]:      Set Single Width Cut In                                 */
+  /* Opcode range: 0x1E                                                    */
+  /* Stack:        f26.6 -->                                               */
+  /*                                                                       */
+  static
+  void  Ins_SSWCI( INS_ARG )
+  {
+    DO_SSWCI
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SSW[]:        Set Single Width                                        */
+  /* Opcode range: 0x1F                                                    */
+  /* Stack:        int32? -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SSW( INS_ARG )
+  {
+    DO_SSW
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FLIPON[]:     Set auto-FLIP to ON                                     */
+  /* Opcode range: 0x4D                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_FLIPON( INS_ARG )
+  {
+    DO_FLIPON
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FLIPOFF[]:    Set auto-FLIP to OFF                                    */
+  /* Opcode range: 0x4E                                                    */
+  /* Stack: -->                                                            */
+  /*                                                                       */
+  static
+  void  Ins_FLIPOFF( INS_ARG )
+  {
+    DO_FLIPOFF
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SANGW[]:      Set ANGle Weight                                        */
+  /* Opcode range: 0x7E                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SANGW( INS_ARG )
+  {
+    /* instruction not supported anymore */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SDB[]:        Set Delta Base                                          */
+  /* Opcode range: 0x5E                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SDB( INS_ARG )
+  {
+    DO_SDB
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SDS[]:        Set Delta Shift                                         */
+  /* Opcode range: 0x5F                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SDS( INS_ARG )
+  {
+    DO_SDS
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MPPEM[]:      Measure Pixel Per EM                                    */
+  /* Opcode range: 0x4B                                                    */
+  /* Stack:        --> Euint16                                             */
+  /*                                                                       */
+  static
+  void  Ins_MPPEM( INS_ARG )
+  {
+    DO_MPPEM
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MPS[]:        Measure Point Size                                      */
+  /* Opcode range: 0x4C                                                    */
+  /* Stack:        --> Euint16                                             */
+  /*                                                                       */
+  static
+  void  Ins_MPS( INS_ARG )
+  {
+    DO_MPS
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DUP[]:        DUPlicate top stack element                             */
+  /* Opcode range: 0x20                                                    */
+  /* Stack:        StkElt --> StkElt StkElt                                */
+  /*                                                                       */
+  static
+  void  Ins_DUP( INS_ARG )
+  {
+    DO_DUP
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* POP[]:        POP the stack's top elt                                 */
+  /* Opcode range: 0x21                                                    */
+  /* Stack:        StkElt -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_POP( INS_ARG )
+  {
+    /* nothing to do */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* CLEAR[]:      CLEAR the entire stack                                  */
+  /* Opcode range: 0x22                                                    */
+  /* Stack:        StkElt... -->                                           */
+  /*                                                                       */
+  static
+  void  Ins_CLEAR( INS_ARG )
+  {
+    DO_CLEAR
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SWAP[]:       SWAP the top two elements                               */
+  /* Opcode range: 0x23                                                    */
+  /* Stack:        2 * StkElt --> 2 * StkElt                               */
+  /*                                                                       */
+  static
+  void  Ins_SWAP( INS_ARG )
+  {
+    DO_SWAP
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DEPTH[]:      return the stack DEPTH                                  */
+  /* Opcode range: 0x24                                                    */
+  /* Stack:        --> uint32                                              */
+  /*                                                                       */
+  static
+  void  Ins_DEPTH( INS_ARG )
+  {
+    DO_DEPTH
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* CINDEX[]:     Copy INDEXed element                                    */
+  /* Opcode range: 0x25                                                    */
+  /* Stack:        int32 --> StkElt                                        */
+  /*                                                                       */
+  static
+  void  Ins_CINDEX( INS_ARG )
+  {
+    DO_CINDEX
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* EIF[]:        End IF                                                  */
+  /* Opcode range: 0x59                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_EIF( INS_ARG )
+  {
+    /* nothing to do */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* JROT[]:       Jump Relative On True                                   */
+  /* Opcode range: 0x78                                                    */
+  /* Stack:        StkElt int32 -->                                        */
+  /*                                                                       */
+  static
+  void  Ins_JROT( INS_ARG )
+  {
+    DO_JROT
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* JMPR[]:       JuMP Relative                                           */
+  /* Opcode range: 0x1C                                                    */
+  /* Stack:        int32 -->                                               */
+  /*                                                                       */
+  static
+  void  Ins_JMPR( INS_ARG )
+  {
+    DO_JMPR
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* JROF[]:       Jump Relative On False                                  */
+  /* Opcode range: 0x79                                                    */
+  /* Stack:        StkElt int32 -->                                        */
+  /*                                                                       */
+  static
+  void  Ins_JROF( INS_ARG )
+  {
+    DO_JROF
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* LT[]:         Less Than                                               */
+  /* Opcode range: 0x50                                                    */
+  /* Stack:        int32? int32? --> bool                                  */
+  /*                                                                       */
+  static
+  void  Ins_LT( INS_ARG )
+  {
+    DO_LT
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* LTEQ[]:       Less Than or EQual                                      */
+  /* Opcode range: 0x51                                                    */
+  /* Stack:        int32? int32? --> bool                                  */
+  /*                                                                       */
+  static
+  void  Ins_LTEQ( INS_ARG )
+  {
+    DO_LTEQ
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GT[]:         Greater Than                                            */
+  /* Opcode range: 0x52                                                    */
+  /* Stack:        int32? int32? --> bool                                  */
+  /*                                                                       */
+  static
+  void  Ins_GT( INS_ARG )
+  {
+    DO_GT
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GTEQ[]:       Greater Than or EQual                                   */
+  /* Opcode range: 0x53                                                    */
+  /* Stack:        int32? int32? --> bool                                  */
+  /*                                                                       */
+  static
+  void  Ins_GTEQ( INS_ARG )
+  {
+    DO_GTEQ
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* EQ[]:         EQual                                                   */
+  /* Opcode range: 0x54                                                    */
+  /* Stack:        StkElt StkElt --> bool                                  */
+  /*                                                                       */
+  static
+  void  Ins_EQ( INS_ARG )
+  {
+    DO_EQ
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* NEQ[]:        Not EQual                                               */
+  /* Opcode range: 0x55                                                    */
+  /* Stack:        StkElt StkElt --> bool                                  */
+  /*                                                                       */
+  static
+  void  Ins_NEQ( INS_ARG )
+  {
+    DO_NEQ
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ODD[]:        Is ODD                                                  */
+  /* Opcode range: 0x56                                                    */
+  /* Stack:        f26.6 --> bool                                          */
+  /*                                                                       */
+  static
+  void  Ins_ODD( INS_ARG )
+  {
+    DO_ODD
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* EVEN[]:       Is EVEN                                                 */
+  /* Opcode range: 0x57                                                    */
+  /* Stack:        f26.6 --> bool                                          */
+  /*                                                                       */
+  static
+  void  Ins_EVEN( INS_ARG )
+  {
+    DO_EVEN
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* AND[]:        logical AND                                             */
+  /* Opcode range: 0x5A                                                    */
+  /* Stack:        uint32 uint32 --> uint32                                */
+  /*                                                                       */
+  static
+  void  Ins_AND( INS_ARG )
+  {
+    DO_AND
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* OR[]:         logical OR                                              */
+  /* Opcode range: 0x5B                                                    */
+  /* Stack:        uint32 uint32 --> uint32                                */
+  /*                                                                       */
+  static
+  void  Ins_OR( INS_ARG )
+  {
+    DO_OR
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* NOT[]:        logical NOT                                             */
+  /* Opcode range: 0x5C                                                    */
+  /* Stack:        StkElt --> uint32                                       */
+  /*                                                                       */
+  static
+  void  Ins_NOT( INS_ARG )
+  {
+    DO_NOT
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ADD[]:        ADD                                                     */
+  /* Opcode range: 0x60                                                    */
+  /* Stack:        f26.6 f26.6 --> f26.6                                   */
+  /*                                                                       */
+  static
+  void  Ins_ADD( INS_ARG )
+  {
+    DO_ADD
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SUB[]:        SUBtract                                                */
+  /* Opcode range: 0x61                                                    */
+  /* Stack:        f26.6 f26.6 --> f26.6                                   */
+  /*                                                                       */
+  static
+  void  Ins_SUB( INS_ARG )
+  {
+    DO_SUB
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DIV[]:        DIVide                                                  */
+  /* Opcode range: 0x62                                                    */
+  /* Stack:        f26.6 f26.6 --> f26.6                                   */
+  /*                                                                       */
+  static
+  void  Ins_DIV( INS_ARG )
+  {
+    DO_DIV
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MUL[]:        MULtiply                                                */
+  /* Opcode range: 0x63                                                    */
+  /* Stack:        f26.6 f26.6 --> f26.6                                   */
+  /*                                                                       */
+  static
+  void  Ins_MUL( INS_ARG )
+  {
+    DO_MUL
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ABS[]:        ABSolute value                                          */
+  /* Opcode range: 0x64                                                    */
+  /* Stack:        f26.6 --> f26.6                                         */
+  /*                                                                       */
+  static
+  void  Ins_ABS( INS_ARG )
+  {
+    DO_ABS
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* NEG[]:        NEGate                                                  */
+  /* Opcode range: 0x65                                                    */
+  /* Stack: f26.6 --> f26.6                                                */
+  /*                                                                       */
+  static
+  void  Ins_NEG( INS_ARG )
+  {
+    DO_NEG
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FLOOR[]:      FLOOR                                                   */
+  /* Opcode range: 0x66                                                    */
+  /* Stack:        f26.6 --> f26.6                                         */
+  /*                                                                       */
+  static
+  void  Ins_FLOOR( INS_ARG )
+  {
+    DO_FLOOR
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* CEILING[]:    CEILING                                                 */
+  /* Opcode range: 0x67                                                    */
+  /* Stack:        f26.6 --> f26.6                                         */
+  /*                                                                       */
+  static
+  void  Ins_CEILING( INS_ARG )
+  {
+    DO_CEILING
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* RS[]:         Read Store                                              */
+  /* Opcode range: 0x43                                                    */
+  /* Stack:        uint32 --> uint32                                       */
+  /*                                                                       */
+  static
+  void  Ins_RS( INS_ARG )
+  {
+    DO_RS
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* WS[]:         Write Store                                             */
+  /* Opcode range: 0x42                                                    */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_WS( INS_ARG )
+  {
+    DO_WS
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* WCVTP[]:      Write CVT in Pixel units                                */
+  /* Opcode range: 0x44                                                    */
+  /* Stack:        f26.6 uint32 -->                                        */
+  /*                                                                       */
+  static
+  void  Ins_WCVTP( INS_ARG )
+  {
+    DO_WCVTP
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* WCVTF[]:      Write CVT in Funits                                     */
+  /* Opcode range: 0x70                                                    */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_WCVTF( INS_ARG )
+  {
+    DO_WCVTF
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* RCVT[]:       Read CVT                                                */
+  /* Opcode range: 0x45                                                    */
+  /* Stack:        uint32 --> f26.6                                        */
+  /*                                                                       */
+  static
+  void  Ins_RCVT( INS_ARG )
+  {
+    DO_RCVT
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* AA[]:         Adjust Angle                                            */
+  /* Opcode range: 0x7F                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_AA( INS_ARG )
+  {
+    /* Intentional - no longer supported */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DEBUG[]:      DEBUG.  Unsupported                                     */
+  /* Opcode range: 0x4F                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  /* Note: The original instruction pops a value from the stack            */
+  /*                                                                       */
+  static
+  void  Ins_DEBUG( INS_ARG )
+  {
+    DO_DEBUG
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ROUND[ab]:    ROUND value                                             */
+  /* Opcode range: 0x68-0x6B                                               */
+  /* Stack:        f26.6 --> f26.6                                         */
+  /*                                                                       */
+  static
+  void  Ins_ROUND( INS_ARG )
+  {
+    DO_ROUND
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* NROUND[ab]:   No ROUNDing of value                                    */
+  /* Opcode range: 0x6C-0x6F                                               */
+  /* Stack:        f26.6 --> f26.6                                         */
+  /*                                                                       */
+  static
+  void  Ins_NROUND( INS_ARG )
+  {
+    DO_NROUND
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MAX[]:        MAXimum                                                 */
+  /* Opcode range: 0x68                                                    */
+  /* Stack:        int32? int32? --> int32                                 */
+  /*                                                                       */
+  static
+  void  Ins_MAX( INS_ARG )
+  {
+    DO_MAX
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MIN[]:        MINimum                                                 */
+  /* Opcode range: 0x69                                                    */
+  /* Stack:        int32? int32? --> int32                                 */
+  /*                                                                       */
+  static
+  void  Ins_MIN( INS_ARG )
+  {
+    DO_MIN
+  }
+
+
+#endif  /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The following functions are called as is within the switch statement. */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MINDEX[]:     Move INDEXed element                                    */
+  /* Opcode range: 0x26                                                    */
+  /* Stack:        int32? --> StkElt                                       */
+  /*                                                                       */
+  static
+  void  Ins_MINDEX( INS_ARG )
+  {
+    TT_Long  L, K;
+
+
+    L = args[0];
+
+    if ( L <= 0 || L > CUR.args )
+    {
+      CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    K = CUR.stack[CUR.args - L];
+
+    MEM_Move( (&CUR.stack[CUR.args - L    ]),
+              (&CUR.stack[CUR.args - L + 1]),
+              (L - 1) * sizeof ( TT_Long ) );
+
+    CUR.stack[CUR.args - 1] = K;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ROLL[]:       ROLL top three elements                                 */
+  /* Opcode range: 0x8A                                                    */
+  /* Stack:        3 * StkElt --> 3 * StkElt                               */
+  /*                                                                       */
+  static
+  void  Ins_ROLL( INS_ARG )
+  {
+    TT_Long  A, B, C;
+
+
+    UNUSED_EXEC;
+
+    A = args[2];
+    B = args[1];
+    C = args[0];
+
+    args[2] = C;
+    args[1] = A;
+    args[0] = B;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MANAGING THE FLOW OF CONTROL                                          */
+  /*                                                                       */
+  /*  Instructions appear in the specs' order.                             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  static
+  TT_Bool  SkipCode( EXEC_OP )
+  {
+    CUR.IP += CUR.length;
+
+    if ( CUR.IP < CUR.codeSize )
+    {
+      CUR.opcode = CUR.code[CUR.IP];
+
+      CUR.length = opcode_length[CUR.opcode];
+      if ( CUR.length < 0 )
+      {
+        if ( CUR.IP + 1 > CUR.codeSize )
+          goto Fail_Overflow;
+        CUR.length = CUR.code[CUR.IP + 1] + 2;
+      }
+
+      if ( CUR.IP + CUR.length <= CUR.codeSize )
+        return SUCCESS;
+    }
+
+  Fail_Overflow:
+    CUR.error = TT_Err_Code_Overflow;
+    return FAILURE;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* IF[]:         IF test                                                 */
+  /* Opcode range: 0x58                                                    */
+  /* Stack:        StkElt -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_IF( INS_ARG )
+  {
+    TT_Int   nIfs;
+    TT_Bool  Out;
+
+
+    if ( args[0] != 0 )
+      return;
+
+    nIfs = 1;
+    Out = 0;
+
+    do
+    {
+      if ( SKIP_Code() == FAILURE )
+        return;
+
+      switch ( CUR.opcode )
+      {
+      case 0x58:      /* IF */
+        nIfs++;
+        break;
+
+      case 0x1B:      /* ELSE */
+        Out = (nIfs == 1);
+        break;
+
+      case 0x59:      /* EIF */
+        nIfs--;
+        Out = (nIfs == 0);
+        break;
+      }
+    } while ( Out == 0 );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ELSE[]:       ELSE                                                    */
+  /* Opcode range: 0x1B                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_ELSE( INS_ARG )
+  {
+    TT_Int  nIfs;
+
+
+    UNUSED_ARG;
+
+    nIfs = 1;
+
+    do
+    {
+      if ( SKIP_Code() == FAILURE )
+        return;
+
+      switch ( CUR.opcode )
+      {
+      case 0x58:    /* IF */
+        nIfs++;
+        break;
+
+      case 0x59:    /* EIF */
+        nIfs--;
+        break;
+      }
+    } while ( nIfs != 0 );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DEFINING AND USING FUNCTIONS AND INSTRUCTIONS                         */
+  /*                                                                       */
+  /*  Instructions appear in the specs' order.                             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FDEF[]:       Function DEFinition                                     */
+  /* Opcode range: 0x2C                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_FDEF( INS_ARG )
+  {
+    TT_ULong       n;
+    TT_DefRecord*  rec;
+    TT_DefRecord*  limit;
+
+    /* some font programs are broken enough to redefine functions! */
+    /* We will then parse the current table..                      */
+    rec   = CUR.FDefs;
+    limit = rec + CUR.numFDefs;
+    n     = args[0];
+    
+    for ( ; rec < limit; rec++ )
+    {
+      if (rec->opc == n)
+        break;
+    }
+    
+    if ( rec == limit )
+    {
+      /* check that there is enough room for new functions */
+      if ( CUR.numFDefs >= CUR.maxFDefs )
+      {
+        CUR.error = TT_Err_Too_Many_Function_Defs;
+        return;
+      }
+      CUR.numFDefs++;
+    }
+    
+    rec->range  = CUR.curRange;
+    rec->opc    = n;
+    rec->start  = CUR.IP+1;
+    rec->active = TRUE;
+    
+    if ( n > CUR.maxFunc )
+      CUR.maxFunc = n;
+    
+    /* Now skip the whole function definition. */
+    /* We don't allow nested IDEFS & FDEFs.    */
+
+    while ( SKIP_Code() == SUCCESS )
+    {
+      switch ( CUR.opcode )
+      {
+      case 0x89:    /* IDEF */
+      case 0x2C:    /* FDEF */
+        CUR.error = TT_Err_Nested_DEFS;
+        return;
+
+      case 0x2D:   /* ENDF */
+        return;
+      }
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ENDF[]:       END Function definition                                 */
+  /* Opcode range: 0x2D                                                    */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_ENDF( INS_ARG )
+  {
+    TT_CallRec*  pRec;
+
+
+    UNUSED_ARG;
+
+    if ( CUR.callTop <= 0 )     /* We encountered an ENDF without a call */
+    {
+      CUR.error = TT_Err_ENDF_In_Exec_Stream;
+      return;
+    }
+
+    CUR.callTop--;
+
+    pRec = &CUR.callStack[CUR.callTop];
+
+    pRec->Cur_Count--;
+
+    CUR.step_ins = FALSE;
+
+    if ( pRec->Cur_Count > 0 )
+    {
+      CUR.callTop++;
+      CUR.IP = pRec->Cur_Restart;
+    }
+    else
+      /* Loop through the current function */
+      INS_Goto_CodeRange( pRec->Caller_Range,
+                          pRec->Caller_IP );
+
+    /* Exit the current call frame.                       */
+
+    /* NOTE: When the last intruction of a program        */
+    /*       is a CALL or LOOPCALL, the return address    */
+    /*       is always out of the code range.  This is    */
+    /*       a valid address, and it's why we do not test */
+    /*       the result of Ins_Goto_CodeRange() here!     */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* CALL[]:       CALL function                                           */
+  /* Opcode range: 0x2B                                                    */
+  /* Stack:        uint32? -->                                             */
+  /*                                                                       */
+  static
+  void  Ins_CALL( INS_ARG )
+  {
+    TT_ULong       F;
+    TT_CallRec*    pCrec;
+    TT_DefRecord*  def;
+
+    /* first of all, check the index */
+    F = args[0];
+    if ( BOUNDS( F, CUR.maxFunc+1 ) ) goto Fail;
+    
+    /* Except for some old Apple fonts, all functions in a TrueType */
+    /* font are defined in increasing order, starting from 0. This  */
+    /* means that we normally have                                  */
+    /*                                                              */
+    /*    CUR.maxFunc+1 == CUR.numFDefs                             */
+    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */
+    /*                                                              */
+    /* If this isn't true, we need to look up the function table.   */
+
+    def = CUR.FDefs + F;
+    if ( CUR.maxFunc+1 != CUR.numFDefs  || def->opc != F )
+    {
+      /* look up the FDefs table */
+      TT_DefRecord*  limit;
+      
+      def   = CUR.FDefs;
+      limit = def + CUR.numFDefs;
+      
+      while (def < limit && def->opc != F)
+        def++;
+        
+      if (def == limit) goto Fail;
+    }
+    
+    /* check that the function is active */
+    if (!def->active)
+      goto Fail;
+      
+    /* check the call stack */
+    if ( CUR.callTop >= CUR.callSize )
+    {
+      CUR.error = TT_Err_Stack_Overflow;
+      return;
+    }
+
+    pCrec = CUR.callStack + CUR.callTop;
+
+    pCrec->Caller_Range = CUR.curRange;
+    pCrec->Caller_IP    = CUR.IP + 1;
+    pCrec->Cur_Count    = 1;
+    pCrec->Cur_Restart  = def->start;
+
+    CUR.callTop++;
+
+    INS_Goto_CodeRange( def->range,
+                        def->start );
+                        
+    CUR.step_ins = FALSE;
+    return;
+    
+  Fail:
+    CUR.error = TT_Err_Invalid_Reference;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* LOOPCALL[]:   LOOP and CALL function                                  */
+  /* Opcode range: 0x2A                                                    */
+  /* Stack:        uint32? Eint16? -->                                     */
+  /*                                                                       */
+  static
+  void  Ins_LOOPCALL( INS_ARG )
+  {
+    TT_ULong       F;
+    TT_CallRec*    pCrec;
+    TT_DefRecord*  def;
+
+    /* first of all, check the index */
+    F = args[1];
+    if ( BOUNDS( F, CUR.maxFunc+1 ) ) goto Fail;
+    
+    /* Except for some old Apple fonts, all functions in a TrueType */
+    /* font are defined in increasing order, starting from 0. This  */
+    /* means that we normally have                                  */
+    /*                                                              */
+    /*    CUR.maxFunc+1 == CUR.numFDefs                             */
+    /*    CUR.FDefs[n].opc == n for n in 0..CUR.maxFunc             */
+    /*                                                              */
+    /* If this isn't true, we need to look up the function table.   */
+
+    def = CUR.FDefs + F;
+    if ( CUR.maxFunc+1 != CUR.numFDefs  || def->opc != F )
+    {
+      /* look up the FDefs table */
+      TT_DefRecord*  limit;
+      
+      def   = CUR.FDefs;
+      limit = def + CUR.numFDefs;
+      
+      while (def < limit && def->opc != F)
+        def++;
+        
+      if (def == limit) goto Fail;
+    }
+    
+    /* check that the function is active */
+    if (!def->active)
+      goto Fail;
+
+    /* check stack */      
+    if ( CUR.callTop >= CUR.callSize )
+    {
+      CUR.error = TT_Err_Stack_Overflow;
+      return;
+    }
+
+    if ( args[0] > 0 )
+    {
+      pCrec = CUR.callStack + CUR.callTop;
+
+      pCrec->Caller_Range = CUR.curRange;
+      pCrec->Caller_IP    = CUR.IP + 1;
+      pCrec->Cur_Count    = (TT_Int)(args[0]);
+      pCrec->Cur_Restart  = def->start;
+
+      CUR.callTop++;
+
+      INS_Goto_CodeRange( def->range, def->start );
+
+      CUR.step_ins = FALSE;
+    }
+    return;
+
+  Fail:
+    CUR.error = TT_Err_Invalid_Reference;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* IDEF[]:       Instruction DEFinition                                  */
+  /* Opcode range: 0x89                                                    */
+  /* Stack:        Eint8 -->                                               */
+  /*                                                                       */
+  static
+  void Ins_IDEF( INS_ARG )
+  {
+    TT_DefRecord*  def;
+    TT_DefRecord*  limit;
+
+    /*  First of all, look for the same function in our table */
+    def   = CUR.IDefs;
+    limit = def + CUR.numIDefs;
+    for ( ; def < limit; def++ )
+      if (def->opc == (TT_ULong)args[0] )
+        break;
+        
+    if ( def == limit )
+    {
+      /* check that there is enough room for a new instruction */
+      if ( CUR.numIDefs >= CUR.maxIDefs )
+      {
+        CUR.error = TT_Err_Too_Many_Instruction_Defs;
+        return;
+      }
+      CUR.numIDefs++;
+    }
+    
+    def->opc    = args[0];
+    def->start  = CUR.IP+1;
+    def->range  = CUR.curRange;
+    def->active = TRUE;
+    
+    if ( (TT_ULong)args[0] > CUR.maxIns )
+      CUR.maxIns = args[0];
+    
+    /* Now skip the whole function definition. */
+    /* We don't allow nested IDEFs & FDEFs.    */
+
+    while ( SKIP_Code() == SUCCESS )
+    {
+      switch ( CUR.opcode )
+      {
+      case 0x89:   /* IDEF */
+      case 0x2C:   /* FDEF */
+        CUR.error = TT_Err_Nested_DEFS;
+        return;
+      case 0x2D:   /* ENDF */
+        return;
+      }
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* PUSHING DATA ONTO THE INTERPRETER STACK                               */
+  /*                                                                       */
+  /*  Instructions appear in the specs' order.                             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* NPUSHB[]:     PUSH N Bytes                                            */
+  /* Opcode range: 0x40                                                    */
+  /* Stack:        --> uint32...                                           */
+  /*                                                                       */
+  static
+  void  Ins_NPUSHB( INS_ARG )
+  {
+    TT_UShort  L, K;
+
+
+    L = (TT_UShort)CUR.code[CUR.IP + 1];
+
+    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    {
+      CUR.error = TT_Err_Stack_Overflow;
+      return;
+    }
+
+    for ( K = 1; K <= L; K++ )
+      args[K - 1] = CUR.code[CUR.IP + K + 1];
+
+    CUR.new_top += L;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* NPUSHW[]:     PUSH N Words                                            */
+  /* Opcode range: 0x41                                                    */
+  /* Stack:        --> int32...                                            */
+  /*                                                                       */
+  static
+  void  Ins_NPUSHW( INS_ARG )
+  {
+    TT_UShort  L, K;
+
+
+    L = (TT_UShort)CUR.code[CUR.IP + 1];
+
+    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    {
+      CUR.error = TT_Err_Stack_Overflow;
+      return;
+    }
+
+    CUR.IP += 2;
+
+    for ( K = 0; K < L; K++ )
+      args[K] = GET_ShortIns();
+
+    CUR.step_ins = FALSE;
+    CUR.new_top += L;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* PUSHB[abc]:   PUSH Bytes                                              */
+  /* Opcode range: 0xB0-0xB7                                               */
+  /* Stack:        --> uint32...                                           */
+  /*                                                                       */
+  static
+  void  Ins_PUSHB( INS_ARG )
+  {
+    TT_UShort  L, K;
+
+
+    L = (TT_UShort)CUR.opcode - 0xB0 + 1;
+
+    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    {
+      CUR.error = TT_Err_Stack_Overflow;
+      return;
+    }
+
+    for ( K = 1; K <= L; K++ )
+      args[K - 1] = CUR.code[CUR.IP + K];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* PUSHW[abc]:   PUSH Words                                              */
+  /* Opcode range: 0xB8-0xBF                                               */
+  /* Stack:        --> int32...                                            */
+  /*                                                                       */
+  static
+  void  Ins_PUSHW( INS_ARG )
+  {
+    TT_UShort  L, K;
+
+
+    L = (TT_UShort)CUR.opcode - 0xB8 + 1;
+
+    if ( BOUNDS( L, CUR.stackSize + 1 - CUR.top ) )
+    {
+      CUR.error = TT_Err_Stack_Overflow;
+      return;
+    }
+
+    CUR.IP++;
+
+    for ( K = 0; K < L; K++ )
+      args[K] = GET_ShortIns();
+
+    CUR.step_ins = FALSE;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MANAGING THE GRAPHICS STATE                                           */
+  /*                                                                       */
+  /*  Instructions appear in the specs' order.                             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GC[a]:        Get Coordinate projected onto                           */
+  /* Opcode range: 0x46-0x47                                               */
+  /* Stack:        uint32 --> f26.6                                        */
+  /*                                                                       */
+  /* BULLSHIT: Measures from the original glyph must be taken along the    */
+  /*           dual projection vector!                                     */
+  /*                                                                       */
+  static void  Ins_GC( INS_ARG )
+  {
+    TT_ULong    L;
+    TT_F26Dot6  R;
+
+
+    L = (TT_ULong)args[0];
+
+    if ( BOUNDS( L, CUR.zp2.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+      {
+        CUR.error = TT_Err_Invalid_Reference;
+        return;
+      }
+      else
+        R = 0;
+    }
+    else
+    {
+      if ( CUR.opcode & 1 )
+        R = CUR_Func_dualproj( CUR.zp2.org + L, NULL_Vector );
+      else
+        R = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector );
+    }
+
+    args[0] = R;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SCFS[]:       Set Coordinate From Stack                               */
+  /* Opcode range: 0x48                                                    */
+  /* Stack:        f26.6 uint32 -->                                        */
+  /*                                                                       */
+  /* Formula:                                                              */
+  /*                                                                       */
+  /*   OA := OA + ( value - OA.p )/( f.p ) * f                             */
+  /*                                                                       */
+  static
+  void  Ins_SCFS( INS_ARG )
+  {
+    TT_Long    K;
+    TT_UShort  L;
+
+
+    L = (TT_UShort)args[0];
+
+    if ( BOUNDS( L, CUR.zp2.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    K = CUR_Func_project( CUR.zp2.cur + L, NULL_Vector );
+
+    CUR_Func_move( &CUR.zp2, L, args[1] - K );
+
+    /* not part of the specs, but here for safety */
+
+    if ( CUR.GS.gep2 == 0 )
+      CUR.zp2.org[L] = CUR.zp2.cur[L];
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MD[a]:        Measure Distance                                        */
+  /* Opcode range: 0x49-0x4A                                               */
+  /* Stack:        uint32 uint32 --> f26.6                                 */
+  /*                                                                       */
+  /* BULLSHIT: Measure taken in the original glyph must be along the dual  */
+  /*           projection vector.                                          */
+  /*                                                                       */
+  /* Second BULLSHIT: Flag attributes are inverted!                        */
+  /*                  0 => measure distance in original outline            */
+  /*                  1 => measure distance in grid-fitted outline         */
+  /*                                                                       */
+  /* Third one: `zp0 - zp1', and not `zp2 - zp1!                           */
+  /*                                                                       */
+  static
+  void  Ins_MD( INS_ARG )
+  {
+    TT_UShort   K, L;
+    TT_F26Dot6  D;
+
+
+    K = (TT_UShort)args[1];
+    L = (TT_UShort)args[0];
+
+    if( BOUNDS( L, CUR.zp0.n_points ) ||
+        BOUNDS( K, CUR.zp1.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+      {
+        CUR.error = TT_Err_Invalid_Reference;
+        return;
+      }
+      D = 0;
+    }
+    else
+    {
+      if ( CUR.opcode & 1 )
+        D = CUR_Func_project( CUR.zp0.cur + L, CUR.zp1.cur + K );
+      else
+        D = CUR_Func_dualproj( CUR.zp0.org + L, CUR.zp1.org + K );
+    }
+
+    args[0] = D;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SDPVTL[a]:    Set Dual PVector to Line                                */
+  /* Opcode range: 0x86-0x87                                               */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_SDPVTL( INS_ARG )
+  {
+    TT_Long    A, B, C;
+    TT_UShort  p1, p2;   /* was TT_Int in pas type ERROR */
+
+
+    p1 = (TT_UShort)args[1];
+    p2 = (TT_UShort)args[0];
+
+    if ( BOUNDS( p2, CUR.zp1.n_points ) ||
+         BOUNDS( p1, CUR.zp2.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    {
+      TT_Vector* v1 = CUR.zp1.org + p2;
+      TT_Vector* v2 = CUR.zp2.org + p1;
+
+
+      A = v1->x - v2->x;
+      B = v1->y - v2->y;
+    }
+
+    if ( (CUR.opcode & 1) != 0 )
+    {
+      C =  B;   /* CounterClockwise rotation */
+      B =  A;
+      A = -C;
+    }
+
+    NORMalize( A, B, &CUR.GS.dualVector );
+
+    {
+      TT_Vector*  v1 = CUR.zp1.cur + p2;
+      TT_Vector*  v2 = CUR.zp2.cur + p1;
+
+
+      A = v1->x - v2->x;
+      B = v1->y - v2->y;
+    }
+
+    if ( (CUR.opcode & 1) != 0 )
+    {
+      C =  B;   /* CounterClockwise rotation */
+      B =  A;
+      A = -C;
+    }
+
+    NORMalize( A, B, &CUR.GS.projVector );
+
+    COMPUTE_Funcs();
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SZP0[]:       Set Zone Pointer 0                                      */
+  /* Opcode range: 0x13                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SZP0( INS_ARG )
+  {
+    switch ( (TT_Int)args[0] )
+    {
+    case 0:
+      CUR.zp0 = CUR.twilight;
+      break;
+
+    case 1:
+      CUR.zp0 = CUR.pts;
+      break;
+
+    default:
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    CUR.GS.gep0 = (TT_UShort)(args[0]);
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SZP1[]:       Set Zone Pointer 1                                      */
+  /* Opcode range: 0x14                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SZP1( INS_ARG )
+  {
+    switch ( (TT_Int)args[0] )
+    {
+    case 0:
+      CUR.zp1 = CUR.twilight;
+      break;
+
+    case 1:
+      CUR.zp1 = CUR.pts;
+      break;
+
+    default:
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    CUR.GS.gep1 = (TT_UShort)(args[0]);
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SZP2[]:       Set Zone Pointer 2                                      */
+  /* Opcode range: 0x15                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SZP2( INS_ARG )
+  {
+    switch ( (TT_Int)args[0] )
+    {
+    case 0:
+      CUR.zp2 = CUR.twilight;
+      break;
+
+    case 1:
+      CUR.zp2 = CUR.pts;
+      break;
+
+    default:
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    CUR.GS.gep2 = (TT_UShort)(args[0]);
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SZPS[]:       Set Zone PointerS                                       */
+  /* Opcode range: 0x16                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SZPS( INS_ARG )
+  {
+    switch ( (TT_Int)args[0] )
+    {
+    case 0:
+      CUR.zp0 = CUR.twilight;
+      break;
+
+    case 1:
+      CUR.zp0 = CUR.pts;
+      break;
+
+    default:
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    CUR.zp1 = CUR.zp0;
+    CUR.zp2 = CUR.zp0;
+
+    CUR.GS.gep0 = (TT_UShort)(args[0]);
+    CUR.GS.gep1 = (TT_UShort)(args[0]);
+    CUR.GS.gep2 = (TT_UShort)(args[0]);
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* INSTCTRL[]:   INSTruction ConTRoL                                     */
+  /* Opcode range: 0x8e                                                    */
+  /* Stack:        int32 int32 -->                                         */
+  /*                                                                       */
+  static
+  void  Ins_INSTCTRL( INS_ARG )
+  {
+    TT_Long  K, L;
+
+
+    K = args[1];
+    L = args[0];
+
+    if ( K < 1 || K > 2 )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    if ( L != 0 )
+        L = K;
+
+    CUR.GS.instruct_control =
+      (TT_Byte)( CUR.GS.instruct_control & ~(TT_Byte)K ) | (TT_Byte)L;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SCANCTRL[]:   SCAN ConTRoL                                            */
+  /* Opcode range: 0x85                                                    */
+  /* Stack:        uint32? -->                                             */
+  /*                                                                       */
+  static
+  void  Ins_SCANCTRL( INS_ARG )
+  {
+    TT_Int  A;
+
+
+    /* Get Threshold */
+    A = (TT_Int)(args[0] & 0xFF);
+
+    if ( A == 0xFF )
+    {
+      CUR.GS.scan_control = TRUE;
+      return;
+    }
+    else if ( A == 0 )
+    {
+      CUR.GS.scan_control = FALSE;
+      return;
+    }
+
+    A *= 64;
+
+    /*
+    if ( (args[0] & 0x100) != 0 && CUR.metrics.pointSize <= A )
+      CUR.GS.scan_control = TRUE;
+    */
+
+    if ( (args[0] & 0x200) != 0 && CUR.tt_metrics.rotated )
+      CUR.GS.scan_control = TRUE;
+
+    if ( (args[0] & 0x400) != 0 && CUR.tt_metrics.stretched )
+      CUR.GS.scan_control = TRUE;
+
+    /*
+    if ( (args[0] & 0x800) != 0 && CUR.metrics.pointSize > A )
+      CUR.GS.scan_control = FALSE;
+    */
+
+    if ( (args[0] & 0x1000) != 0 && CUR.tt_metrics.rotated )
+      CUR.GS.scan_control = FALSE;
+
+    if ( (args[0] & 0x2000) != 0 && CUR.tt_metrics.stretched )
+      CUR.GS.scan_control = FALSE;
+}
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SCANTYPE[]:   SCAN TYPE                                               */
+  /* Opcode range: 0x8D                                                    */
+  /* Stack:        uint32? -->                                             */
+  /*                                                                       */
+  static
+  void  Ins_SCANTYPE( INS_ARG )
+  {
+    /* For compatibility with future enhancements, */
+    /* we must ignore new modes                    */
+
+    if ( args[0] >= 0 && args[0] <= 5 )
+    {
+      if ( args[0] == 3 )
+        args[0] = 2;
+
+      CUR.GS.scan_type = (TT_Int)args[0];
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MANAGING OUTLINES                                                     */
+  /*                                                                       */
+  /*  Instructions appear in the specs' order.                             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FLIPPT[]:     FLIP PoinT                                              */
+  /* Opcode range: 0x80                                                    */
+  /* Stack:        uint32... -->                                           */
+  /*                                                                       */
+  static
+  void  Ins_FLIPPT( INS_ARG )
+  {
+    TT_UShort  point;
+
+
+    UNUSED_ARG;
+
+    if ( CUR.top < CUR.GS.loop )
+    {
+      CUR.error = TT_Err_Too_Few_Arguments;
+      return;
+    }
+
+    while ( CUR.GS.loop > 0 )
+    {
+      CUR.args--;
+
+      point = (TT_UShort)CUR.stack[CUR.args];
+
+      if ( BOUNDS( point, CUR.pts.n_points ) )
+      {
+        if ( CUR.pedantic_hinting )
+        {
+          CUR.error = TT_Err_Invalid_Reference;
+          return;
+        }
+      }
+      else
+        CUR.pts.touch[point] ^= FT_Curve_Tag_On;
+
+      CUR.GS.loop--;
+    }
+
+    CUR.GS.loop = 1;
+    CUR.new_top = CUR.args;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FLIPRGON[]:   FLIP RanGe ON                                           */
+  /* Opcode range: 0x81                                                    */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_FLIPRGON( INS_ARG )
+  {
+    TT_UShort  I, K, L;
+
+
+    K = (TT_UShort)args[1];
+    L = (TT_UShort)args[0];
+
+    if ( BOUNDS( K, CUR.pts.n_points ) ||
+         BOUNDS( L, CUR.pts.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    for ( I = L; I <= K; I++ )
+      CUR.pts.touch[I] |= FT_Curve_Tag_On;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FLIPRGOFF:    FLIP RanGe OFF                                          */
+  /* Opcode range: 0x82                                                    */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_FLIPRGOFF( INS_ARG )
+  {
+    TT_UShort  I, K, L;
+
+
+    K = (TT_UShort)args[1];
+    L = (TT_UShort)args[0];
+
+    if ( BOUNDS( K, CUR.pts.n_points ) ||
+         BOUNDS( L, CUR.pts.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    for ( I = L; I <= K; I++ )
+      CUR.pts.touch[I] &= ~FT_Curve_Tag_On;
+  }
+
+
+  static
+  TT_Bool  Compute_Point_Displacement( EXEC_OP_ TT_F26Dot6*    x,
+                                                TT_F26Dot6*    y,
+                                                TT_GlyphZone*  zone,
+                                                TT_UShort*     refp )
+  {
+    TT_GlyphZone  zp;
+    TT_UShort     p;
+    TT_F26Dot6    d;
+
+
+    if ( CUR.opcode & 1 )
+    {
+      zp = CUR.zp0;
+      p  = CUR.GS.rp1;
+    }
+    else
+    {
+      zp = CUR.zp1;
+      p  = CUR.GS.rp2;
+    }
+
+    if ( BOUNDS( p, zp.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return FAILURE;
+    }
+
+    *zone = zp;
+    *refp = p;
+
+    d = CUR_Func_project( zp.cur + p, zp.org + p );
+
+    *x = TT_MULDIV( d,
+                    (TT_Long)CUR.GS.freeVector.x * 0x10000L,
+                    CUR.F_dot_P );
+    *y = TT_MULDIV( d,
+                    (TT_Long)CUR.GS.freeVector.y * 0x10000L,
+                    CUR.F_dot_P );
+
+    return SUCCESS;
+  }
+
+
+  static
+  void  Move_Zp2_Point( EXEC_OP_ TT_UShort   point,
+                                 TT_F26Dot6  dx,
+                                 TT_F26Dot6  dy,
+                                 TT_Bool     touch )
+  {
+    if ( CUR.GS.freeVector.x != 0 )
+    {
+      CUR.zp2.cur[point].x += dx;
+      if ( touch )
+        CUR.zp2.touch[point] |= FT_Curve_Tag_Touch_X;
+    }
+
+    if ( CUR.GS.freeVector.y != 0 )
+    {
+      CUR.zp2.cur[point].y += dy;
+      if ( touch )
+        CUR.zp2.touch[point] |= FT_Curve_Tag_Touch_Y;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SHP[a]:       SHift Point by the last point                           */
+  /* Opcode range: 0x32-0x33                                               */
+  /* Stack:        uint32... -->                                           */
+  /*                                                                       */
+  static
+  void  Ins_SHP( INS_ARG )
+  {
+    TT_GlyphZone  zp;
+    TT_UShort     refp;
+
+    TT_F26Dot6    dx,
+                  dy;
+    TT_UShort     point;
+
+
+    UNUSED_ARG;
+
+    if ( CUR.top < CUR.GS.loop )
+    {
+      CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+      return;
+
+    while ( CUR.GS.loop > 0 )
+    {
+      CUR.args--;
+      point = (TT_UShort)CUR.stack[CUR.args];
+
+      if ( BOUNDS( point, CUR.zp2.n_points ) )
+      {
+        if ( CUR.pedantic_hinting )
+        {
+          CUR.error = TT_Err_Invalid_Reference;
+          return;
+        }
+      }
+      else
+        /* XXX: UNDOCUMENTED! SHP touches the points */
+        MOVE_Zp2_Point( point, dx, dy, TRUE );
+
+      CUR.GS.loop--;
+    }
+
+    CUR.GS.loop = 1;
+    CUR.new_top = CUR.args;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SHC[a]:       SHift Contour                                           */
+  /* Opcode range: 0x34-35                                                 */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SHC( INS_ARG )
+  {
+    TT_GlyphZone zp;
+    TT_UShort    refp;
+    TT_F26Dot6   dx,
+                 dy;
+
+    TT_Short     contour;
+    TT_UShort    first_point, last_point, i;
+
+
+    contour = (TT_UShort)args[0];
+
+    if ( BOUNDS( contour, CUR.pts.n_contours ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+      return;
+
+    if ( contour == 0 )
+      first_point = 0;
+    else
+      first_point = CUR.pts.contours[contour - 1] + 1;
+
+    last_point = CUR.pts.contours[contour];
+
+    /* XXX: this is probably wrong... at least it prevents memory */
+    /*      corruption when zp2 is the twilight zone              */
+    if ( last_point > CUR.zp2.n_points )
+    {
+      if ( CUR.zp2.n_points > 0 )
+        last_point = CUR.zp2.n_points - 1;
+      else
+        last_point = 0;
+    }
+
+    /* XXX: UNDOCUMENTED! SHC doesn't touch the points */
+    for ( i = first_point; i <= last_point; i++ )
+    {
+      if ( zp.cur != CUR.zp2.cur || refp != i )
+        MOVE_Zp2_Point( i, dx, dy, FALSE );
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SHZ[a]:       SHift Zone                                              */
+  /* Opcode range: 0x36-37                                                 */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_SHZ( INS_ARG )
+  {
+    TT_GlyphZone zp;
+    TT_UShort    refp;
+    TT_F26Dot6   dx,
+                 dy;
+
+    TT_UShort  last_point, i;
+
+
+    if ( BOUNDS( args[0], 2 ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    if ( COMPUTE_Point_Displacement( &dx, &dy, &zp, &refp ) )
+      return;
+
+    if ( CUR.zp2.n_points > 0 )
+      last_point = CUR.zp2.n_points - 1;
+    else
+      last_point = 0;
+
+    /* XXX: UNDOCUMENTED! SHZ doesn't touch the points */
+    for ( i = 0; i <= last_point; i++ )
+    {
+      if ( zp.cur != CUR.zp2.cur || refp != i )
+        MOVE_Zp2_Point( i, dx, dy, FALSE );
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* SHPIX[]:      SHift points by a PIXel amount                          */
+  /* Opcode range: 0x38                                                    */
+  /* Stack:        f26.6 uint32... -->                                     */
+  /*                                                                       */
+  static
+  void  Ins_SHPIX( INS_ARG )
+  {
+    TT_F26Dot6  dx, dy;
+    TT_UShort   point;
+
+
+    if ( CUR.top < CUR.GS.loop + 1 )
+    {
+      CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    dx = TT_MULDIV( args[0],
+                    (TT_Long)CUR.GS.freeVector.x,
+                    0x4000 );
+    dy = TT_MULDIV( args[0],
+                    (TT_Long)CUR.GS.freeVector.y,
+                    0x4000 );
+
+    while ( CUR.GS.loop > 0 )
+    {
+      CUR.args--;
+
+      point = (TT_UShort)CUR.stack[CUR.args];
+
+      if ( BOUNDS( point, CUR.zp2.n_points ) )
+      {
+        if ( CUR.pedantic_hinting )
+        {
+          CUR.error = TT_Err_Invalid_Reference;
+          return;
+        }
+      }
+      else
+        MOVE_Zp2_Point( point, dx, dy, TRUE );
+
+      CUR.GS.loop--;
+    }
+
+    CUR.GS.loop = 1;
+    CUR.new_top = CUR.args;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MSIRP[a]:     Move Stack Indirect Relative Position                   */
+  /* Opcode range: 0x3A-0x3B                                               */
+  /* Stack:        f26.6 uint32 -->                                        */
+  /*                                                                       */
+  static
+  void  Ins_MSIRP( INS_ARG )
+  {
+    TT_UShort      point;
+    TT_F26Dot6  distance;
+
+
+    point = (TT_UShort)args[0];
+
+    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
+         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    /* XXX: UNDOCUMENTED! behaviour */
+    if ( CUR.GS.gep0 == 0 )   /* if in twilight zone */
+    {
+      CUR.zp1.org[point] = CUR.zp0.org[CUR.GS.rp0];
+      CUR.zp1.cur[point] = CUR.zp1.org[point];
+    }
+
+    distance = CUR_Func_project( CUR.zp1.cur + point,
+                                 CUR.zp0.cur + CUR.GS.rp0 );
+
+    CUR_Func_move( &CUR.zp1, point, args[1] - distance );
+
+    CUR.GS.rp1 = CUR.GS.rp0;
+    CUR.GS.rp2 = point;
+
+    if ( (CUR.opcode & 1) != 0 )
+      CUR.GS.rp0 = point;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MDAP[a]:      Move Direct Absolute Point                              */
+  /* Opcode range: 0x2E-0x2F                                               */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_MDAP( INS_ARG )
+  {
+    TT_UShort   point;
+    TT_F26Dot6  cur_dist,
+                distance;
+
+
+    point = (TT_UShort)args[0];
+
+    if ( BOUNDS( point, CUR.zp0.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    /* XXX: Is there some undocumented feature while in the */
+    /*      twilight zone? ?                                */
+    if ( (CUR.opcode & 1) != 0 )
+    {
+      cur_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector );
+      distance = CUR_Func_round( cur_dist,
+                                 CUR.tt_metrics.compensations[0] ) - cur_dist;
+    }
+    else
+      distance = 0;
+
+    CUR_Func_move( &CUR.zp0, point, distance );
+
+    CUR.GS.rp0 = point;
+    CUR.GS.rp1 = point;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MIAP[a]:      Move Indirect Absolute Point                            */
+  /* Opcode range: 0x3E-0x3F                                               */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_MIAP( INS_ARG )
+  {
+    TT_ULong    cvtEntry;
+    TT_UShort   point;
+    TT_F26Dot6  distance,
+                org_dist;
+
+
+    cvtEntry = (TT_ULong)args[1];
+    point    = (TT_UShort)args[0];
+
+    if ( BOUNDS( point,    CUR.zp0.n_points ) ||
+         BOUNDS( cvtEntry, CUR.cvtSize )      )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    /* UNDOCUMENTED!                                     */
+    /*                                                   */
+    /* The behaviour of an MIAP instruction is quite     */
+    /* different when used in the twilight zone.         */
+    /*                                                   */
+    /* First, no control value cutin test is performed   */
+    /* as it would fail anyway.  Second, the original    */
+    /* point, i.e. (org_x,org_y) of zp0.point, is set    */
+    /* to the absolute, unrounded distance found in      */
+    /* the CVT.                                          */
+    /*                                                   */
+    /* This is used in the CVT programs of the Microsoft */
+    /* fonts Arial, Times, etc., in order to re-adjust   */
+    /* some key font heights.  It allows the use of the  */
+    /* IP instruction in the twilight zone, which        */
+    /* otherwise would be `illegal' according to the     */
+    /* specs :)                                          */
+    /*                                                   */
+    /* We implement it with a special sequence for the   */
+    /* twilight zone.  This is a bad hack, but it seems  */
+    /* to work.                                          */
+
+    distance = CUR_Func_read_cvt( cvtEntry );
+
+    if ( CUR.GS.gep0 == 0 )   /* If in twilight zone */
+    {
+      CUR.zp0.org[point].x = TT_MULDIV( CUR.GS.freeVector.x,
+                                        distance, 0x4000 );
+      CUR.zp0.org[point].y = TT_MULDIV( CUR.GS.freeVector.y,
+                                        distance, 0x4000 );
+      CUR.zp0.cur[point] = CUR.zp0.org[point];
+    }
+
+    org_dist = CUR_Func_project( CUR.zp0.cur + point, NULL_Vector );
+
+    if ( (CUR.opcode & 1) != 0 )   /* rounding and control cutin flag */
+    {
+      if ( ABS( distance - org_dist ) > CUR.GS.control_value_cutin )
+        distance = org_dist;
+
+      distance = CUR_Func_round( distance, CUR.tt_metrics.compensations[0] );
+    }
+
+    CUR_Func_move( &CUR.zp0, point, distance - org_dist );
+
+    CUR.GS.rp0 = point;
+    CUR.GS.rp1 = point;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MDRP[abcde]:  Move Direct Relative Point                              */
+  /* Opcode range: 0xC0-0xDF                                               */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_MDRP( INS_ARG )
+  {
+    TT_UShort   point;
+    TT_F26Dot6  org_dist, distance;
+
+
+    point = (TT_UShort)args[0];
+
+    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
+         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    /* XXX: Is there some undocumented feature while in the */
+    /*      twilight zone?                                  */
+
+    org_dist = CUR_Func_dualproj( CUR.zp1.org + point,
+                                  CUR.zp0.org + CUR.GS.rp0 );
+
+    /* single width cutin test */
+
+    if ( ABS( org_dist ) < CUR.GS.single_width_cutin )
+    {
+      if ( org_dist >= 0 )
+        org_dist = CUR.GS.single_width_value;
+      else
+        org_dist = -CUR.GS.single_width_value;
+    }
+
+    /* round flag */
+
+    if ( (CUR.opcode & 4) != 0 )
+      distance = CUR_Func_round( org_dist,
+                                 CUR.tt_metrics.compensations[CUR.opcode & 3] );
+    else
+      distance = ROUND_None( org_dist,
+                             CUR.tt_metrics.compensations[CUR.opcode & 3]  );
+
+    /* minimum distance flag */
+
+    if ( (CUR.opcode & 8) != 0 )
+    {
+      if ( org_dist >= 0 )
+      {
+        if ( distance < CUR.GS.minimum_distance )
+          distance = CUR.GS.minimum_distance;
+      }
+      else
+      {
+        if ( distance > -CUR.GS.minimum_distance )
+          distance = -CUR.GS.minimum_distance;
+      }
+    }
+
+    /* now move the point */
+
+    org_dist = CUR_Func_project( CUR.zp1.cur + point,
+                                 CUR.zp0.cur + CUR.GS.rp0 );
+
+    CUR_Func_move( &CUR.zp1, point, distance - org_dist );
+
+    CUR.GS.rp1 = CUR.GS.rp0;
+    CUR.GS.rp2 = point;
+
+    if ( (CUR.opcode & 16) != 0 )
+      CUR.GS.rp0 = point;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MIRP[abcde]:  Move Indirect Relative Point                            */
+  /* Opcode range: 0xE0-0xFF                                               */
+  /* Stack:        int32? uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_MIRP( INS_ARG )
+  {
+    TT_UShort   point;
+    TT_ULong    cvtEntry;
+
+    TT_F26Dot6  cvt_dist,
+                distance,
+                cur_dist,
+                org_dist;
+
+
+    point    = (TT_UShort)args[0];
+    cvtEntry = (TT_ULong)(args[1] + 1);
+
+    /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */
+
+    if ( BOUNDS( point,      CUR.zp1.n_points ) ||
+         BOUNDS( cvtEntry,   CUR.cvtSize + 1 )  ||
+         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    if ( !cvtEntry )
+      cvt_dist = 0;
+    else
+      cvt_dist = CUR_Func_read_cvt( cvtEntry - 1 );
+
+    /* single width test */
+
+    if ( ABS( cvt_dist ) < CUR.GS.single_width_cutin )
+    {
+      if ( cvt_dist >= 0 )
+        cvt_dist =  CUR.GS.single_width_value;
+      else
+        cvt_dist = -CUR.GS.single_width_value;
+    }
+
+    /* XXX: UNDOCUMENTED! -- twilight zone */
+
+    if ( CUR.GS.gep1 == 0 )
+    {
+      CUR.zp1.org[point].x = CUR.zp0.org[CUR.GS.rp0].x +
+                             TT_MULDIV( cvt_dist,
+                                        CUR.GS.freeVector.x,
+                                        0x4000 );
+
+      CUR.zp1.org[point].y = CUR.zp0.org[CUR.GS.rp0].y +
+                             TT_MULDIV( cvt_dist,
+                                        CUR.GS.freeVector.y,
+                                        0x4000 );
+
+      CUR.zp1.cur[point] = CUR.zp1.org[point];
+    }
+
+    org_dist = CUR_Func_dualproj( CUR.zp1.org + point,
+                                  CUR.zp0.org + CUR.GS.rp0 );
+
+    cur_dist = CUR_Func_project( CUR.zp1.cur + point,
+                                 CUR.zp0.cur + CUR.GS.rp0 );
+
+    /* auto-flip test */
+
+    if ( CUR.GS.auto_flip )
+    {
+      if ( (org_dist ^ cvt_dist) < 0 )
+        cvt_dist = -cvt_dist;
+    }
+
+    /* control value cutin and round */
+
+    if ( (CUR.opcode & 4) != 0 )
+    {
+      /* XXX: UNDOCUMENTED!  Only perform cut-in test when both points */
+      /*      refer to the same zone.                                  */
+
+      if ( CUR.GS.gep0 == CUR.GS.gep1 )
+        if ( ABS( cvt_dist - org_dist ) >= CUR.GS.control_value_cutin )
+          cvt_dist = org_dist;
+
+      distance = CUR_Func_round( cvt_dist,
+                                 CUR.tt_metrics.compensations[CUR.opcode & 3] );
+    }
+    else
+      distance = ROUND_None( cvt_dist,
+                             CUR.tt_metrics.compensations[CUR.opcode & 3] );
+
+    /* minimum distance test */
+
+    if ( (CUR.opcode & 8) != 0 )
+    {
+      if ( org_dist >= 0 )
+      {
+        if ( distance < CUR.GS.minimum_distance )
+          distance = CUR.GS.minimum_distance;
+      }
+      else
+      {
+        if ( distance > -CUR.GS.minimum_distance )
+          distance = -CUR.GS.minimum_distance;
+      }
+    }
+
+    CUR_Func_move( &CUR.zp1, point, distance - cur_dist );
+
+    CUR.GS.rp1 = CUR.GS.rp0;
+
+    if ( (CUR.opcode & 16) != 0 )
+      CUR.GS.rp0 = point;
+
+    /* XXX: UNDOCUMENTED! */
+
+    CUR.GS.rp2 = point;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ALIGNRP[]:    ALIGN Relative Point                                    */
+  /* Opcode range: 0x3C                                                    */
+  /* Stack:        uint32 uint32... -->                                    */
+  /*                                                                       */
+  static
+  void  Ins_ALIGNRP( INS_ARG )
+  {
+    TT_UShort   point;
+    TT_F26Dot6  distance;
+
+
+    UNUSED_ARG;
+
+    if ( CUR.top < CUR.GS.loop ||
+         BOUNDS( CUR.GS.rp0, CUR.zp0.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    while ( CUR.GS.loop > 0 )
+    {
+      CUR.args--;
+
+      point = (TT_UShort)CUR.stack[CUR.args];
+
+      if ( BOUNDS( point, CUR.zp1.n_points ) )
+      {
+        if ( CUR.pedantic_hinting )
+        {
+          CUR.error = TT_Err_Invalid_Reference;
+          return;
+        }
+      }
+      else
+      {
+        distance = CUR_Func_project( CUR.zp1.cur + point,
+                                     CUR.zp0.cur + CUR.GS.rp0 );
+
+        CUR_Func_move( &CUR.zp1, point, -distance );
+      }
+
+      CUR.GS.loop--;
+    }
+
+    CUR.GS.loop = 1;
+    CUR.new_top = CUR.args;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ISECT[]:      moves point to InterSECTion                             */
+  /* Opcode range: 0x0F                                                    */
+  /* Stack:        5 * uint32 -->                                          */
+  /*                                                                       */
+  static
+  void  Ins_ISECT( INS_ARG )
+  {
+    TT_UShort   point,
+                a0, a1,
+                b0, b1;
+
+    TT_F26Dot6  discriminant;
+
+    TT_F26Dot6  dx,  dy,
+                dax, day,
+                dbx, dby;
+
+    TT_F26Dot6  val;
+
+    TT_Vector   R;
+
+
+    point = (TT_UShort)args[0];
+
+    a0 = (TT_UShort)args[1];
+    a1 = (TT_UShort)args[2];
+    b0 = (TT_UShort)args[3];
+    b1 = (TT_UShort)args[4];
+
+    if ( BOUNDS( b0, CUR.zp0.n_points )  ||
+         BOUNDS( b1, CUR.zp0.n_points )  ||
+         BOUNDS( a0, CUR.zp1.n_points )  ||
+         BOUNDS( a1, CUR.zp1.n_points )  ||
+         BOUNDS( point, CUR.zp2.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    dbx = CUR.zp0.cur[b1].x - CUR.zp0.cur[b0].x;
+    dby = CUR.zp0.cur[b1].y - CUR.zp0.cur[b0].y;
+
+    dax = CUR.zp1.cur[a1].x - CUR.zp1.cur[a0].x;
+    day = CUR.zp1.cur[a1].y - CUR.zp1.cur[a0].y;
+
+    dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x;
+    dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y;
+
+    CUR.zp2.touch[point] |= FT_Curve_Tag_Touch_Both;
+
+    discriminant = TT_MULDIV( dax, -dby, 0x40 ) +
+                   TT_MULDIV( day, dbx, 0x40 );
+
+    if ( ABS( discriminant ) >= 0x40 )
+    {
+      val = TT_MULDIV( dx, -dby, 0x40 ) + TT_MULDIV( dy, dbx, 0x40 );
+
+      R.x = TT_MULDIV( val, dax, discriminant );
+      R.y = TT_MULDIV( val, day, discriminant );
+
+      CUR.zp2.cur[point].x = CUR.zp1.cur[a0].x + R.x;
+      CUR.zp2.cur[point].y = CUR.zp1.cur[a0].y + R.y;
+    }
+    else
+    {
+      /* else, take the middle of the middles of A and B */
+
+      CUR.zp2.cur[point].x = ( CUR.zp1.cur[a0].x +
+                               CUR.zp1.cur[a1].x +
+                               CUR.zp0.cur[b0].x +
+                               CUR.zp0.cur[b1].x ) / 4;
+      CUR.zp2.cur[point].y = ( CUR.zp1.cur[a0].y +
+                               CUR.zp1.cur[a1].y +
+                               CUR.zp0.cur[b0].y +
+                               CUR.zp0.cur[b1].y ) / 4;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* ALIGNPTS[]:   ALIGN PoinTS                                            */
+  /* Opcode range: 0x27                                                    */
+  /* Stack:        uint32 uint32 -->                                       */
+  /*                                                                       */
+  static
+  void  Ins_ALIGNPTS( INS_ARG )
+  {
+    TT_UShort   p1, p2;
+    TT_F26Dot6  distance;
+
+
+    p1 = (TT_UShort)args[0];
+    p2 = (TT_UShort)args[1];
+
+    if ( BOUNDS( args[0], CUR.zp1.n_points ) ||
+         BOUNDS( args[1], CUR.zp0.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    distance = CUR_Func_project( CUR.zp0.cur + p2,
+                                 CUR.zp1.cur + p1 ) / 2;
+
+    CUR_Func_move( &CUR.zp1, p1, distance );
+    CUR_Func_move( &CUR.zp0, p2, -distance );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* IP[]:         Interpolate Point                                       */
+  /* Opcode range: 0x39                                                    */
+  /* Stack:        uint32... -->                                           */
+  /*                                                                       */
+  static
+  void  Ins_IP( INS_ARG )
+  {
+    TT_F26Dot6  org_a, org_b, org_x,
+                cur_a, cur_b, cur_x,
+                distance;
+    TT_UShort   point;
+
+
+    UNUSED_ARG;
+
+    if ( CUR.top < CUR.GS.loop )
+    {
+      CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    /* XXX: there are some glyphs in some braindead but popular  */
+    /*      fonts out there (e.g. [aeu]grave in monotype.ttf)    */
+    /*      calling IP[] with bad values of rp[12].              */
+    /*      Do something sane when this odd thing happens.       */
+
+    if ( BOUNDS( CUR.GS.rp1, CUR.zp0.n_points ) ||
+         BOUNDS( CUR.GS.rp2, CUR.zp1.n_points ) )
+    {
+      org_a = cur_a = 0;
+      org_b = cur_b = 0;
+    }
+    else
+    {
+      org_a = CUR_Func_dualproj( CUR.zp0.org + CUR.GS.rp1, NULL_Vector );
+      org_b = CUR_Func_dualproj( CUR.zp1.org + CUR.GS.rp2, NULL_Vector );
+
+      cur_a = CUR_Func_project( CUR.zp0.cur + CUR.GS.rp1, NULL_Vector );
+      cur_b = CUR_Func_project( CUR.zp1.cur + CUR.GS.rp2, NULL_Vector );
+    }
+
+    while ( CUR.GS.loop > 0 )
+    {
+      CUR.args--;
+
+      point = (TT_UShort)CUR.stack[CUR.args];
+      if ( BOUNDS( point, CUR.zp2.n_points ) )
+      {
+        if ( CUR.pedantic_hinting )
+        {
+          CUR.error = TT_Err_Invalid_Reference;
+          return;
+        }
+      }
+      else
+      {
+        org_x = CUR_Func_dualproj( CUR.zp2.org + point, NULL_Vector );
+        cur_x = CUR_Func_project ( CUR.zp2.cur + point, NULL_Vector );
+
+        if ( ( org_a <= org_b && org_x <= org_a ) ||
+             ( org_a >  org_b && org_x >= org_a ) )
+
+          distance = ( cur_a - org_a ) + ( org_x - cur_x );
+
+        else if ( ( org_a <= org_b  &&  org_x >= org_b ) ||
+                  ( org_a >  org_b  &&  org_x <  org_b ) )
+
+          distance = ( cur_b - org_b ) + ( org_x - cur_x );
+
+        else
+           /* note: it seems that rounding this value isn't a good */
+           /*       idea (cf. width of capital `S' in Times)       */
+
+           distance = TT_MULDIV( cur_b - cur_a,
+                                 org_x - org_a,
+                                 org_b - org_a ) + ( cur_a - cur_x );
+
+        CUR_Func_move( &CUR.zp2, point, distance );
+      }
+
+      CUR.GS.loop--;
+    }
+
+    CUR.GS.loop = 1;
+    CUR.new_top = CUR.args;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* UTP[a]:       UnTouch Point                                           */
+  /* Opcode range: 0x29                                                    */
+  /* Stack:        uint32 -->                                              */
+  /*                                                                       */
+  static
+  void  Ins_UTP( INS_ARG )
+  {
+    TT_UShort  point;
+    TT_Byte    mask;
+
+
+    point = (TT_UShort)args[0];
+
+    if ( BOUNDS( point, CUR.zp0.n_points ) )
+    {
+      if ( CUR.pedantic_hinting )
+        CUR.error = TT_Err_Invalid_Reference;
+      return;
+    }
+
+    mask = 0xFF;
+
+    if ( CUR.GS.freeVector.x != 0 )
+      mask &= ~FT_Curve_Tag_Touch_X;
+
+    if ( CUR.GS.freeVector.y != 0 )
+      mask &= ~FT_Curve_Tag_Touch_Y;
+
+    CUR.zp0.touch[point] &= mask;
+  }
+
+
+  /* Local variables for Ins_IUP: */
+  struct LOC_Ins_IUP
+  {
+    TT_Vector*  orgs;   /* original and current coordinate */
+    TT_Vector*  curs;   /* arrays                          */
+  };
+
+
+  static void  Shift( TT_UInt              p1,
+                      TT_UInt              p2,
+                      TT_UInt              p,
+                      struct LOC_Ins_IUP*  LINK )
+  {
+    TT_UInt     i;
+    TT_F26Dot6  x;
+
+    x = LINK->curs[p].x - LINK->orgs[p].x;
+
+    for ( i = p1; i < p; i++ )
+      LINK->curs[i].x += x;
+
+    for ( i = p + 1; i <= p2; i++ )
+      LINK->curs[i].x += x;
+  }
+
+
+  static void  Interp( TT_UInt              p1,
+                       TT_UInt              p2,
+                       TT_UInt              ref1,
+                       TT_UInt              ref2,
+                       struct LOC_Ins_IUP*  LINK )
+  {
+    TT_UInt     i;
+    TT_F26Dot6  x, x1, x2, d1, d2;
+
+    if ( p1 > p2 )
+      return;
+
+    x1 = LINK->orgs[ref1].x;
+    d1 = LINK->curs[ref1].x - LINK->orgs[ref1].x;
+    x2 = LINK->orgs[ref2].x;
+    d2 = LINK->curs[ref2].x - LINK->orgs[ref2].x;
+
+    if ( x1 == x2 )
+    {
+      for ( i = p1; i <= p2; i++ )
+      {
+        x = LINK->orgs[i].x;
+
+        if ( x <= x1 )
+          x += d1;
+        else
+          x += d2;
+
+        LINK->curs[i].x = x;
+      }
+      return;
+    }
+
+    if ( x1 < x2 )
+    {
+      for ( i = p1; i <= p2; i++ )
+      {
+        x = LINK->orgs[i].x;
+
+        if ( x <= x1 )
+          x += d1;
+        else
+        {
+          if ( x >= x2 )
+            x += d2;
+          else
+            x = LINK->curs[ref1].x +
+                  TT_MULDIV( x - x1,
+                             LINK->curs[ref2].x - LINK->curs[ref1].x,
+                             x2 - x1 );
+        }
+        LINK->curs[i].x = x;
+      }
+      return;
+    }
+
+    /* x2 < x1 */
+
+    for ( i = p1; i <= p2; i++ )
+    {
+      x = LINK->orgs[i].x;
+      if ( x <= x2 )
+        x += d2;
+      else
+      {
+        if ( x >= x1 )
+          x += d1;
+        else
+          x = LINK->curs[ref1].x +
+              TT_MULDIV( x - x1,
+                         LINK->curs[ref2].x - LINK->curs[ref1].x,
+                         x2 - x1 );
+      }
+      LINK->curs[i].x = x;
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* IUP[a]:       Interpolate Untouched Points                            */
+  /* Opcode range: 0x30-0x31                                               */
+  /* Stack:        -->                                                     */
+  /*                                                                       */
+  static
+  void  Ins_IUP( INS_ARG )
+  {
+    struct LOC_Ins_IUP  V;
+    TT_Byte             mask;
+
+    TT_UInt   first_point;   /* first point of contour        */
+    TT_UInt   end_point;     /* end point (last+1) of contour */
+
+    TT_UInt   first_touched; /* first touched point in contour   */
+    TT_UInt   cur_touched;   /* current touched point in contour */
+
+    TT_UInt   point;         /* current point   */
+    TT_Short  contour;       /* current contour */
+
+
+    UNUSED_ARG;
+
+    if ( CUR.opcode & 1 )
+    {
+      mask   = FT_Curve_Tag_Touch_X;
+      V.orgs = CUR.pts.org;
+      V.curs = CUR.pts.cur;
+    }
+    else
+    {
+      mask   = FT_Curve_Tag_Touch_Y;
+      V.orgs = (TT_Vector*)( ((TT_F26Dot6*)CUR.pts.org) + 1 );
+      V.curs = (TT_Vector*)( ((TT_F26Dot6*)CUR.pts.cur) + 1 );
+    }
+
+    contour = 0;
+    point   = 0;
+
+    do
+    {
+      end_point   = CUR.pts.contours[contour];
+      first_point = point;
+
+      while ( point <= end_point && (CUR.pts.touch[point] & mask) == 0 )
+        point++;
+
+      if ( point <= end_point )
+      {
+        first_touched = point;
+        cur_touched   = point;
+
+        point++;
+
+        while ( point <= end_point )
+        {
+          if ( (CUR.pts.touch[point] & mask) != 0 )
+          {
+            if ( point > 0 )
+              Interp( cur_touched + 1,
+                      point - 1,
+                      cur_touched,
+                      point,
+                      &V );
+            cur_touched = point;
+          }
+
+          point++;
+        }
+
+        if ( cur_touched == first_touched )
+          Shift( first_point, end_point, cur_touched, &V );
+        else
+        {
+          Interp( (TT_UShort)(cur_touched + 1),
+                  end_point,
+                  cur_touched,
+                  first_touched,
+                  &V );
+
+          if ( first_touched > 0 )
+            Interp( first_point,
+                    first_touched - 1,
+                    cur_touched,
+                    first_touched,
+                    &V );
+        }
+      }
+      contour++;
+    } while ( contour < CUR.pts.n_contours );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DELTAPn[]:    DELTA exceptions P1, P2, P3                             */
+  /* Opcode range: 0x5D,0x71,0x72                                          */
+  /* Stack:        uint32 (2 * uint32)... -->                              */
+  /*                                                                       */
+  static
+  void  Ins_DELTAP( INS_ARG )
+  {
+    TT_ULong   k, nump;
+    TT_UShort  A;
+    TT_ULong   C;
+    TT_Long    B;
+
+
+    nump = (TT_ULong)args[0];   /* some points theoretically may occur more
+                                   than once, thus UShort isn't enough */
+
+    for ( k = 1; k <= nump; k++ )
+    {
+      if ( CUR.args < 2 )
+      {
+        CUR.error = TT_Err_Too_Few_Arguments;
+        return;
+      }
+
+      CUR.args -= 2;
+
+      A = (TT_UShort)CUR.stack[CUR.args + 1];
+      B = CUR.stack[CUR.args];
+
+      /* XXX : because some popular fonts contain some invalid DeltaP */
+      /*       instructions, we simply ignore them when the stacked   */
+      /*       point reference is off limit, rather than returning an */
+      /*       error. As a delta instruction doesn't change a glyph   */
+      /*       in great ways, this shouldn't be a problem..           */
+
+      if ( !BOUNDS( A, CUR.zp0.n_points ) )
+      {
+        C = ((TT_ULong)B & 0xF0) >> 4;
+
+        switch ( CUR.opcode )
+        {
+        case 0x5D:
+          break;
+
+        case 0x71:
+          C += 16;
+          break;
+
+        case 0x72:
+          C += 32;
+          break;
+        }
+
+        C += CUR.GS.delta_base;
+
+        if ( CURRENT_Ppem() == (TT_Long)C )
+        {
+          B = ((TT_ULong)B & 0xF) - 8;
+          if ( B >= 0 )
+            B++;
+          B = B * 64 / (1L << CUR.GS.delta_shift);
+
+          CUR_Func_move( &CUR.zp0, A, B );
+        }
+      }
+      else
+        if ( CUR.pedantic_hinting )
+          CUR.error = TT_Err_Invalid_Reference;
+    }
+
+    CUR.new_top = CUR.args;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* DELTACn[]:    DELTA exceptions C1, C2, C3                             */
+  /* Opcode range: 0x73,0x74,0x75                                          */
+  /* Stack:        uint32 (2 * uint32)... -->                              */
+  /*                                                                       */
+  static
+  void  Ins_DELTAC( INS_ARG )
+  {
+    TT_ULong  nump, k;
+    TT_ULong  A, C;
+    TT_Long   B;
+
+
+    nump = (TT_ULong)args[0];
+
+    for ( k = 1; k <= nump; k++ )
+    {
+      if ( CUR.args < 2 )
+      {
+        CUR.error = TT_Err_Too_Few_Arguments;
+        return;
+      }
+
+      CUR.args -= 2;
+
+      A = (TT_ULong)CUR.stack[CUR.args + 1];
+      B = CUR.stack[CUR.args];
+
+      if ( BOUNDS( A, CUR.cvtSize ) )
+      {
+        if (CUR.pedantic_hinting)
+        {
+          CUR.error = TT_Err_Invalid_Reference;
+          return;
+        }
+      }
+      else
+      {
+        C = ((TT_ULong)B & 0xF0) >> 4;
+
+        switch ( CUR.opcode )
+        {
+        case 0x73:
+          break;
+
+        case 0x74:
+          C += 16;
+          break;
+
+        case 0x75:
+          C += 32;
+          break;
+        }
+
+        C += CUR.GS.delta_base;
+
+        if ( CURRENT_Ppem() == (TT_Long)C )
+        {
+          B = ((TT_ULong)B & 0xF) - 8;
+          if ( B >= 0 )
+            B++;
+          B = B * 64 / (1L << CUR.GS.delta_shift);
+
+          CUR_Func_move_cvt( A, B );
+        }
+      }
+    }
+
+    CUR.new_top = CUR.args;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* MISC. INSTRUCTIONS                                                    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* GETINFO[]:    GET INFOrmation                                         */
+  /* Opcode range: 0x88                                                    */
+  /* Stack:        uint32 --> uint32                                       */
+  /*                                                                       */
+  /* XXX: According to Apple specs, bits 1 & 2 of the argument ought to be */
+  /*      consulted before rotated/stretched info is returned.             */
+  static
+  void  Ins_GETINFO( INS_ARG )
+  {
+    TT_Long  K;
+
+
+    K = 0;
+
+    /* We return then Windows 3.1 version number */
+    /* for the font scaler                       */
+    if ( (args[0] & 1) != 0 )
+      K = 3;
+
+    /* Has the glyph been rotated ? */
+    if ( CUR.tt_metrics.rotated )
+      K |= 0x80;
+
+    /* Has the glyph been stretched ? */
+    if ( CUR.tt_metrics.stretched )
+      K |= 0x100;
+
+    args[0] = K;
+  }
+
+
+  static
+  void  Ins_UNKNOWN( INS_ARG )
+  {
+    TT_DefRecord*  def   = CUR.IDefs;
+    TT_DefRecord*  limit = def + CUR.numIDefs;
+    
+    UNUSED_ARG;
+ 
+    for ( ; def < limit; def++ )
+    {
+      if (def->opc == CUR.opcode && def->active )
+      {
+        TT_CallRec*  call;
+        
+        if ( CUR.callTop >= CUR.callSize )
+        {
+          CUR.error = TT_Err_Stack_Overflow;
+          return;
+        }
+        
+        call = CUR.callStack + CUR.callTop++;
+
+        call->Caller_Range = CUR.curRange;
+        call->Caller_IP    = CUR.IP+1;
+        call->Cur_Count    = 1;
+        call->Cur_Restart  = def->start;
+        
+        INS_Goto_CodeRange( def->range, def->start );
+        
+        CUR.step_ins = FALSE;
+        return;
+      }
+    }
+
+    CUR.error = TT_Err_Invalid_Opcode;
+  }
+
+
+#ifndef TT_CONFIG_OPTION_INTERPRETER_SWITCH
+  static
+  TInstruction_Function  Instruct_Dispatch[256] =
+  {
+    /* Opcodes are gathered in groups of 16. */
+    /* Please keep the spaces as they are.   */
+
+    /*  SVTCA  y  */  Ins_SVTCA,
+    /*  SVTCA  x  */  Ins_SVTCA,
+    /*  SPvTCA y  */  Ins_SPVTCA,
+    /*  SPvTCA x  */  Ins_SPVTCA,
+    /*  SFvTCA y  */  Ins_SFVTCA,
+    /*  SFvTCA x  */  Ins_SFVTCA,
+    /*  SPvTL //  */  Ins_SPVTL,
+    /*  SPvTL +   */  Ins_SPVTL,
+    /*  SFvTL //  */  Ins_SFVTL,
+    /*  SFvTL +   */  Ins_SFVTL,
+    /*  SPvFS     */  Ins_SPVFS,
+    /*  SFvFS     */  Ins_SFVFS,
+    /*  GPV       */  Ins_GPV,
+    /*  GFV       */  Ins_GFV,
+    /*  SFvTPv    */  Ins_SFVTPV,
+    /*  ISECT     */  Ins_ISECT,
+
+    /*  SRP0      */  Ins_SRP0,
+    /*  SRP1      */  Ins_SRP1,
+    /*  SRP2      */  Ins_SRP2,
+    /*  SZP0      */  Ins_SZP0,
+    /*  SZP1      */  Ins_SZP1,
+    /*  SZP2      */  Ins_SZP2,
+    /*  SZPS      */  Ins_SZPS,
+    /*  SLOOP     */  Ins_SLOOP,
+    /*  RTG       */  Ins_RTG,
+    /*  RTHG      */  Ins_RTHG,
+    /*  SMD       */  Ins_SMD,
+    /*  ELSE      */  Ins_ELSE,
+    /*  JMPR      */  Ins_JMPR,
+    /*  SCvTCi    */  Ins_SCVTCI,
+    /*  SSwCi     */  Ins_SSWCI,
+    /*  SSW       */  Ins_SSW,
+
+    /*  DUP       */  Ins_DUP,
+    /*  POP       */  Ins_POP,
+    /*  CLEAR     */  Ins_CLEAR,
+    /*  SWAP      */  Ins_SWAP,
+    /*  DEPTH     */  Ins_DEPTH,
+    /*  CINDEX    */  Ins_CINDEX,
+    /*  MINDEX    */  Ins_MINDEX,
+    /*  AlignPTS  */  Ins_ALIGNPTS,
+    /*  INS_0x28  */  Ins_UNKNOWN,
+    /*  UTP       */  Ins_UTP,
+    /*  LOOPCALL  */  Ins_LOOPCALL,
+    /*  CALL      */  Ins_CALL,
+    /*  FDEF      */  Ins_FDEF,
+    /*  ENDF      */  Ins_ENDF,
+    /*  MDAP[0]   */  Ins_MDAP,
+    /*  MDAP[1]   */  Ins_MDAP,
+
+    /*  IUP[0]    */  Ins_IUP,
+    /*  IUP[1]    */  Ins_IUP,
+    /*  SHP[0]    */  Ins_SHP,
+    /*  SHP[1]    */  Ins_SHP,
+    /*  SHC[0]    */  Ins_SHC,
+    /*  SHC[1]    */  Ins_SHC,
+    /*  SHZ[0]    */  Ins_SHZ,
+    /*  SHZ[1]    */  Ins_SHZ,
+    /*  SHPIX     */  Ins_SHPIX,
+    /*  IP        */  Ins_IP,
+    /*  MSIRP[0]  */  Ins_MSIRP,
+    /*  MSIRP[1]  */  Ins_MSIRP,
+    /*  AlignRP   */  Ins_ALIGNRP,
+    /*  RTDG      */  Ins_RTDG,
+    /*  MIAP[0]   */  Ins_MIAP,
+    /*  MIAP[1]   */  Ins_MIAP,
+
+    /*  NPushB    */  Ins_NPUSHB,
+    /*  NPushW    */  Ins_NPUSHW,
+    /*  WS        */  Ins_WS,
+    /*  RS        */  Ins_RS,
+    /*  WCvtP     */  Ins_WCVTP,
+    /*  RCvt      */  Ins_RCVT,
+    /*  GC[0]     */  Ins_GC,
+    /*  GC[1]     */  Ins_GC,
+    /*  SCFS      */  Ins_SCFS,
+    /*  MD[0]     */  Ins_MD,
+    /*  MD[1]     */  Ins_MD,
+    /*  MPPEM     */  Ins_MPPEM,
+    /*  MPS       */  Ins_MPS,
+    /*  FlipON    */  Ins_FLIPON,
+    /*  FlipOFF   */  Ins_FLIPOFF,
+    /*  DEBUG     */  Ins_DEBUG,
+
+    /*  LT        */  Ins_LT,
+    /*  LTEQ      */  Ins_LTEQ,
+    /*  GT        */  Ins_GT,
+    /*  GTEQ      */  Ins_GTEQ,
+    /*  EQ        */  Ins_EQ,
+    /*  NEQ       */  Ins_NEQ,
+    /*  ODD       */  Ins_ODD,
+    /*  EVEN      */  Ins_EVEN,
+    /*  IF        */  Ins_IF,
+    /*  EIF       */  Ins_EIF,
+    /*  AND       */  Ins_AND,
+    /*  OR        */  Ins_OR,
+    /*  NOT       */  Ins_NOT,
+    /*  DeltaP1   */  Ins_DELTAP,
+    /*  SDB       */  Ins_SDB,
+    /*  SDS       */  Ins_SDS,
+
+    /*  ADD       */  Ins_ADD,
+    /*  SUB       */  Ins_SUB,
+    /*  DIV       */  Ins_DIV,
+    /*  MUL       */  Ins_MUL,
+    /*  ABS       */  Ins_ABS,
+    /*  NEG       */  Ins_NEG,
+    /*  FLOOR     */  Ins_FLOOR,
+    /*  CEILING   */  Ins_CEILING,
+    /*  ROUND[0]  */  Ins_ROUND,
+    /*  ROUND[1]  */  Ins_ROUND,
+    /*  ROUND[2]  */  Ins_ROUND,
+    /*  ROUND[3]  */  Ins_ROUND,
+    /*  NROUND[0] */  Ins_NROUND,
+    /*  NROUND[1] */  Ins_NROUND,
+    /*  NROUND[2] */  Ins_NROUND,
+    /*  NROUND[3] */  Ins_NROUND,
+
+    /*  WCvtF     */  Ins_WCVTF,
+    /*  DeltaP2   */  Ins_DELTAP,
+    /*  DeltaP3   */  Ins_DELTAP,
+    /*  DeltaCn[0] */ Ins_DELTAC,
+    /*  DeltaCn[1] */ Ins_DELTAC,
+    /*  DeltaCn[2] */ Ins_DELTAC,
+    /*  SROUND    */  Ins_SROUND,
+    /*  S45Round  */  Ins_S45ROUND,
+    /*  JROT      */  Ins_JROT,
+    /*  JROF      */  Ins_JROF,
+    /*  ROFF      */  Ins_ROFF,
+    /*  INS_0x7B  */  Ins_UNKNOWN,
+    /*  RUTG      */  Ins_RUTG,
+    /*  RDTG      */  Ins_RDTG,
+    /*  SANGW     */  Ins_SANGW,
+    /*  AA        */  Ins_AA,
+
+    /*  FlipPT    */  Ins_FLIPPT,
+    /*  FlipRgON  */  Ins_FLIPRGON,
+    /*  FlipRgOFF */  Ins_FLIPRGOFF,
+    /*  INS_0x83  */  Ins_UNKNOWN,
+    /*  INS_0x84  */  Ins_UNKNOWN,
+    /*  ScanCTRL  */  Ins_SCANCTRL,
+    /*  SDPVTL[0] */  Ins_SDPVTL,
+    /*  SDPVTL[1] */  Ins_SDPVTL,
+    /*  GetINFO   */  Ins_GETINFO,
+    /*  IDEF      */  Ins_IDEF,
+    /*  ROLL      */  Ins_ROLL,
+    /*  MAX       */  Ins_MAX,
+    /*  MIN       */  Ins_MIN,
+    /*  ScanTYPE  */  Ins_SCANTYPE,
+    /*  InstCTRL  */  Ins_INSTCTRL,
+    /*  INS_0x8F  */  Ins_UNKNOWN,
+
+    /*  INS_0x90  */   Ins_UNKNOWN,
+    /*  INS_0x91  */   Ins_UNKNOWN,
+    /*  INS_0x92  */   Ins_UNKNOWN,
+    /*  INS_0x93  */   Ins_UNKNOWN,
+    /*  INS_0x94  */   Ins_UNKNOWN,
+    /*  INS_0x95  */   Ins_UNKNOWN,
+    /*  INS_0x96  */   Ins_UNKNOWN,
+    /*  INS_0x97  */   Ins_UNKNOWN,
+    /*  INS_0x98  */   Ins_UNKNOWN,
+    /*  INS_0x99  */   Ins_UNKNOWN,
+    /*  INS_0x9A  */   Ins_UNKNOWN,
+    /*  INS_0x9B  */   Ins_UNKNOWN,
+    /*  INS_0x9C  */   Ins_UNKNOWN,
+    /*  INS_0x9D  */   Ins_UNKNOWN,
+    /*  INS_0x9E  */   Ins_UNKNOWN,
+    /*  INS_0x9F  */   Ins_UNKNOWN,
+
+    /*  INS_0xA0  */   Ins_UNKNOWN,
+    /*  INS_0xA1  */   Ins_UNKNOWN,
+    /*  INS_0xA2  */   Ins_UNKNOWN,
+    /*  INS_0xA3  */   Ins_UNKNOWN,
+    /*  INS_0xA4  */   Ins_UNKNOWN,
+    /*  INS_0xA5  */   Ins_UNKNOWN,
+    /*  INS_0xA6  */   Ins_UNKNOWN,
+    /*  INS_0xA7  */   Ins_UNKNOWN,
+    /*  INS_0xA8  */   Ins_UNKNOWN,
+    /*  INS_0xA9  */   Ins_UNKNOWN,
+    /*  INS_0xAA  */   Ins_UNKNOWN,
+    /*  INS_0xAB  */   Ins_UNKNOWN,
+    /*  INS_0xAC  */   Ins_UNKNOWN,
+    /*  INS_0xAD  */   Ins_UNKNOWN,
+    /*  INS_0xAE  */   Ins_UNKNOWN,
+    /*  INS_0xAF  */   Ins_UNKNOWN,
+
+    /*  PushB[0]  */  Ins_PUSHB,
+    /*  PushB[1]  */  Ins_PUSHB,
+    /*  PushB[2]  */  Ins_PUSHB,
+    /*  PushB[3]  */  Ins_PUSHB,
+    /*  PushB[4]  */  Ins_PUSHB,
+    /*  PushB[5]  */  Ins_PUSHB,
+    /*  PushB[6]  */  Ins_PUSHB,
+    /*  PushB[7]  */  Ins_PUSHB,
+    /*  PushW[0]  */  Ins_PUSHW,
+    /*  PushW[1]  */  Ins_PUSHW,
+    /*  PushW[2]  */  Ins_PUSHW,
+    /*  PushW[3]  */  Ins_PUSHW,
+    /*  PushW[4]  */  Ins_PUSHW,
+    /*  PushW[5]  */  Ins_PUSHW,
+    /*  PushW[6]  */  Ins_PUSHW,
+    /*  PushW[7]  */  Ins_PUSHW,
+
+    /*  MDRP[00]  */  Ins_MDRP,
+    /*  MDRP[01]  */  Ins_MDRP,
+    /*  MDRP[02]  */  Ins_MDRP,
+    /*  MDRP[03]  */  Ins_MDRP,
+    /*  MDRP[04]  */  Ins_MDRP,
+    /*  MDRP[05]  */  Ins_MDRP,
+    /*  MDRP[06]  */  Ins_MDRP,
+    /*  MDRP[07]  */  Ins_MDRP,
+    /*  MDRP[08]  */  Ins_MDRP,
+    /*  MDRP[09]  */  Ins_MDRP,
+    /*  MDRP[10]  */  Ins_MDRP,
+    /*  MDRP[11]  */  Ins_MDRP,
+    /*  MDRP[12]  */  Ins_MDRP,
+    /*  MDRP[13]  */  Ins_MDRP,
+    /*  MDRP[14]  */  Ins_MDRP,
+    /*  MDRP[15]  */  Ins_MDRP,
+
+    /*  MDRP[16]  */  Ins_MDRP,
+    /*  MDRP[17]  */  Ins_MDRP,
+    /*  MDRP[18]  */  Ins_MDRP,
+    /*  MDRP[19]  */  Ins_MDRP,
+    /*  MDRP[20]  */  Ins_MDRP,
+    /*  MDRP[21]  */  Ins_MDRP,
+    /*  MDRP[22]  */  Ins_MDRP,
+    /*  MDRP[23]  */  Ins_MDRP,
+    /*  MDRP[24]  */  Ins_MDRP,
+    /*  MDRP[25]  */  Ins_MDRP,
+    /*  MDRP[26]  */  Ins_MDRP,
+    /*  MDRP[27]  */  Ins_MDRP,
+    /*  MDRP[28]  */  Ins_MDRP,
+    /*  MDRP[29]  */  Ins_MDRP,
+    /*  MDRP[30]  */  Ins_MDRP,
+    /*  MDRP[31]  */  Ins_MDRP,
+
+    /*  MIRP[00]  */  Ins_MIRP,
+    /*  MIRP[01]  */  Ins_MIRP,
+    /*  MIRP[02]  */  Ins_MIRP,
+    /*  MIRP[03]  */  Ins_MIRP,
+    /*  MIRP[04]  */  Ins_MIRP,
+    /*  MIRP[05]  */  Ins_MIRP,
+    /*  MIRP[06]  */  Ins_MIRP,
+    /*  MIRP[07]  */  Ins_MIRP,
+    /*  MIRP[08]  */  Ins_MIRP,
+    /*  MIRP[09]  */  Ins_MIRP,
+    /*  MIRP[10]  */  Ins_MIRP,
+    /*  MIRP[11]  */  Ins_MIRP,
+    /*  MIRP[12]  */  Ins_MIRP,
+    /*  MIRP[13]  */  Ins_MIRP,
+    /*  MIRP[14]  */  Ins_MIRP,
+    /*  MIRP[15]  */  Ins_MIRP,
+
+    /*  MIRP[16]  */  Ins_MIRP,
+    /*  MIRP[17]  */  Ins_MIRP,
+    /*  MIRP[18]  */  Ins_MIRP,
+    /*  MIRP[19]  */  Ins_MIRP,
+    /*  MIRP[20]  */  Ins_MIRP,
+    /*  MIRP[21]  */  Ins_MIRP,
+    /*  MIRP[22]  */  Ins_MIRP,
+    /*  MIRP[23]  */  Ins_MIRP,
+    /*  MIRP[24]  */  Ins_MIRP,
+    /*  MIRP[25]  */  Ins_MIRP,
+    /*  MIRP[26]  */  Ins_MIRP,
+    /*  MIRP[27]  */  Ins_MIRP,
+    /*  MIRP[28]  */  Ins_MIRP,
+    /*  MIRP[29]  */  Ins_MIRP,
+    /*  MIRP[30]  */  Ins_MIRP,
+    /*  MIRP[31]  */  Ins_MIRP
+  };
+#endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* RUN                                                                   */
+  /*                                                                       */
+  /*  This function executes a run of opcodes.  It will exit in the        */
+  /*  following cases:                                                     */
+  /*                                                                       */
+  /*  - Errors (in which case it returns FALSE).                           */
+  /*                                                                       */
+  /*  - Reaching the end of the main code range (returns TRUE).            */
+  /*    Reaching the end of a code range within a function call is an      */
+  /*    error.                                                             */
+  /*                                                                       */
+  /*  - After executing one single opcode, if the flag `Instruction_Trap'  */
+  /*    is set to TRUE (returns TRUE).                                     */
+  /*                                                                       */
+  /*  On exit whith TRUE, test IP < CodeSize to know wether it comes from  */
+  /*  an instruction trap or a normal termination.                         */
+  /*                                                                       */
+  /*                                                                       */
+  /*  Note: The documented DEBUG opcode pops a value from the stack.  This */
+  /*        behaviour is unsupported, here a DEBUG opcode is always an     */
+  /*        error.                                                         */
+  /*                                                                       */
+  /*                                                                       */
+  /* THIS IS THE INTERPRETER'S MAIN LOOP.                                  */
+  /*                                                                       */
+  /*  Instructions appear in the specs' order.                             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  EXPORT_FUNC
+#ifndef DEBUG_INTERPRETER
+  TT_Error  TT_RunIns( TT_ExecContext  exc )
+#else
+  TT_Error  TT_RunIns2( TT_ExecContext  exc )
+#endif
+  {
+    TT_Long    ins_counter = 0;  /* executed instructions counter */
+
+#ifdef TT_CONFIG_OPTION_STATIC_RASTER
+    cur = *exc;
+#endif
+
+    /* set CVT functions */
+    CUR.tt_metrics.ratio = 0;
+    if ( CUR.metrics.x_ppem != CUR.metrics.y_ppem )
+    {
+      /* non-square pixels, use the stretched routines */
+      CUR.func_read_cvt  = Read_CVT_Stretched;
+      CUR.func_write_cvt = Write_CVT_Stretched;
+      CUR.func_move_cvt  = Move_CVT_Stretched;
+    }
+    else
+    {
+      /* square pixels, use normal routines */
+      CUR.func_read_cvt  = Read_CVT;
+      CUR.func_write_cvt = Write_CVT;
+      CUR.func_move_cvt  = Move_CVT;
+    }
+
+    COMPUTE_Funcs();
+    COMPUTE_Round( (TT_Byte)exc->GS.round_state );
+
+    do
+    {
+      CUR.opcode = CUR.code[CUR.IP];
+
+      if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
+      {
+        if ( CUR.IP + 1 > CUR.codeSize )
+          goto LErrorCodeOverflow_;
+
+        CUR.length = CUR.code[CUR.IP + 1] + 2;
+      }
+
+      if ( CUR.IP + CUR.length > CUR.codeSize )
+        goto LErrorCodeOverflow_;
+
+      /* First, let's check for empty stack and overflow */
+      CUR.args = CUR.top - (Pop_Push_Count[CUR.opcode] >> 4);
+
+      /* `args' is the top of the stack once arguments have been popped. */
+      /* One can also interpret it as the index of the last argument.    */
+      if ( CUR.args < 0 )
+      {
+        CUR.error = TT_Err_Too_Few_Arguments;
+        goto LErrorLabel_;
+      }
+
+      CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15);
+
+      /* `new_top' is the new top of the stack, after the instruction's */
+      /* execution.  `top' will be set to `new_top' after the `switch'  */
+      /* statement.                                                     */
+      if ( CUR.new_top > CUR.stackSize )
+      {
+        CUR.error = TT_Err_Stack_Overflow;
+        goto LErrorLabel_;
+      }
+
+      CUR.step_ins = TRUE;
+      CUR.error    = TT_Err_Ok;
+
+#ifdef TT_CONFIG_OPTION_INTERPRETER_SWITCH
+      {
+        TT_Long*  args   = CUR.stack + CUR.args;
+        TT_Byte   opcode = CUR.opcode;
+
+
+#undef   ARRAY_BOUND_ERROR
+#define  ARRAY_BOUND_ERROR   goto Set_Invalid_Ref
+
+
+        switch ( opcode )
+        {
+        case 0x00:  /* SVTCA y  */
+        case 0x01:  /* SVTCA x  */
+        case 0x02:  /* SPvTCA y */
+        case 0x03:  /* SPvTCA x */
+        case 0x04:  /* SFvTCA y */
+        case 0x05:  /* SFvTCA x */
+          {
+            TT_Short AA, BB;
+
+
+            AA = (TT_Short)(opcode & 1) << 14;
+            BB = AA ^ (TT_Short)0x4000;
+
+            if ( opcode < 4 )
+            {
+              CUR.GS.projVector.x = AA;
+              CUR.GS.projVector.y = BB;
+
+              CUR.GS.dualVector.x = AA;
+              CUR.GS.dualVector.y = BB;
+            }
+
+            if ( (opcode & 2) == 0 )
+            {
+              CUR.GS.freeVector.x = AA;
+              CUR.GS.freeVector.y = BB;
+            }
+
+            COMPUTE_Funcs();
+          }
+          break;
+
+        case 0x06:  /* SPvTL // */
+        case 0x07:  /* SPvTL +  */
+          DO_SPVTL
+          break;
+
+        case 0x08:  /* SFvTL // */
+        case 0x09:  /* SFvTL +  */
+          DO_SFVTL
+          break;
+
+        case 0x0A:  /* SPvFS */
+          DO_SPVFS
+          break;
+
+        case 0x0B:  /* SFvFS */
+          DO_SFVFS
+          break;
+
+        case 0x0C:  /* GPV */
+          DO_GPV
+          break;
+
+        case 0x0D:  /* GFV */
+          DO_GFV
+          break;
+
+        case 0x0E:  /* SFvTPv */
+          DO_SFVTPV
+          break;
+
+        case 0x0F:  /* ISECT  */
+          Ins_ISECT( EXEC_ARG_  args );
+          break;
+
+        case 0x10:  /* SRP0 */
+          DO_SRP0
+          break;
+
+        case 0x11:  /* SRP1 */
+          DO_SRP1
+          break;
+
+        case 0x12:  /* SRP2 */
+          DO_SRP2
+          break;
+
+        case 0x13:  /* SZP0 */
+          Ins_SZP0( EXEC_ARG_  args );
+          break;
+
+        case 0x14:  /* SZP1 */
+          Ins_SZP1( EXEC_ARG_  args );
+          break;
+
+        case 0x15:  /* SZP2 */
+          Ins_SZP2( EXEC_ARG_  args );
+          break;
+
+        case 0x16:  /* SZPS */
+          Ins_SZPS( EXEC_ARG_  args );
+          break;
+
+        case 0x17:  /* SLOOP */
+          DO_SLOOP
+          break;
+
+        case 0x18:  /* RTG */
+          DO_RTG
+          break;
+
+        case 0x19:  /* RTHG */
+          DO_RTHG
+          break;
+
+        case 0x1A:  /* SMD */
+          DO_SMD
+          break;
+
+        case 0x1B:  /* ELSE */
+          Ins_ELSE( EXEC_ARG_  args );
+          break;
+
+        case 0x1C:  /* JMPR */
+          DO_JMPR
+          break;
+
+        case 0x1D:  /* SCVTCI */
+          DO_SCVTCI
+          break;
+
+        case 0x1E:  /* SSWCI */
+          DO_SSWCI
+          break;
+
+        case 0x1F:  /* SSW */
+          DO_SSW
+          break;
+
+        case 0x20:  /* DUP */
+          DO_DUP
+          break;
+
+        case 0x21:  /* POP */
+          /* nothing :-) ! */
+          break;
+
+        case 0x22:  /* CLEAR */
+          DO_CLEAR
+          break;
+
+        case 0x23:  /* SWAP */
+          DO_SWAP
+          break;
+
+        case 0x24:  /* DEPTH */
+          DO_DEPTH
+          break;
+
+        case 0x25:  /* CINDEX */
+          DO_CINDEX
+          break;
+
+        case 0x26:  /* MINDEX */
+          Ins_MINDEX( EXEC_ARG_  args );
+          break;
+
+        case 0x27:  /* ALIGNPTS */
+          Ins_ALIGNPTS( EXEC_ARG_  args );
+          break;
+
+        case 0x28:  /* ???? */
+          Ins_UNKNOWN( EXEC_ARG_  args );
+          break;
+
+        case 0x29:  /* UTP */
+          Ins_UTP( EXEC_ARG_  args );
+          break;
+
+        case 0x2A:  /* LOOPCALL */
+          Ins_LOOPCALL( EXEC_ARG_  args );
+          break;
+
+        case 0x2B:  /* CALL */
+          Ins_CALL( EXEC_ARG_  args );
+          break;
+
+        case 0x2C:  /* FDEF */
+          Ins_FDEF( EXEC_ARG_  args );
+          break;
+
+        case 0x2D:  /* ENDF */
+          Ins_ENDF( EXEC_ARG_  args );
+          break;
+
+        case 0x2E:  /* MDAP */
+        case 0x2F:  /* MDAP */
+          Ins_MDAP( EXEC_ARG_  args );
+          break;
+
+
+        case 0x30:  /* IUP */
+        case 0x31:  /* IUP */
+          Ins_IUP( EXEC_ARG_  args );
+          break;
+
+        case 0x32:  /* SHP */
+        case 0x33:  /* SHP */
+          Ins_SHP( EXEC_ARG_  args );
+          break;
+
+        case 0x34:  /* SHC */
+        case 0x35:  /* SHC */
+          Ins_SHC( EXEC_ARG_  args );
+          break;
+
+        case 0x36:  /* SHZ */
+        case 0x37:  /* SHZ */
+          Ins_SHZ( EXEC_ARG_  args );
+          break;
+
+        case 0x38:  /* SHPIX */
+          Ins_SHPIX( EXEC_ARG_  args );
+          break;
+
+        case 0x39:  /* IP    */
+          Ins_IP( EXEC_ARG_  args );
+          break;
+
+        case 0x3A:  /* MSIRP */
+        case 0x3B:  /* MSIRP */
+          Ins_MSIRP( EXEC_ARG_  args );
+          break;
+
+        case 0x3C:  /* AlignRP */
+          Ins_ALIGNRP( EXEC_ARG_  args );
+          break;
+
+        case 0x3D:  /* RTDG */
+          DO_RTDG
+          break;
+
+        case 0x3E:  /* MIAP */
+        case 0x3F:  /* MIAP */
+          Ins_MIAP( EXEC_ARG_  args );
+          break;
+
+        case 0x40:  /* NPUSHB */
+          Ins_NPUSHB( EXEC_ARG_  args );
+          break;
+
+        case 0x41:  /* NPUSHW */
+          Ins_NPUSHW( EXEC_ARG_  args );
+          break;
+
+        case 0x42:  /* WS */
+          DO_WS
+          break;
+
+    Set_Invalid_Ref:
+            CUR.error = TT_Err_Invalid_Reference;
+          break;
+
+        case 0x43:  /* RS */
+          DO_RS
+          break;
+
+        case 0x44:  /* WCVTP */
+          DO_WCVTP
+          break;
+
+        case 0x45:  /* RCVT */
+          DO_RCVT
+          break;
+
+        case 0x46:  /* GC */
+        case 0x47:  /* GC */
+          Ins_GC( EXEC_ARG_  args );
+          break;
+
+        case 0x48:  /* SCFS */
+          Ins_SCFS( EXEC_ARG_  args );
+          break;
+
+        case 0x49:  /* MD */
+        case 0x4A:  /* MD */
+          Ins_MD( EXEC_ARG_  args );
+          break;
+
+        case 0x4B:  /* MPPEM */
+          DO_MPPEM
+          break;
+
+        case 0x4C:  /* MPS */
+          DO_MPS
+          break;
+
+        case 0x4D:  /* FLIPON */
+          DO_FLIPON
+          break;
+
+        case 0x4E:  /* FLIPOFF */
+          DO_FLIPOFF
+          break;
+
+        case 0x4F:  /* DEBUG */
+          DO_DEBUG
+          break;
+
+        case 0x50:  /* LT */
+          DO_LT
+          break;
+
+        case 0x51:  /* LTEQ */
+          DO_LTEQ
+          break;
+
+        case 0x52:  /* GT */
+          DO_GT
+          break;
+
+        case 0x53:  /* GTEQ */
+          DO_GTEQ
+          break;
+
+        case 0x54:  /* EQ */
+          DO_EQ
+          break;
+
+        case 0x55:  /* NEQ */
+          DO_NEQ
+          break;
+
+        case 0x56:  /* ODD */
+          DO_ODD
+          break;
+
+        case 0x57:  /* EVEN */
+          DO_EVEN
+          break;
+
+        case 0x58:  /* IF */
+          Ins_IF( EXEC_ARG_  args );
+          break;
+
+        case 0x59:  /* EIF */
+          /* do nothing */
+          break;
+
+        case 0x5A:  /* AND */
+          DO_AND
+          break;
+
+        case 0x5B:  /* OR */
+          DO_OR
+          break;
+
+        case 0x5C:  /* NOT */
+          DO_NOT
+          break;
+
+        case 0x5D:  /* DELTAP1 */
+          Ins_DELTAP( EXEC_ARG_  args );
+          break;
+
+        case 0x5E:  /* SDB */
+          DO_SDB
+          break;
+
+        case 0x5F:  /* SDS */
+          DO_SDS
+          break;
+
+        case 0x60:  /* ADD */
+          DO_ADD
+          break;
+
+        case 0x61:  /* SUB */
+          DO_SUB
+          break;
+
+        case 0x62:  /* DIV */
+          DO_DIV
+          break;
+
+        case 0x63:  /* MUL */
+          DO_MUL
+          break;
+
+        case 0x64:  /* ABS */
+          DO_ABS
+          break;
+
+        case 0x65:  /* NEG */
+          DO_NEG
+          break;
+
+        case 0x66:  /* FLOOR */
+          DO_FLOOR
+          break;
+
+        case 0x67:  /* CEILING */
+          DO_CEILING
+          break;
+
+        case 0x68:  /* ROUND */
+        case 0x69:  /* ROUND */
+        case 0x6A:  /* ROUND */
+        case 0x6B:  /* ROUND */
+          DO_ROUND
+          break;
+
+        case 0x6C:  /* NROUND */
+        case 0x6D:  /* NROUND */
+        case 0x6E:  /* NRRUND */
+        case 0x6F:  /* NROUND */
+          DO_NROUND
+          break;
+
+        case 0x70:  /* WCVTF */
+          DO_WCVTF
+          break;
+
+        case 0x71:  /* DELTAP2 */
+        case 0x72:  /* DELTAP3 */
+          Ins_DELTAP( EXEC_ARG_  args );
+          break;
+
+        case 0x73:  /* DELTAC0 */
+        case 0x74:  /* DELTAC1 */
+        case 0x75:  /* DELTAC2 */
+          Ins_DELTAC( EXEC_ARG_  args );
+          break;
+
+        case 0x76:  /* SROUND */
+          DO_SROUND
+          break;
+
+        case 0x77:  /* S45Round */
+          DO_S45ROUND
+          break;
+
+        case 0x78:  /* JROT */
+          DO_JROT
+          break;
+
+        case 0x79:  /* JROF */
+          DO_JROF
+          break;
+
+        case 0x7A:  /* ROFF */
+          DO_ROFF
+          break;
+
+        case 0x7B:  /* ???? */
+          Ins_UNKNOWN( EXEC_ARG_  args );
+          break;
+
+        case 0x7C:  /* RUTG */
+          DO_RUTG
+          break;
+
+        case 0x7D:  /* RDTG */
+          DO_RDTG
+          break;
+
+        case 0x7E:  /* SANGW */
+        case 0x7F:  /* AA    */
+          /* nothing - obsolete */
+          break;
+
+        case 0x80:  /* FLIPPT */
+          Ins_FLIPPT( EXEC_ARG_  args );
+          break;
+
+        case 0x81:  /* FLIPRGON */
+          Ins_FLIPRGON( EXEC_ARG_  args );
+          break;
+
+        case 0x82:  /* FLIPRGOFF */
+          Ins_FLIPRGOFF( EXEC_ARG_  args );
+          break;
+
+        case 0x83:  /* UNKNOWN */
+        case 0x84:  /* UNKNOWN */
+          Ins_UNKNOWN( EXEC_ARG_  args );
+          break;
+
+        case 0x85:  /* SCANCTRL */
+          Ins_SCANCTRL( EXEC_ARG_  args );
+          break;
+
+        case 0x86:  /* SDPVTL */
+        case 0x87:  /* SDPVTL */
+          Ins_SDPVTL( EXEC_ARG_  args );
+          break;
+
+        case 0x88:  /* GETINFO */
+          Ins_GETINFO( EXEC_ARG_  args );
+          break;
+
+        case 0x89:  /* IDEF */
+          Ins_IDEF( EXEC_ARG_  args );
+          break;
+
+        case 0x8A:  /* ROLL */
+          Ins_ROLL( EXEC_ARG_  args );
+          break;
+
+        case 0x8B:  /* MAX */
+          DO_MAX
+          break;
+
+        case 0x8C:  /* MIN */
+          DO_MIN
+          break;
+
+        case 0x8D:  /* SCANTYPE */
+          Ins_SCANTYPE( EXEC_ARG_  args );
+          break;
+
+        case 0x8E:  /* INSTCTRL */
+          Ins_INSTCTRL( EXEC_ARG_  args );
+          break;
+
+        case 0x8F:
+          Ins_UNKNOWN( EXEC_ARG_  args );
+          break;
+
+        default:
+          if ( opcode >= 0xE0 )
+            Ins_MIRP( EXEC_ARG_  args );
+          else if ( opcode >= 0xC0 )
+            Ins_MDRP( EXEC_ARG_  args );
+          else if ( opcode >= 0xB8 )
+            Ins_PUSHW( EXEC_ARG_  args );
+          else if ( opcode >= 0xB0 )
+            Ins_PUSHB( EXEC_ARG_  args );
+          else
+            Ins_UNKNOWN( EXEC_ARG_  args );
+        }
+
+      }
+#else
+      Instruct_Dispatch[CUR.opcode]( EXEC_ARG_ &CUR.stack[CUR.args] );
+#endif
+      if ( CUR.error != TT_Err_Ok )
+      {
+        switch ( CUR.error )
+        {
+        case TT_Err_Invalid_Opcode: /* looking for redefined instructions */
+          {
+            TT_DefRecord*  def   = CUR.IDefs;
+            TT_DefRecord*  limit = def + CUR.numIDefs;
+            
+            for ( ; def < limit; def++ )
+            {
+              if ( def->active && CUR.opcode == def->opc )
+              {
+                TT_CallRec*  callrec;
+    
+                if ( CUR.callTop >= CUR.callSize )
+                {
+                  CUR.error = TT_Err_Invalid_Reference;
+                  goto LErrorLabel_;
+                }
+    
+                callrec = &CUR.callStack[CUR.callTop];
+    
+                callrec->Caller_Range = CUR.curRange;
+                callrec->Caller_IP    = CUR.IP + 1;
+                callrec->Cur_Count    = 1;
+                callrec->Cur_Restart  = def->start;
+    
+                if ( INS_Goto_CodeRange( def->range, def->start ) == FAILURE )
+                  goto LErrorLabel_;
+    
+                goto LSuiteLabel_;
+              }
+            }
+          }
+
+          CUR.error = TT_Err_Invalid_Opcode;
+          goto LErrorLabel_;
+/*        break;   Unreachable code warning suppress.  Leave in case a later
+                   change to remind the editor to consider break; */
+
+        default:
+          goto LErrorLabel_;
+/*        break; */
+        }
+      }
+
+      CUR.top = CUR.new_top;
+
+      if ( CUR.step_ins )
+        CUR.IP += CUR.length;
+
+      /* increment instruction counter and check if we didn't   */
+      /* run this program for too long ?? (e.g. infinite loops) */
+      if ( ++ins_counter > MAX_RUNNABLE_OPCODES )
+        return TT_Err_Execution_Too_Long;
+
+  LSuiteLabel_:
+      if ( CUR.IP >= CUR.codeSize )
+      {
+        if ( CUR.callTop > 0 )
+        {
+          CUR.error = TT_Err_Code_Overflow;
+          goto LErrorLabel_;
+        }
+        else
+          goto LNo_Error_;
+      }
+    } while ( !CUR.instruction_trap );
+
+  LNo_Error_:
+#ifdef TT_CONFIG_OPTION_STATIC_RASTER
+    *exc = cur;
+#endif
+    return TT_Err_Ok;
+
+  LErrorCodeOverflow_:
+    CUR.error = TT_Err_Code_Overflow;
+
+  LErrorLabel_:
+#ifdef TT_CONFIG_OPTION_STATIC_RASTER
+    *exc = cur;
+#endif
+    return CUR.error;
+  }
+
+
+#if 0
+
+  /* This function must be declared by the debugger front end */
+  /* in order to specify which code range to debug.           */
+
+  int  debug_coderange = tt_coderange_glyph;
+
+  static char  tempStr[128];
+
+  static const char*  OpStr[256] =
+  {
+    "SVTCA y",       /* Set vectors to coordinate axis y    */
+    "SVTCA x",       /* Set vectors to coordinate axis x    */
+    "SPvTCA y",      /* Set Proj. vec. to coord. axis y     */
+    "SPvTCA x",      /* Set Proj. vec. to coord. axis x     */
+    "SFvTCA y",      /* Set Free. vec. to coord. axis y     */
+    "SFvTCA x",      /* Set Free. vec. to coord. axis x     */
+    "SPvTL //",      /* Set Proj. vec. parallel to segment  */
+    "SPvTL +",       /* Set Proj. vec. normal to segment    */
+    "SFvTL //",      /* Set Free. vec. parallel to segment  */
+    "SFvTL +",       /* Set Free. vec. normal to segment    */
+    "SPvFS",         /* Set Proj. vec. from stack           */
+    "SFvFS",         /* Set Free. vec. from stack           */
+    "GPV",           /* Get projection vector               */
+    "GFV",           /* Get freedom vector                  */
+    "SFvTPv",        /* Set free. vec. to proj. vec.        */
+    "ISECT",         /* compute intersection                */
+
+    "SRP0",          /* Set reference point 0               */
+    "SRP1",          /* Set reference point 1               */
+    "SRP2",          /* Set reference point 2               */
+    "SZP0",          /* Set Zone Pointer 0                  */
+    "SZP1",          /* Set Zone Pointer 1                  */
+    "SZP2",          /* Set Zone Pointer 2                  */
+    "SZPS",          /* Set all zone pointers               */
+    "SLOOP",         /* Set loop counter                    */
+    "RTG",           /* Round to Grid                       */
+    "RTHG",          /* Round to Half-Grid                  */
+    "SMD",           /* Set Minimum Distance                */
+    "ELSE",          /* Else                                */
+    "JMPR",          /* Jump Relative                       */
+    "SCvTCi",        /* Set CVT                             */
+    "SSwCi",         /*                                     */
+    "SSW",           /*                                     */
+
+    "DUP",
+    "POP",
+    "CLEAR",
+    "SWAP",
+    "DEPTH",
+    "CINDEX",
+    "MINDEX",
+    "AlignPTS",
+    "INS_$28",
+    "UTP",
+    "LOOPCALL",
+    "CALL",
+    "FDEF",
+    "ENDF",
+    "MDAP[-]",
+    "MDAP[r]",
+
+    "IUP[y]",
+    "IUP[x]",
+    "SHP[0]",
+    "SHP[1]",
+    "SHC[0]",
+    "SHC[1]",
+    "SHZ[0]",
+    "SHZ[1]",
+    "SHPIX",
+    "IP",
+    "MSIRP[0]",
+    "MSIRP[1]",
+    "AlignRP",
+    "RTDG",
+    "MIAP[-]",
+    "MIAP[r]",
+
+    "NPushB",
+    "NPushW",
+    "WS",
+    "RS",
+    "WCvtP",
+    "RCvt",
+    "GC[0]",
+    "GC[1]",
+    "SCFS",
+    "MD[0]",
+    "MD[1]",
+    "MPPEM",
+    "MPS",
+    "FlipON",
+    "FlipOFF",
+    "DEBUG",
+
+    "LT",
+    "LTEQ",
+    "GT",
+    "GTEQ",
+    "EQ",
+    "NEQ",
+    "ODD",
+    "EVEN",
+    "IF",
+    "EIF",
+    "AND",
+    "OR",
+    "NOT",
+    "DeltaP1",
+    "SDB",
+    "SDS",
+
+    "ADD",
+    "SUB",
+    "DIV",
+    "MUL",
+    "ABS",
+    "NEG",
+    "FLOOR",
+    "CEILING",
+    "ROUND[G]",
+    "ROUND[B]",
+    "ROUND[W]",
+    "ROUND[?]",
+    "NROUND[G]",
+    "NROUND[B]",
+    "NROUND[W]",
+    "NROUND[?]",
+
+    "WCvtF",
+    "DeltaP2",
+    "DeltaP3",
+    "DeltaC1",
+    "DeltaC2",
+    "DeltaC3",
+    "SROUND",
+    "S45Round",
+    "JROT",
+    "JROF",
+    "ROFF",
+    "INS_$7B",
+    "RUTG",
+    "RDTG",
+    "SANGW",
+    "AA",
+
+    "FlipPT",
+    "FlipRgON",
+    "FlipRgOFF",
+    "INS_$83",
+    "INS_$84",
+    "ScanCTRL",
+    "SDPVTL[0]",
+    "SDPVTL[1]",
+    "GetINFO",
+    "IDEF",
+    "ROLL",
+    "MAX",
+    "MIN",
+    "ScanTYPE",
+    "IntCTRL",
+    "INS_$8F",
+
+    "INS_$90",
+    "INS_$91",
+    "INS_$92",
+    "INS_$93",
+    "INS_$94",
+    "INS_$95",
+    "INS_$96",
+    "INS_$97",
+    "INS_$98",
+    "INS_$99",
+    "INS_$9A",
+    "INS_$9B",
+    "INS_$9C",
+    "INS_$9D",
+    "INS_$9E",
+    "INS_$9F",
+
+    "INS_$A0",
+    "INS_$A1",
+    "INS_$A2",
+    "INS_$A3",
+    "INS_$A4",
+    "INS_$A5",
+    "INS_$A6",
+    "INS_$A7",
+    "INS_$A8",
+    "INS_$A9",
+    "INS_$AA",
+    "INS_$AB",
+    "INS_$AC",
+    "INS_$AD",
+    "INS_$AE",
+    "INS_$AF",
+
+    "PushB[0]",
+    "PushB[1]",
+    "PushB[2]",
+    "PushB[3]",
+    "PushB[4]",
+    "PushB[5]",
+    "PushB[6]",
+    "PushB[7]",
+    "PushW[0]",
+    "PushW[1]",
+    "PushW[2]",
+    "PushW[3]",
+    "PushW[4]",
+    "PushW[5]",
+    "PushW[6]",
+    "PushW[7]",
+
+    "MDRP[G]",
+    "MDRP[B]",
+    "MDRP[W]",
+    "MDRP[?]",
+    "MDRP[rG]",
+    "MDRP[rB]",
+    "MDRP[rW]",
+    "MDRP[r?]",
+    "MDRP[mG]",
+    "MDRP[mB]",
+    "MDRP[mW]",
+    "MDRP[m?]",
+    "MDRP[mrG]",
+    "MDRP[mrB]",
+    "MDRP[mrW]",
+    "MDRP[mr?]",
+    "MDRP[pG]",
+    "MDRP[pB]",
+
+    "MDRP[pW]",
+    "MDRP[p?]",
+    "MDRP[prG]",
+    "MDRP[prB]",
+    "MDRP[prW]",
+    "MDRP[pr?]",
+    "MDRP[pmG]",
+    "MDRP[pmB]",
+    "MDRP[pmW]",
+    "MDRP[pm?]",
+    "MDRP[pmrG]",
+    "MDRP[pmrB]",
+    "MDRP[pmrW]",
+    "MDRP[pmr?]",
+
+    "MIRP[G]",
+    "MIRP[B]",
+    "MIRP[W]",
+    "MIRP[?]",
+    "MIRP[rG]",
+    "MIRP[rB]",
+    "MIRP[rW]",
+    "MIRP[r?]",
+    "MIRP[mG]",
+    "MIRP[mB]",
+    "MIRP[mW]",
+    "MIRP[m?]",
+    "MIRP[mrG]",
+    "MIRP[mrB]",
+    "MIRP[mrW]",
+    "MIRP[mr?]",
+    "MIRP[pG]",
+    "MIRP[pB]",
+
+    "MIRP[pW]",
+    "MIRP[p?]",
+    "MIRP[prG]",
+    "MIRP[prB]",
+    "MIRP[prW]",
+    "MIRP[pr?]",
+    "MIRP[pmG]",
+    "MIRP[pmB]",
+    "MIRP[pmW]",
+    "MIRP[pm?]",
+    "MIRP[pmrG]",
+    "MIRP[pmrB]",
+    "MIRP[pmrW]",
+    "MIRP[pmr?]"
+  };
+
+
+  const char* Cur_U_Line( TT_ExecContext exec )
+  {
+    char  s[32];
+
+    int  op, i, n;
+
+    op = exec->code[exec->IP];
+
+    sprintf( tempStr, "%s", OpStr[op] );
+
+    if ( op == 0x40 )
+    {
+      n = exec->code[exec->IP + 1];
+      sprintf( s, "(%d)", n );
+      strncat( tempStr, s, 8 );
+
+      if ( n > 20 ) n = 20; /* limit output */
+
+      for ( i = 0; i < n; i++ )
+      {
+        sprintf( s, " $%02hx", exec->code[exec->IP + i + 2] );
+        strncat( tempStr, s, 8 );
+      }
+    }
+    else if ( op == 0x41 )
+    {
+      n = exec->code[exec->IP + 1];
+      sprintf( s, "(%d)", n );
+      strncat( tempStr, s, 8 );
+
+      if ( n > 20 ) n = 20; /* limit output */
+
+      for ( i = 0; i < n; i++ )
+      {
+        sprintf( s, " $%02hx%02hx", exec->code[exec->IP + i*2 + 2],
+                                    exec->code[exec->IP + i*2 + 3] );
+        strncat( tempStr, s, 8 );
+      }
+    }
+    else if ( (op & 0xF8) == 0xB0 )
+    {
+      n = op - 0xB0;
+
+      for ( i = 0; i <= n; i++ )
+      {
+        sprintf( s, " $%02hx", exec->code[exec->IP + i + 1] );
+        strncat( tempStr, s, 8 );
+      }
+    }
+    else if ( (op & 0xF8) == 0xB8 )
+    {
+      n = op-0xB8;
+
+      for ( i = 0; i <= n; i++ )
+      {
+        sprintf( s, " $%02hx%02hx", exec->code[exec->IP + i*2 + 1],
+                                    exec->code[exec->IP + i*2 + 2] );
+        strncat( tempStr, s, 8 );
+      }
+    }
+
+    return (char*)tempStr;
+  }
+
+
+  EXPORT_FUNC
+  TT_Error  TT_RunIns( TT_ExecContext  exc )
+  {
+    TT_Int    A, diff;
+    TT_ULong  next_IP;
+    TT_Char   ch, oldch;
+    char     *temp;
+    int       key;
+    FT_Memory memory;
+
+    TT_Error  error = 0;
+
+    TT_GlyphZone  save;
+    TT_GlyphZone  pts;
+
+#define TT_Round_Off             5
+#define TT_Round_To_Half_Grid    0
+#define TT_Round_To_Grid         1
+#define TT_Round_To_Double_Grid  2
+#define TT_Round_Up_To_Grid      4
+#define TT_Round_Down_To_Grid    3
+#define TT_Round_Super           6
+#define TT_Round_Super_45        7
+
+    const char*  round_str[8] =
+    {
+      "to half-grid",
+      "to grid",
+      "to double grid",
+      "down to grid",
+      "up to grid",
+      "off",
+      "super",
+      "super 45"
+    };
+
+    /* Check that we're running the code range that is effectively */
+    /* asked by the debugger front end.                            */
+    if ( exc->curRange != debug_coderange )
+      return TT_RunIns2( exc );
+
+    pts = exc->pts;
+
+    memory = exc->face->root.memory;
+
+    save.n_points   = pts.n_points;
+    save.n_contours = pts.n_contours;
+
+    MEM_Alloc( save.org, sizeof ( TT_Vector ) * save.n_points );
+    MEM_Alloc( save.cur, sizeof ( TT_Vector ) * save.n_points );
+    MEM_Alloc( save.touch, sizeof ( TT_Byte ) * save.n_points );
+
+    exc->instruction_trap = 1;
+
+    oldch = '\0';
+
+    do
+    {
+      if ( exc->IP < exc->codeSize )
+      {
+#ifdef TT_CONFIG_OPTION_STATIC_INTERPRETER
+        cur = *exc;
+#endif
+        if ( ( CUR.length = opcode_length[CUR.opcode] ) < 0 )
+        {
+          if ( CUR.IP + 1 > CUR.codeSize )
+            goto LErrorCodeOverflow_;
+
+          CUR.length = CUR.code[CUR.IP + 1] + 2;
+        }
+
+        exc->args = exc->top - (Pop_Push_Count[exc->opcode] >> 4);
+
+        /* `args' is the top of the stack once arguments have been popped. */
+        /* One can also interpret it as the index of the last argument.    */
+
+        /* Print the current line.  We use a 80-columns console with the   */
+        /* following formatting:                                           */
+        /*                                                                 */
+        /* [loc]:[addr] [opcode]  [disassemby]          [a][b]|[c][d]      */
+        /*                                                                 */
+
+        {
+          char      temp[80];
+          int       n, col, pop;
+          int       args = CUR.args;
+
+
+          sprintf( temp, "%78c\n", ' ' );
+
+          /* first letter of location */
+          switch ( CUR.curRange )
+          {
+          case tt_coderange_glyph:
+            temp[0] = 'g';
+            break;
+          case tt_coderange_cvt:
+            temp[0] = 'c';
+            break;
+          default:
+            temp[0] = 'f';
+          }
+
+          /* current IP */
+          sprintf( temp+1, "%04lx: %02x  %-36.36s",
+                   CUR.IP,
+                   CUR.opcode,
+                   Cur_U_Line(&CUR) );
+
+          strncpy( temp+46, " (", 2 );
+
+          args = CUR.top - 1;
+          pop  = Pop_Push_Count[CUR.opcode] >> 4;
+          col  = 48;
+          for ( n = 6; n > 0; n-- )
+          {
+            if ( pop == 0 )
+              temp[col-1] = (temp[col-1] == '(' ? ' ' : ')' );
+
+            if ( args < CUR.top && args >= 0 )
+              sprintf( temp+col, "%04lx", CUR.stack[args] );
+            else
+              sprintf( temp+col, "    " );
+
+            temp[col+4] = ' ';
+            col += 5;
+            pop--;
+            args--;
+          }
+          temp[78] = '\n';
+          temp[79] = '\0';
+          FT_TRACE0(( temp ));
+        }
+
+        /* First, check for empty stack and overflow */
+        if ( CUR.args < 0 )
+        {
+          FT_TRACE0(( "ERROR : Too few arguments\n" ));
+          exc->error = TT_Err_Too_Few_Arguments;
+          goto LErrorLabel_;
+        }
+
+        CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15);
+
+      /* new_top  is the new top of the stack, after the instruction's */
+      /* execution. top will be set to new_top after the 'case'        */
+
+        if ( CUR.new_top > CUR.stackSize )
+        {
+          FT_TRACE0(( "ERROR : Stack overflow\n" ));
+          exc->error = TT_Err_Stack_Overflow;
+          goto LErrorLabel_;
+        }
+      }
+      else
+        FT_TRACE0(( "End of program reached.\n" ));
+
+      key = 0;
+      do
+      {
+       /* read keyboard */
+
+        ch = getch();
+
+        switch ( ch )
+        {
+        /* Help - show keybindings */
+        case '?':
+          FT_TRACE0(( "FDebug Help\n\n" ));
+          FT_TRACE0(( "?   Show this page\n" ));
+          FT_TRACE0(( "q   Quit debugger\n" ));
+          FT_TRACE0(( "n   Skip to next instruction\n" ));
+          FT_TRACE0(( "s   Step into\n" ));
+          FT_TRACE0(( "v   Show vector info\n" ));
+          FT_TRACE0(( "g   Show graphics state\n" ));
+          FT_TRACE0(( "p   Show points zone\n\n" ));
+          break;
+
+        /* Show vectors */
+        case 'v':
+          FT_TRACE0(( "freedom    (%04hx,%04hx)\n", exc->GS.freeVector.x,
+                                                  exc->GS.freeVector.y ));
+          FT_TRACE0(( "projection (%04hx,%04hx)\n", exc->GS.projVector.x,
+                                                  exc->GS.projVector.y ));
+          FT_TRACE0(( "dual       (%04hx,%04hx)\n\n", exc->GS.dualVector.x,
+                                                    exc->GS.dualVector.y ));
+          break;
+
+        /* Show graphics state */
+        case 'g':
+          FT_TRACE0(( "rounding   %s\n", round_str[exc->GS.round_state] ));
+          FT_TRACE0(( "min dist   %04lx\n", exc->GS.minimum_distance ));
+          FT_TRACE0(( "cvt_cutin  %04lx\n", exc->GS.control_value_cutin ));
+          break;
+
+        /* Show points table */
+        case 'p':
+          for ( A = 0; A < exc->pts.n_points; A++ )
+          {
+            FT_TRACE0(( "%02hx  ", A ));
+            FT_TRACE0(( "%08lx,%08lx - ", pts.org[A].x, pts.org[A].y ));
+            FT_TRACE0(( "%08lx,%08lx\n",  pts.cur[A].x, pts.cur[A].y ));
+          }
+          FT_TRACE0(( "\n" ));
+          break;
+
+        default:
+          key = 1;
+        }
+      } while ( !key );
+
+      MEM_Copy( save.org,   pts.org, pts.n_points * sizeof ( TT_Vector ) );
+      MEM_Copy( save.cur,   pts.cur, pts.n_points * sizeof ( TT_Vector ) );
+      MEM_Copy( save.touch, pts.touch, pts.n_points );
+
+      /* a return indicate the last command */
+      if (ch == '\r')
+        ch = oldch;
+
+      switch ( ch )
+      {
+      /* Quit debugger */
+      case 'q':
+        goto LErrorLabel_;
+
+      /* Step over */
+      case 'n':
+        if ( exc->IP < exc->codeSize )
+        {
+          /* `step over' is equivalent to `step into' except if  */
+          /* the current opcode is a CALL or LOOPCALL            */
+          if ( CUR.opcode != 0x2a && CUR.opcode != 0x2b )
+            goto Step_into;
+
+          /* otherwise, loop execution until we reach the next opcode */
+          next_IP = CUR.IP + CUR.length;
+          while ( exc->IP != next_IP )
+          {
+            if ( ( error = TT_RunIns2( exc ) ) )
+              goto LErrorLabel_;
+          }
+        }
+        oldch = ch;
+        break;
+
+      /* Step into */
+      case 's':
+        if ( exc->IP < exc->codeSize )
+
+      Step_into:
+          if ( ( error = TT_RunIns2( exc ) ) )
+            goto LErrorLabel_;
+        oldch = ch;
+        break;
+
+      default:
+        FT_TRACE0(( "unknown command. Press ? for help\n" ));
+        oldch = '\0';
+      }
+
+      for ( A = 0; A < pts.n_points; A++ )
+      {
+        diff = 0;
+        if ( save.org[A].x != pts.org[A].x ) diff |= 1;
+        if ( save.org[A].y != pts.org[A].y ) diff |= 2;
+        if ( save.cur[A].x != pts.cur[A].x ) diff |= 4;
+        if ( save.cur[A].y != pts.cur[A].y ) diff |= 8;
+        if ( save.touch[A] != pts.touch[A] ) diff |= 16;
+
+        if ( diff )
+        {
+          FT_TRACE0(( "%02hx  ", A ));
+
+          if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx ";
+          FT_TRACE0(( temp, save.touch[A] & 7 ));
+
+          if ( diff & 1 ) temp = "(%08lx)"; else temp = " %08lx ";
+          FT_TRACE0(( temp, save.org[A].x ));
+
+          if ( diff & 2 ) temp = "(%08lx)"; else temp = " %08lx ";
+          FT_TRACE0(( temp, save.org[A].y ));
+
+          if ( diff & 4 ) temp = "(%08lx)"; else temp = " %08lx ";
+          FT_TRACE0(( temp, save.cur[A].x ));
+
+          if ( diff & 8 ) temp = "(%08lx)"; else temp = " %08lx ";
+          FT_TRACE0(( temp, save.cur[A].y ));
+
+          FT_TRACE0(( "\n" ));
+
+          FT_TRACE0(( "%02hx  ", A ));
+
+          if ( diff & 16 ) temp = "[%01hx]"; else temp = " %01hx ";
+          FT_TRACE0(( temp, pts.touch[A] & 7 ));
+
+          if ( diff & 1 ) temp = "[%08lx]"; else temp = " %08lx ";
+          FT_TRACE0(( temp, pts.org[A].x ));
+
+          if ( diff & 2 ) temp = "[%08lx]"; else temp = " %08lx ";
+          FT_TRACE0(( temp, pts.org[A].y ));
+
+          if ( diff & 4 ) temp = "[%08lx]"; else temp = " %08lx ";
+          FT_TRACE0(( temp, pts.cur[A].x ));
+
+          if ( diff & 8 ) temp = "[%08lx]"; else temp = " %08lx ";
+          FT_TRACE0(( temp, pts.cur[A].y ));
+
+          FT_TRACE0(( "\n\n" ));
+        }
+      }
+    } while ( TRUE );
+
+  LErrorLabel_:
+
+    return error;
+
+  LErrorCodeOverflow_:
+    error = TT_Err_Code_Overflow;
+    return error;
+  }
+
+#endif /* DEBUG_INTERPRETER */
+
+
+/* END */
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
new file mode 100644
index 0000000..96cd4a5
--- /dev/null
+++ b/src/truetype/ttinterp.h
@@ -0,0 +1,470 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttinterp.h                                                             */
+/*                                                                         */
+/*    TrueType bytecode intepreter (specification).                        */
+/*                                                                         */
+/*  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 TTINTERP_H
+#define TTINTERP_H
+
+#include <ttobjs.h>
+
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+#ifndef TT_STATIC_INTEPRETER  /* indirect implementation */
+
+#define EXEC_OP_   TT_ExecContext  exc,
+#define EXEC_OP    TT_ExecContext  exc
+#define EXEC_ARG_  exc,
+#define EXEC_ARG   exc
+
+#else                          /* static implementation */
+
+#define EXEC_OP_   /* void */
+#define EXEC_OP    /* void */
+#define EXEC_ARG_  /* void */
+#define EXEC_ARG   /* void */
+
+#endif /* TT_STATIC_INTERPRETER */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Rounding mode constants.                                              */
+  /*                                                                       */
+#define TT_Round_Off             5
+#define TT_Round_To_Half_Grid    0
+#define TT_Round_To_Grid         1
+#define TT_Round_To_Double_Grid  2
+#define TT_Round_Up_To_Grid      4
+#define TT_Round_Down_To_Grid    3
+#define TT_Round_Super           6
+#define TT_Round_Super_45        7
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Function types used by the interpreter, depending on various modes    */
+  /* (e.g. the rounding mode, whether to render a vertical or horizontal   */
+  /* line etc).                                                            */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /* Rounding function */
+  typedef TT_F26Dot6  (*TT_Round_Func)( EXEC_OP_ TT_F26Dot6  distance,
+                                                 TT_F26Dot6  compensation );
+
+  /* Point displacement along the freedom vector routine */
+  typedef void  (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone*  zone,
+                                          TT_UInt        point,
+                                          TT_F26Dot6     distance );
+
+  /* Distance projection along one of the projection vectors */
+  typedef TT_F26Dot6  (*TT_Project_Func)( EXEC_OP_ TT_Vector*  v1,
+                                                   TT_Vector*  v2 );
+
+  /* reading a cvt value.  Take care of non-square pixels if necessary */
+  typedef TT_F26Dot6  (*TT_Get_CVT_Func)( EXEC_OP_ TT_ULong  index );
+
+  /* setting or moving a cvt value.  Take care of non-square pixels  */
+  /* if necessary                                                    */
+  typedef void  (*TT_Set_CVT_Func)( EXEC_OP_ TT_ULong    index,
+                                             TT_F26Dot6  value );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This structure defines a call record, used to manage function calls.  */
+  /*                                                                       */
+  typedef struct  TT_CallRec_
+  {
+    TT_Int   Caller_Range;
+    TT_Long  Caller_IP;
+    TT_Long  Cur_Count;
+    TT_Long  Cur_Restart;
+
+  } TT_CallRec, *TT_CallStack;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The main structure for the interpreter which collects all necessary   */
+  /* variables and states.                                                 */
+  /*                                                                       */
+  typedef struct  TT_ExecContextRec_
+  {
+    TT_Face         face;
+    TT_Size         size;
+    FT_Memory       memory;
+
+    /* instructions state */
+
+    TT_Error        error;      /* last execution error */
+
+    TT_Long         top;        /* top of exec. stack   */
+
+    TT_UInt         stackSize;  /* size of exec. stack  */
+    TT_Long*        stack;      /* current exec. stack  */
+
+    TT_Long         args;
+    TT_UInt         new_top;    /* new top after exec.  */
+
+    TT_GlyphZone    zp0,        /* zone records */
+                    zp1,
+                    zp2,
+                    pts,
+                    twilight;
+
+    FT_Size_Metrics  metrics;
+    TT_Size_Metrics  tt_metrics; /* size metrics */
+
+    TT_GraphicsState  GS;         /* current graphics state */
+
+    TT_Int          curRange;  /* current code range number   */
+    TT_Byte*        code;      /* current code range          */
+    TT_Long         IP;        /* current instruction pointer */
+    TT_Long         codeSize;  /* size of current range       */
+
+    TT_Byte         opcode;    /* current opcode              */
+    TT_Int          length;    /* length of current opcode    */
+
+    TT_Bool         step_ins;  /* true if the interpreter must */
+                               /* increment IP after ins. exec */
+    TT_Long         cvtSize;
+    TT_Long*        cvt;
+
+    TT_UInt         glyphSize; /* glyph instructions buffer size */
+    TT_Byte*        glyphIns;  /* glyph instructions buffer */
+
+    TT_UInt         numFDefs;  /* number of function defs         */
+    TT_UInt         maxFDefs;  /* maximum number of function defs */
+    TT_DefArray     FDefs;     /* table of FDefs entries          */
+
+    TT_UInt         numIDefs;  /* number of instruction defs */
+    TT_UInt         maxIDefs;  /* maximum number of ins defs */
+    TT_DefArray     IDefs;     /* table of IDefs entries     */
+
+    TT_UInt         maxFunc;   /* maximum function index     */
+    TT_UInt         maxIns;    /* maximum instruction index  */
+
+    TT_Int          callTop,    /* top of call stack during execution */
+                    callSize;   /* size of call stack */
+    TT_CallStack    callStack;  /* call stack */
+
+    TT_UShort       maxPoints;    /* capacity of this context's `pts' */
+    TT_Short        maxContours;  /* record, expressed in points and  */
+                                  /* contours.                        */
+
+    TT_CodeRangeTable  codeRangeTable;  /* table of valid code ranges */
+                                        /* useful for the debugger   */
+
+    TT_UShort       storeSize;  /* size of current storage */
+    TT_Long*        storage;    /* storage area            */
+
+    TT_F26Dot6      period;     /* values used for the */
+    TT_F26Dot6      phase;      /* `SuperRounding'     */
+    TT_F26Dot6      threshold;
+
+    /* this seems to be unused */
+#if 0
+    TT_Int          cur_ppem;       /* ppem along the current proj vector */
+#endif
+    TT_Bool         instruction_trap;  /* If `True', the interpreter will */
+                                       /* exit after each instruction     */
+
+    TT_GraphicsState  default_GS;      /* graphics state resulting from    */
+                                       /* the prep program                 */
+    TT_Bool          is_composite;     /* true if the glyph is composite   */
+    TT_Bool          pedantic_hinting; /* true for pedantic interpretation */
+
+    /* latest interpreter additions */
+
+    TT_Long            F_dot_P;    /* dot product of freedom and projection */
+                                   /* vectors                               */
+    TT_Round_Func      func_round; /* current rounding function             */
+
+    TT_Project_Func    func_project,   /* current projection function */
+                       func_dualproj,  /* current dual proj. function */
+                       func_freeProj;  /* current freedom proj. func  */
+
+    TT_Move_Func       func_move;      /* current point move function */
+
+    TT_Get_CVT_Func    func_read_cvt;  /* read a cvt entry              */
+    TT_Set_CVT_Func    func_write_cvt; /* write a cvt entry (in pixels) */
+    TT_Set_CVT_Func    func_move_cvt;  /* incr a cvt entry (in pixels)  */
+
+    TT_ULong           loadSize;
+    TT_SubGlyph_Stack  loadStack;      /* loading subglyph stack */
+
+  } TT_ExecContextRec;
+
+
+
+  LOCAL_DEF
+  const TT_GraphicsState  tt_default_graphics_state;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Goto_CodeRange                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Switches to a new code range (updates the code related elements in */
+  /*    `exec', and `IP').                                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range :: The new execution code range.                             */
+  /*    IP    :: The  new IP in the new code range.                        */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    exec  :: The target execution context.                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   TrueType error code.  0 means success.                              */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Goto_CodeRange( TT_ExecContext  exec,
+                               TT_Int          range,
+                               TT_Long         IP );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Set_CodeRange                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets a code range.                                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range  :: The code range index.                                    */
+  /*    base   :: The new code base.                                       */
+  /*    length :: The range size in bytes.                                 */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    exec   :: The target execution context.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   TrueType error code.  0 means success.                              */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Set_CodeRange( TT_ExecContext  exec,
+                              TT_Int          range,
+                              void*           base,
+                              TT_Long         length );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Clear_CodeRange                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Clears a code range.                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    range :: The code range index.                                     */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    exec  :: The target execution context.                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   TrueType error code.  0 means success.                              */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Does not set the Error variable.                                   */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Clear_CodeRange( TT_ExecContext  exec,
+                                TT_Int          range );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_New_Context                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Queries the face context for a given font.  Note that there is     */
+  /*    now a _single_ execution context in the TrueType driver which is   */
+  /*    shared among faces.                                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A handle to the source face object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    A handle to the execution context.  Initialized for `face'.        */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  EXPORT_DEF
+  TT_ExecContext  TT_New_Context( TT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_Context                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Discards an execution context.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec :: A handle to the target execution context.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  EXPORT_DEF
+  TT_Error  TT_Done_Context( TT_ExecContext  exec );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Destroy_Context                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given context.                                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec   :: A handle to the target execution context.                */
+  /*    memory :: A handle to the parent memory object.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Destroy_Context( TT_ExecContext  exec,
+                                FT_Memory       memory );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Context                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Prepare an execution context for glyph hinting.                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec :: A handle to the target execution context.                  */
+  /*    face :: A handle to the source face object.                        */
+  /*    size :: A handle to the source size object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  EXPORT_DEF
+  TT_Error  TT_Load_Context( TT_ExecContext  exec,
+                             TT_Face         face,
+                             TT_Size         size );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Save_Context                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Saves the code ranges in a `size' object.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec :: A handle to the source execution context.                  */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    ins  :: A handle to the target size object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Save_Context( TT_ExecContext  exec,
+                             TT_Size         ins );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Run_Context                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Executes one or more instructions in the execution context.        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec  :: A handle to the target execution context.                 */
+  /*                                                                       */
+  /*    debug :: A Boolean flag.  If set, the function sets some internal  */
+  /*             variables and returns immediately, otherwise TT_RunIns()  */
+  /*             is called.                                                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueTyoe error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only the glyph loader and debugger should call this function.      */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Run_Context( TT_ExecContext  exec,
+                            TT_Bool         debug );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_RunIns                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Executes one or more instruction in the execution context.  This   */
+  /*    is the main function of the TrueType opcode interpreter.           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    exec :: A handle to the target execution context.                  */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Only object manager and debugger should call this function.        */
+  /*                                                                       */
+  EXPORT_DEF
+  TT_Error  TT_RunIns( TT_ExecContext  exec );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* TTINTERP_H */
+
+
+/* END */
diff --git a/src/truetype/ttnameid.h b/src/truetype/ttnameid.h
new file mode 100644
index 0000000..98b19ab
--- /dev/null
+++ b/src/truetype/ttnameid.h
@@ -0,0 +1,603 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttnameid.h                                                             */
+/*                                                                         */
+/*    TrueType name ID definitions (specification only).                   */
+/*                                                                         */
+/*  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 FREETYPE_H
+#error "Don't include this file! Use freetype.h instead."
+#endif
+
+
+#ifndef TTNAMEID_H
+#define TTNAMEID_H
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values for the `Platform' identifier code in the name        */
+  /* records of the TTF `name' table.                                      */
+  /*                                                                       */
+#define TT_PLATFORM_APPLE_UNICODE  0
+#define TT_PLATFORM_MACINTOSH      1
+#define TT_PLATFORM_ISO            2
+#define TT_PLATFORM_MICROSOFT      3
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the platform specific encoding identifier field in */
+  /* the name records of the TTF `name' table when the `Platform'          */
+  /* identifier code is TT_PLATFORM_APPLE_UNICODE.                         */
+  /*                                                                       */
+#define TT_APPLE_ID_DEFAULT      0
+#define TT_APPLE_ID_UNICODE_1_1  1
+#define TT_APPLE_ID_ISO_10646    2
+#define TT_APPLE_ID_UNICODE_2_0  3
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the platform specific encoding identifier field in */
+  /* the name records of the TTF `name' table when the `Platform'          */
+  /* identifier code is TT_PLATFORM_MACINTOSH.                             */
+  /*                                                                       */
+#define TT_MAC_ID_ROMAN                 0
+#define TT_MAC_ID_JAPANESE              1
+#define TT_MAC_ID_TRADITIONAL_CHINESE   2
+#define TT_MAC_ID_KOREAN                3
+#define TT_MAC_ID_ARABIC                4
+#define TT_MAC_ID_HEBREW                5
+#define TT_MAC_ID_GREEK                 6
+#define TT_MAC_ID_RUSSIAN               7
+#define TT_MAC_ID_RSYMBOL               8
+#define TT_MAC_ID_DEVANAGARI            9
+#define TT_MAC_ID_GURMUKHI             10
+#define TT_MAC_ID_GUJARATI             11
+#define TT_MAC_ID_ORIYA                12
+#define TT_MAC_ID_BENGALI              13
+#define TT_MAC_ID_TAMIL                14
+#define TT_MAC_ID_TELUGU               15
+#define TT_MAC_ID_KANNADA              16
+#define TT_MAC_ID_MALAYALAM            17
+#define TT_MAC_ID_SINHALESE            18
+#define TT_MAC_ID_BURMESE              19
+#define TT_MAC_ID_KHMER                20
+#define TT_MAC_ID_THAI                 21
+#define TT_MAC_ID_LAOTIAN              22
+#define TT_MAC_ID_GEORGIAN             23
+#define TT_MAC_ID_ARMENIAN             24
+#define TT_MAC_ID_MALDIVIAN            25
+#define TT_MAC_ID_SIMPLIFIED_CHINESE   25
+#define TT_MAC_ID_TIBETAN              26
+#define TT_MAC_ID_MONGOLIAN            27
+#define TT_MAC_ID_GEEZ                 28
+#define TT_MAC_ID_SLAVIC               29
+#define TT_MAC_ID_VIETNAMESE           30
+#define TT_MAC_ID_SINDHI               31
+#define TT_MAC_ID_UNINTERP             32
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the platform specific encoding identifier field in */
+  /* the name records of the TTF `name' table when the `Platform'          */
+  /* identifier code is TT_PLATFORM_ISO.                                   */
+  /*                                                                       */
+#define TT_ISO_ID_7BIT_ASCII  0
+#define TT_ISO_ID_10646       1
+#define TT_ISO_ID_8859_1      2
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the platform specific encoding identifier field in */
+  /* the name records of the TTF `name' table when the `Platform'          */
+  /* identifier code is TT_PLATFORM_MICROSOFT.                             */
+  /*                                                                       */
+#define TT_MS_ID_SYMBOL_CS   0
+#define TT_MS_ID_UNICODE_CS  1
+#define TT_MS_ID_SJIS        2
+#define TT_MS_ID_GB2312      3
+#define TT_MS_ID_BIG_5       4
+#define TT_MS_ID_WANSUNG     5
+#define TT_MS_ID_JOHAB       6
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the language identifier field in the name records  */
+  /* of the TTF `name' table when the `Platform' identifier code is        */
+  /* TT_PLATFORM_MACINTOSH.                                                */
+  /*                                                                       */
+  /* The canonical source for the Apple assigned Language ID's is at       */
+  /* http://fonts.apple.com/TTRefMan/RM06/Chap6name.html.                  */
+  /*                                                                       */
+#define TT_MAC_LANGID_ENGLISH                      0
+#define TT_MAC_LANGID_FRENCH                       1
+#define TT_MAC_LANGID_GERMAN                       2
+#define TT_MAC_LANGID_ITALIAN                      3
+#define TT_MAC_LANGID_DUTCH                        4
+#define TT_MAC_LANGID_SWEDISH                      5
+#define TT_MAC_LANGID_SPANISH                      6
+#define TT_MAC_LANGID_DANISH                       7
+#define TT_MAC_LANGID_PORTUGUESE                   8
+#define TT_MAC_LANGID_NORWEGIAN                    9
+#define TT_MAC_LANGID_HEBREW                      10
+#define TT_MAC_LANGID_JAPANESE                    11
+#define TT_MAC_LANGID_ARABIC                      12
+#define TT_MAC_LANGID_FINNISH                     13
+#define TT_MAC_LANGID_GREEK                       14
+#define TT_MAC_LANGID_ICELANDIC                   15
+#define TT_MAC_LANGID_MALTESE                     16
+#define TT_MAC_LANGID_TURKISH                     17
+#define TT_MAC_LANGID_CROATIAN                    18
+#define TT_MAC_LANGID_CHINESE_TRADITIONAL         19
+#define TT_MAC_LANGID_URDU                        20
+#define TT_MAC_LANGID_HINDI                       21
+#define TT_MAC_LANGID_THAI                        22
+#define TT_MAC_LANGID_KOREAN                      23
+#define TT_MAC_LANGID_LITHUANIAN                  24
+#define TT_MAC_LANGID_POLISH                      25
+#define TT_MAC_LANGID_HUNGARIAN                   26
+#define TT_MAC_LANGID_ESTONIAN                    27
+#define TT_MAC_LANGID_LETTISH                     28
+#define TT_MAC_LANGID_SAAMISK                     29
+#define TT_MAC_LANGID_FAEROESE                    30
+#define TT_MAC_LANGID_FARSI                       31
+#define TT_MAC_LANGID_RUSSIAN                     32
+#define TT_MAC_LANGID_CHINESE_SIMPLIFIED          33
+#define TT_MAC_LANGID_FLEMISH                     34
+#define TT_MAC_LANGID_IRISH                       35
+#define TT_MAC_LANGID_ALBANIAN                    36
+#define TT_MAC_LANGID_ROMANIAN                    37
+#define TT_MAC_LANGID_CZECH                       38
+#define TT_MAC_LANGID_SLOVAK                      39
+#define TT_MAC_LANGID_SLOVENIAN                   40
+#define TT_MAC_LANGID_YIDDISH                     41
+#define TT_MAC_LANGID_SERBIAN                     42
+#define TT_MAC_LANGID_MACEDONIAN                  43
+#define TT_MAC_LANGID_BULGARIAN                   44
+#define TT_MAC_LANGID_UKRAINIAN                   45
+#define TT_MAC_LANGID_BYELORUSSIAN                46
+#define TT_MAC_LANGID_UZBEK                       47
+#define TT_MAC_LANGID_KAZAKH                      48
+#define TT_MAC_LANGID_AZERBAIJANI                 49
+#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT   50
+#define TT_MAC_LANGID_ARMENIAN                    51
+#define TT_MAC_LANGID_GEORGIAN                    52
+#define TT_MAC_LANGID_MOLDAVIAN                   53
+#define TT_MAC_LANGID_KIRGHIZ                     54
+#define TT_MAC_LANGID_TAJIKI                      55
+#define TT_MAC_LANGID_TURKMEN                     56
+#define TT_MAC_LANGID_MONGOLIAN                   57
+#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT   58
+#define TT_MAC_LANGID_PASHTO                      59
+#define TT_MAC_LANGID_KURDISH                     60
+#define TT_MAC_LANGID_KASHMIRI                    61
+#define TT_MAC_LANGID_SINDHI                      62
+#define TT_MAC_LANGID_TIBETAN                     63
+#define TT_MAC_LANGID_NEPALI                      64
+#define TT_MAC_LANGID_SANSKRIT                    65
+#define TT_MAC_LANGID_MARATHI                     66
+#define TT_MAC_LANGID_BENGALI                     67
+#define TT_MAC_LANGID_ASSAMESE                    68
+#define TT_MAC_LANGID_GUJARATI                    69
+#define TT_MAC_LANGID_PUNJABI                     70
+#define TT_MAC_LANGID_ORIYA                       71
+#define TT_MAC_LANGID_MALAYALAM                   72
+#define TT_MAC_LANGID_KANNADA                     73
+#define TT_MAC_LANGID_TAMIL                       74
+#define TT_MAC_LANGID_TELUGU                      75
+#define TT_MAC_LANGID_SINHALESE                   76
+#define TT_MAC_LANGID_BURMESE                     77
+#define TT_MAC_LANGID_KHMER                       78
+#define TT_MAC_LANGID_LAO                         79
+#define TT_MAC_LANGID_VIETNAMESE                  80
+#define TT_MAC_LANGID_INDONESIAN                  81
+#define TT_MAC_LANGID_TAGALOG                     82
+#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT          83
+#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT         84
+#define TT_MAC_LANGID_AMHARIC                     85
+#define TT_MAC_LANGID_TIGRINYA                    86
+#define TT_MAC_LANGID_GALLA                       87
+#define TT_MAC_LANGID_SOMALI                      88
+#define TT_MAC_LANGID_SWAHILI                     89
+#define TT_MAC_LANGID_RUANDA                      90
+#define TT_MAC_LANGID_RUNDI                       91
+#define TT_MAC_LANGID_CHEWA                       92
+#define TT_MAC_LANGID_MALAGASY                    93
+#define TT_MAC_LANGID_ESPERANTO                   94
+#define TT_MAC_LANGID_WELSH                      128
+#define TT_MAC_LANGID_BASQUE                     129
+#define TT_MAC_LANGID_CATALAN                    130
+#define TT_MAC_LANGID_LATIN                      131
+#define TT_MAC_LANGID_QUECHUA                    132
+#define TT_MAC_LANGID_GUARANI                    133
+#define TT_MAC_LANGID_AYMARA                     134
+#define TT_MAC_LANGID_TATAR                      135
+#define TT_MAC_LANGID_UIGHUR                     136
+#define TT_MAC_LANGID_DZONGKHA                   137
+#define TT_MAC_LANGID_JAVANESE                   138
+#define TT_MAC_LANGID_SUNDANESE                  139
+#define TT_MAC_LANGID_SCOTTISH_GAELIC            140
+#define TT_MAC_LANGID_IRISH_GAELIC               141
+#define TT_MAC_LANGID_BRETON                     142
+#define TT_MAC_LANGID_INUKTITUT                  143
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Possible values of the language identifier field in the name records  */
+  /* of the TTF `name' table when the `Platform' identifier code is        */
+  /* TT_PLATFORM_MICROSOFT.                                                */
+  /*                                                                       */
+  /* The canonical source for the MS assigned LCID's is at                 */
+  /* http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt.               */
+  /*                                                                       */
+#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA               0x0401
+#define TT_MS_LANGID_ARABIC_IRAQ                       0x0801
+#define TT_MS_LANGID_ARABIC_EGYPT                      0x0c01
+#define TT_MS_LANGID_ARABIC_LIBYA                      0x1001
+#define TT_MS_LANGID_ARABIC_ALGERIA                    0x1401
+#define TT_MS_LANGID_ARABIC_MOROCCO                    0x1801
+#define TT_MS_LANGID_ARABIC_TUNISIA                    0x1c01
+#define TT_MS_LANGID_ARABIC_OMAN                       0x2001
+#define TT_MS_LANGID_ARABIC_YEMEN                      0x2401
+#define TT_MS_LANGID_ARABIC_SYRIA                      0x2801
+#define TT_MS_LANGID_ARABIC_JORDAN                     0x2c01
+#define TT_MS_LANGID_ARABIC_LEBANON                    0x3001
+#define TT_MS_LANGID_ARABIC_KUWAIT                     0x3401
+#define TT_MS_LANGID_ARABIC_UAE                        0x3801
+#define TT_MS_LANGID_ARABIC_BAHRAIN                    0x3c01
+#define TT_MS_LANGID_ARABIC_QATAR                      0x4001
+#define TT_MS_LANGID_BULGARIAN_BULGARIA                0x0402
+#define TT_MS_LANGID_CATALAN_SPAIN                     0x0403
+#define TT_MS_LANGID_CHINESE_TAIWAN                    0x0404
+#define TT_MS_LANGID_CHINESE_PRC                       0x0804
+#define TT_MS_LANGID_CHINESE_HONG_KONG                 0x0c04
+#define TT_MS_LANGID_CHINESE_SINGAPORE                 0x1004
+#define TT_MS_LANGID_CHINESE_MACAU                     0x1404
+#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC              0x0405
+#define TT_MS_LANGID_DANISH_DENMARK                    0x0406
+#define TT_MS_LANGID_GERMAN_GERMANY                    0x0407
+#define TT_MS_LANGID_GERMAN_SWITZERLAND                0x0807
+#define TT_MS_LANGID_GERMAN_AUSTRIA                    0x0c07
+#define TT_MS_LANGID_GERMAN_LUXEMBOURG                 0x1007
+#define TT_MS_LANGID_GERMAN_LIECHTENSTEI               0x1407
+#define TT_MS_LANGID_GREEK_GREECE                      0x0408
+#define TT_MS_LANGID_ENGLISH_UNITED_STATES             0x0409
+#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM            0x0809
+#define TT_MS_LANGID_ENGLISH_AUSTRALIA                 0x0c09
+#define TT_MS_LANGID_ENGLISH_CANADA                    0x1009
+#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND               0x1409
+#define TT_MS_LANGID_ENGLISH_IRELAND                   0x1809
+#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA              0x1c09
+#define TT_MS_LANGID_ENGLISH_JAMAICA                   0x2009
+#define TT_MS_LANGID_ENGLISH_CARIBBEAN                 0x2409
+#define TT_MS_LANGID_ENGLISH_BELIZE                    0x2809
+#define TT_MS_LANGID_ENGLISH_TRINIDAD                  0x2c09
+#define TT_MS_LANGID_ENGLISH_ZIMBABWE                  0x3009
+#define TT_MS_LANGID_ENGLISH_PHILIPPINES               0x3409
+#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT    0x040a
+#define TT_MS_LANGID_SPANISH_MEXICO                    0x080a
+#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT  0x0c0a
+#define TT_MS_LANGID_SPANISH_GUATEMALA                 0x100a
+#define TT_MS_LANGID_SPANISH_COSTA_RICA                0x140a
+#define TT_MS_LANGID_SPANISH_PANAMA                    0x180a
+#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC        0x1c0a
+#define TT_MS_LANGID_SPANISH_VENEZUELA                 0x200a
+#define TT_MS_LANGID_SPANISH_COLOMBIA                  0x240a
+#define TT_MS_LANGID_SPANISH_PERU                      0x280a
+#define TT_MS_LANGID_SPANISH_ARGENTINA                 0x2c0a
+#define TT_MS_LANGID_SPANISH_ECUADOR                   0x300a
+#define TT_MS_LANGID_SPANISH_CHILE                     0x340a
+#define TT_MS_LANGID_SPANISH_URUGUAY                   0x380a
+#define TT_MS_LANGID_SPANISH_PARAGUAY                  0x3c0a
+#define TT_MS_LANGID_SPANISH_BOLIVIA                   0x400a
+#define TT_MS_LANGID_SPANISH_EL_SALVADOR               0x440a
+#define TT_MS_LANGID_SPANISH_HONDURAS                  0x480a
+#define TT_MS_LANGID_SPANISH_NICARAGUA                 0x4c0a
+#define TT_MS_LANGID_SPANISH_PUERTO_RICO               0x500a
+#define TT_MS_LANGID_FINNISH_FINLAND                   0x040b
+#define TT_MS_LANGID_FRENCH_FRANCE                     0x040c
+#define TT_MS_LANGID_FRENCH_BELGIUM                    0x080c
+#define TT_MS_LANGID_FRENCH_CANADA                     0x0c0c
+#define TT_MS_LANGID_FRENCH_SWITZERLAND                0x100c
+#define TT_MS_LANGID_FRENCH_LUXEMBOURG                 0x140c
+#define TT_MS_LANGID_FRENCH_MONACO                     0x180c
+#define TT_MS_LANGID_HEBREW_ISRAEL                     0x040d
+#define TT_MS_LANGID_HUNGARIAN_HUNGARY                 0x040e
+#define TT_MS_LANGID_ICELANDIC_ICELAND                 0x040f
+#define TT_MS_LANGID_ITALIAN_ITALY                     0x0410
+#define TT_MS_LANGID_ITALIAN_SWITZERLAND               0x0810
+#define TT_MS_LANGID_JAPANESE_JAPAN                    0x0411
+#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA     0x0412
+#define TT_MS_LANGID_KOREAN_JOHAB_KOREA                0x0812
+#define TT_MS_LANGID_DUTCH_NETHERLANDS                 0x0413
+#define TT_MS_LANGID_DUTCH_BELGIUM                     0x0813
+#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL           0x0414
+#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK          0x0814
+#define TT_MS_LANGID_POLISH_POLAND                     0x0415
+#define TT_MS_LANGID_PORTUGUESE_BRAZIL                 0x0416
+#define TT_MS_LANGID_PORTUGUESE_PORTUGAL               0x0816
+#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND        0x0417
+#define TT_MS_LANGID_ROMANIAN_ROMANIA                  0x0418
+#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA                0x0818
+#define TT_MS_LANGID_RUSSIAN_RUSSIA                    0x0419
+#define TT_MS_LANGID_RUSSIAN_MOLDAVIA                  0x0819
+#define TT_MS_LANGID_CROATIAN_CROATIA                  0x041a
+#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN              0x081a
+#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC           0x0c1a
+#define TT_MS_LANGID_SLOVAK_SLOVAKIA                   0x041b
+#define TT_MS_LANGID_ALBANIAN_ALBANIA                  0x041c
+#define TT_MS_LANGID_SWEDISH_SWEDEN                    0x041d
+#define TT_MS_LANGID_SWEDISH_FINLAND                   0x081d
+#define TT_MS_LANGID_THAI_THAILAND                     0x041e
+#define TT_MS_LANGID_TURKISH_TURKEY                    0x041f
+#define TT_MS_LANGID_URDU_PAKISTAN                     0x0420
+#define TT_MS_LANGID_INDONESIAN_INDONESIA              0x0421
+#define TT_MS_LANGID_UKRAINIAN_UKRAINE                 0x0422
+#define TT_MS_LANGID_BELARUSIAN_BELARUS                0x0423
+#define TT_MS_LANGID_SLOVENE_SLOVENIA                  0x0424
+#define TT_MS_LANGID_ESTONIAN_ESTONIA                  0x0425
+#define TT_MS_LANGID_LATVIAN_LATVIA                    0x0426
+#define TT_MS_LANGID_LITHUANIAN_LITHUANIA              0x0427
+#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA      0x0827
+#define TT_MS_LANGID_MAORI_NEW_ZEALAND                 0x0428
+#define TT_MS_LANGID_FARSI_IRAN                        0x0429
+#define TT_MS_LANGID_VIETNAMESE_VIET_NAM               0x042a
+#define TT_MS_LANGID_ARMENIAN_ARMENIA                  0x042b
+#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN            0x042c
+#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC         0x082c
+#define TT_MS_LANGID_BASQUE_SPAIN                      0x042d
+#define TT_MS_LANGID_SORBIAN_GERMANY                   0x042e
+#define TT_MS_LANGID_MACEDONIAN_MACEDONIA              0x042f
+#define TT_MS_LANGID_SUTU_SOUTH_AFRICA                 0x0430
+#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA               0x0431
+#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA               0x0432
+#define TT_MS_LANGID_VENDA_SOUTH_AFRICA                0x0433
+#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA                0x0434
+#define TT_MS_LANGID_ZULU_SOUTH_AFRICA                 0x0435
+#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA            0x0436
+#define TT_MS_LANGID_GEORGIAN_GEORGIA                  0x0437
+#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS           0x0438
+#define TT_MS_LANGID_HINDI_INDIA                       0x0439
+#define TT_MS_LANGID_MALTESE_MALTA                     0x043a
+#define TT_MS_LANGID_SAAMI_LAPONIA                     0x043b
+#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043c
+#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083c
+#define TT_MS_LANGID_MALAY_MALAYSIA                    0x043e
+#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM           0x083e
+#define TT_MS_LANGID_KAZAK_KAZAKSTAN                   0x043f
+#define TT_MS_LANGID_SWAHILI_KENYA                     0x0441
+#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN            0x0443
+#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC         0x0843
+#define TT_MS_LANGID_TATAR_TATARSTAN                   0x0444
+#define TT_MS_LANGID_BENGALI_INDIA                     0x0445
+#define TT_MS_LANGID_PUNJABI_INDIA                     0x0446
+#define TT_MS_LANGID_GUJARATI_INDIA                    0x0447
+#define TT_MS_LANGID_ORIYA_INDIA                       0x0448
+#define TT_MS_LANGID_TAMIL_INDIA                       0x0449
+#define TT_MS_LANGID_TELUGU_INDIA                      0x044a
+#define TT_MS_LANGID_KANNADA_INDIA                     0x044b
+#define TT_MS_LANGID_MALAYALAM_INDIA                   0x044c
+#define TT_MS_LANGID_ASSAMESE_INDIA                    0x044d
+#define TT_MS_LANGID_MARATHI_INDIA                     0x044e
+#define TT_MS_LANGID_SANSKRIT_INDIA                    0x044f
+#define TT_MS_LANGID_KONKANI_INDIA                     0x0457
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* possible values of the `Name' identifier field in the name records of */
+  /* the TTF `name' table.  These values are platform independent.         */
+  /*                                                                       */
+#define TT_NAME_ID_COPYRIGHT             0
+#define TT_NAME_ID_FONT_FAMILY           1
+#define TT_NAME_ID_FONT_SUBFAMILY        2
+#define TT_NAME_ID_UNIQUE_ID             3
+#define TT_NAME_ID_FULL_NAME             4
+#define TT_NAME_ID_VERSION_STRING        5
+#define TT_NAME_ID_PS_NAME               6
+#define TT_NAME_ID_TRADEMARK             7
+/* the following values are from the OpenType spec */
+#define TT_NAME_ID_MANUFACTURER          8
+#define TT_NAME_ID_DESIGNER              9
+#define TT_NAME_ID_DESCRIPTION          10
+#define TT_NAME_ID_VENDOR_URL           11
+#define TT_NAME_ID_DESIGNER_URL         12
+#define TT_NAME_ID_LICENSE              13
+#define TT_NAME_ID_LICENSE_URL          14
+/* number 15 is reserved */
+#define TT_NAME_ID_PREFERRED_FAMILY     16
+#define TT_NAME_ID_PREFERRED_SUBFAMILY  17
+#define TT_NAME_ID_MAC_FULL_NAME        18
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Bit mask values for the Unicode ranges from the TTF `OS2 ' table.     */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+/* General Scripts Area */
+
+/* Bit  0   C0 Controls and Basic Latin */
+#define TT_UCR_BASIC_LATIN                      (1 <<  0) /* U+0000-U+007F */
+/* Bit  1   C1 Controls and Latin-1 Supplement */
+#define TT_UCR_LATIN1_SUPPLEMENT                (1 <<  1) /* U+0080-U+00FF */
+/* Bit  2   Latin Extended-A */
+#define TT_UCR_LATIN_EXTENDED_A                 (1 <<  2) /* U+0100-U+017F */
+/* Bit  3   Latin Extended-B */
+#define TT_UCR_LATIN_EXTENDED_B                 (1 <<  3) /* U+0180-U+024F */
+/* Bit  4   IPA Extensions */
+#define TT_UCR_IPA_EXTENSIONS                   (1 <<  4) /* U+0250-U+02AF */
+/* Bit  5   Spacing Modifier Letters */
+#define TT_UCR_SPACING_MODIFIER                 (1 <<  5) /* U+02B0-U+02FF */
+/* Bit  6   Combining Diacritical Marks */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS      (1 <<  6) /* U+0300-U+036F */
+/* Bit  7   Greek */
+#define TT_UCR_GREEK                            (1 <<  7) /* U+0370-U+03FF */
+/* Bit 8 is reserved (was: Greek Symbols and Coptic) */
+/* Bit  9   Cyrillic */
+#define TT_UCR_CYRILLIC                         (1 <<  9) /* U+0400-U+04FF */
+/* Bit 10   Armenian */
+#define TT_UCR_ARMENIAN                         (1 << 10) /* U+0530-U+058F */
+/* Bit 11   Hebrew */
+#define TT_UCR_HEBREW                           (1 << 11) /* U+0590-U+05FF */
+/* Bit 12 is reserved (was: Hebrew Extended) */
+/* Bit 13   Arabic */
+#define TT_UCR_ARABIC                           (1 << 13) /* U+0600-U+06FF */
+/* Bit 14 is reserved (was: Arabic Extended) */
+/* Bit 15   Devanagari */
+#define TT_UCR_DEVANAGARI                       (1 << 15) /* U+0900-U+097F */
+/* Bit 16   Bengali */
+#define TT_UCR_BENGALI                          (1 << 16) /* U+0980-U+09FF */
+/* Bit 17   Gurmukhi */
+#define TT_UCR_GURMUKHI                         (1 << 17) /* U+0A00-U+0A7F */
+/* Bit 18   Gujarati */
+#define TT_UCR_GUJARATI                         (1 << 18) /* U+0A80-U+0AFF */
+/* Bit 19   Oriya */
+#define TT_UCR_ORIYA                            (1 << 19) /* U+0B00-U+0B7F */
+/* Bit 20   Tamil */
+#define TT_UCR_TAMIL                            (1 << 20) /* U+0B80-U+0BFF */
+/* Bit 21   Telugu */
+#define TT_UCR_TELUGU                           (1 << 21) /* U+0C00-U+0C7F */
+/* Bit 22   Kannada */
+#define TT_UCR_KANNADA                          (1 << 22) /* U+0C80-U+0CFF */
+/* Bit 23   Malayalam */
+#define TT_UCR_MALAYALAM                        (1 << 23) /* U+0D00-U+0D7F */
+/* Bit 24   Thai */
+#define TT_UCR_THAI                             (1 << 24) /* U+0E00-U+0E7F */
+/* Bit 25   Lao */
+#define TT_UCR_LAO                              (1 << 25) /* U+0E80-U+0EFF */
+/* Bit 26   Georgian */
+#define TT_UCR_GEORGIAN                         (1 << 26) /* U+10A0-U+10FF */
+/* Bit 27 is reserved (was Georgian Extended) */
+/* Bit 28   Hangul Jamo */
+#define TT_UCR_HANGUL_JAMO                      (1 << 28) /* U+1100-U+11FF */
+/* Bit 29   Latin Extended Additional */
+#define TT_UCR_LATIN_EXTENDED_ADDITIONAL        (1 << 29) /* U+1E00-U+1EFF */
+/* Bit 30   Greek Extended */
+#define TT_UCR_GREEK_EXTENDED                   (1 << 30) /* U+1F00-U+1FFF */
+
+/* Symbols Area */
+
+/* Bit 31   General Punctuation */
+#define TT_UCR_GENERAL_PUNCTUATION              (1 << 31) /* U+2000-U+206F */
+/* Bit 32   Superscripts And Subscripts */
+#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS          (1 <<  0) /* U+2070-U+209F */
+/* Bit 33   Currency Symbols */
+#define TT_UCR_CURRENCY_SYMBOLS                 (1 <<  1) /* U+20A0-U+20CF */
+/* Bit 34   Combining Diacritical Marks For Symbols */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB (1 <<  2) /* U+20D0-U+20FF */
+/* Bit 35   Letterlike Symbols */
+#define TT_UCR_LETTERLIKE_SYMBOLS               (1 <<  3) /* U+2100-U+214F */
+/* Bit 36   Number Forms */
+#define TT_UCR_NUMBER_FORMS                     (1 <<  4) /* U+2150-U+218F */
+/* Bit 37   Arrows */
+#define TT_UCR_ARROWS                           (1 <<  5) /* U+2190-U+21FF */
+/* Bit 38   Mathematical Operators */
+#define TT_UCR_MATHEMATICAL_OPERATORS           (1 <<  6) /* U+2200-U+22FF */
+/* Bit 39 Miscellaneous Technical */
+#define TT_UCR_MISCELLANEOUS_TECHNICAL          (1 <<  7) /* U+2300-U+23FF */
+/* Bit 40   Control Pictures */
+#define TT_UCR_CONTROL_PICTURES                 (1 <<  8) /* U+2400-U+243F */
+/* Bit 41   Optical Character Recognition */
+#define TT_UCR_OCR                              (1 <<  9) /* U+2440-U+245F */
+/* Bit 42   Enclosed Alphanumerics */
+#define TT_UCR_ENCLOSED_ALPHANUMERICS           (1 << 10) /* U+2460-U+24FF */
+/* Bit 43   Box Drawing */
+#define TT_UCR_BOX_DRAWING                      (1 << 11) /* U+2500-U+257F */
+/* Bit 44   Block Elements */
+#define TT_UCR_BLOCK_ELEMENTS                   (1 << 12) /* U+2580-U+259F */
+/* Bit 45   Geometric Shapes */
+#define TT_UCR_GEOMETRIC_SHAPES                 (1 << 13) /* U+25A0-U+25FF */
+/* Bit 46   Miscellaneous Symbols */
+#define TT_UCR_MISCELLANEOUS_SYMBOLS            (1 << 14) /* U+2600-U+26FF */
+/* Bit 47   Dingbats */
+#define TT_UCR_DINGBATS                         (1 << 15) /* U+2700-U+27BF */
+
+/* CJK Phonetics and Symbols Area */
+
+/* Bit 48   CJK Symbols And Punctuation */
+#define TT_UCR_CJK_SYMBOLS                      (1 << 16) /* U+3000-U+303F */
+/* Bit 49   Hiragana */
+#define TT_UCR_HIRAGANA                         (1 << 17) /* U+3040-U+309F */
+/* Bit 50   Katakana */
+#define TT_UCR_KATAKANA                         (1 << 18) /* U+30A0-U+30FF */
+/* Bit 51   Bopomofo */
+#define TT_UCR_BOPOMOFO                         (1 << 19) /* U+3100-U+312F */
+/* Bit 52   Hangul Compatibility Jamo */
+#define TT_UCR_HANGUL_COMPATIBILITY_JAMO        (1 << 20) /* U+3130-U+318F */
+/* Bit 53   CJK Miscellaneous */
+#define TT_UCR_CJK_MISC                         (1 << 21) /* U+3190-U+319F */
+/* Bit 54   Enclosed CJK Letters And Months */
+#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS      (1 << 22) /* U+3200-U+32FF */
+/* Bit 55   CJK Compatibility */
+#define TT_UCR_CJK_COMPATIBILITY                (1 << 23) /* U+3300-U+33FF */
+
+/* Hangul Syllables Area */
+
+/* Bit 56   Hangul */
+#define TT_UCR_HANGUL                           (1 << 24) /* U+AC00-U+D7A3 */
+
+/* Surrogates Area */
+
+/* Bit 57   Surrogates */
+#define TT_UCR_SURROGATES                       (1 << 25) /* U+D800-U+DFFF */
+/* Bit 58 is reserved for Unicode SubRanges */
+
+/* CJK Ideographs Area */
+
+/* Bit 59   CJK Unified Ideographs */
+#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS           (1 << 27) /* U+4E00-U+9FFF */
+
+/* Private Use Area */
+
+/* Bit 60   Private Use */
+#define TT_UCR_PRIVATE_USE                      (1 << 28) /* U+E000-U+F8FF */
+
+/* Compatibility Area and Specials */
+
+/* Bit 61   CJK Compatibility Ideographs */
+#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS     (1 << 29) /* U+F900-U+FAFF */
+/* Bit 62   Alphabetic Presentation Forms */
+#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS    (1 << 30) /* U+FB00-U+FB4F */
+/* Bit 63   Arabic Presentation Forms-A */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_A      (1 << 31) /* U+FB50-U+FSFF */
+/* Bit 64   Combining Half Marks */
+#define TT_UCR_COMBINING_HALF_MARKS             (1 <<  0) /* U+FE20-U+FE2F */
+/* Bit 65   CJK Compatibility Forms */
+#define TT_UCR_CJK_COMPATIBILITY_FORMS          (1 <<  1) /* U+FE30-U+FE4F */
+/* Bit 66   Small Form Variants */
+#define TT_UCR_SMALL_FORM_VARIANTS              (1 <<  2) /* U+FE50-U+FE6F */
+/* Bit 67   Arabic Presentation Forms-B */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_B      (1 <<  3) /* U+FE70-U+FEFF */
+/* Bit 68   Halfwidth And Fullwidth Forms */
+#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS        (1 <<  4) /* U+FF00-U+FFEF */
+/* Bit 69   Specials */
+#define TT_UCR_SPECIALS                         (1 <<  5) /* U+FEFF,
+                                                             U+FFF0-U+FFFF */
+/* Bit 70   Tibetan */
+#define TT_UCR_TIBETAN                          (1 <<  6) /* U+0F00-U+0FBF */
+
+
+#endif /* TTNAMEID_H */
+
+
+/* END */
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
new file mode 100644
index 0000000..caa14ab
--- /dev/null
+++ b/src/truetype/ttobjs.c
@@ -0,0 +1,888 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttobjs.c                                                               */
+/*                                                                         */
+/*    Objects manager (body).                                              */
+/*                                                                         */
+/*  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 <freetype.h>
+#include <ftdebug.h>
+#include <ftcalc.h>
+#include <ftstream.h>
+#include <ttnameid.h>
+
+#include <sfnt.h>
+
+#include <ttpload.h>
+#include <ttinterp.h>
+#include <tterrors.h>
+
+/* required by tracing mode */
+#undef   FT_COMPONENT
+#define  FT_COMPONENT  trace_ttobjs
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                       GLYPH ZONE FUNCTIONS                            */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_New_GlyphZone                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Allocates a new glyph zone.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory      :: A handle to the current memory object.              */
+  /*                                                                       */
+  /*    maxPoints   :: The capacity of glyph zone in points.               */
+  /*                                                                       */
+  /*    maxContours :: The capacity of glyph zone in contours.             */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    pts         :: A pointer to the target glyph zone record.          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_New_GlyphZone( FT_Memory      memory,
+                              TT_GlyphZone*  pts,
+                              TT_UShort      maxPoints,
+                              TT_Short       maxContours )
+  {
+    TT_Error  error;
+
+
+    if ( ALLOC( pts->org, maxPoints * 2 * sizeof ( TT_F26Dot6 )   ) ||
+         ALLOC( pts->cur, maxPoints * 2 * sizeof ( TT_F26Dot6 )   ) ||
+         ALLOC( pts->touch, maxPoints * sizeof ( TT_Byte )        ) ||
+         ALLOC( pts->contours, maxContours * sizeof ( TT_UShort ) ) )
+      return error;
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_GlyphZone                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Deallocates a glyph zone.                                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to the current memory object.                   */
+  /*                                                                       */
+  /*    pts    :: A pointer to the target glyph zone record.               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Done_GlyphZone( FT_Memory      memory,
+                               TT_GlyphZone*  pts )
+  {
+    FREE( pts->contours );
+    FREE( pts->touch );
+    FREE( pts->cur );
+    FREE( pts->org );
+
+    return TT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Get_Name                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Returns a given ENGLISH name record in ASCII.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the source face object.                      */
+  /*                                                                       */
+  /*    nameid :: The name id of the name record to return.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Char string.  NULL if no name is present.                          */
+  /*                                                                       */
+  static
+  FT_String*  Get_Name( TT_Face    face,
+                        TT_UShort  nameid )
+  {
+    FT_Memory    memory = face->root.memory;
+    TT_UShort    n;
+    TT_NameRec*  rec;
+    TT_Bool      wide_chars = 1;
+
+    /* first pass, look for a given name record */
+
+    rec = face->name_table.names;
+    for ( n = 0; n < face->name_table.numNameRecords; n++, rec++ )
+    {
+      if ( rec->nameID == nameid )
+      {
+        /* found the name - now create an ASCII string from it */
+        TT_Bool  found = 0;
+
+
+        /* Test for Microsoft English language */
+        if ( rec->platformID == TT_PLATFORM_MICROSOFT &&
+             rec->encodingID <  TT_MS_ID_UNICODE_CS   &&
+             (rec->languageID & 0x3FF) == 0x009 )
+          found = 1;
+
+        /* Test for Apple Unicode encoding */
+        else if ( rec->platformID == TT_PLATFORM_APPLE_UNICODE )
+          found = 1;
+        
+        /* Test for Apple Roman */
+        else if ( rec->platformID == TT_PLATFORM_MACINTOSH &&
+                  rec->languageID == TT_MAC_ID_ROMAN       )
+        {
+          found      = 1;
+          wide_chars = 0;
+        }
+
+        /* Found a Unicode Name */
+        if ( found )
+        {
+          TT_String*  string;
+          TT_UInt     len;
+
+          if ( wide_chars )
+          {
+            TT_UInt   m;
+            
+            len = (TT_UInt)rec->stringLength / 2;
+            if ( MEM_Alloc( string, len + 1 ) )
+              return NULL;
+    
+            for ( m = 0; m < len; m ++ )
+              string[m] = rec->string[2*m + 1];
+          }
+          else
+          {
+            len = rec->stringLength;
+            if ( MEM_Alloc( string, len + 1 ) )
+              return NULL;
+
+            MEM_Copy( string, rec->string, len );
+          }
+
+          string[len] = '\0';
+          return string;
+        }
+      }
+    }
+    return NULL;
+  }
+
+
+#undef  LOAD_
+#define LOAD_(x)   ( (error = sfnt->load_##x( face, stream )) != TT_Err_Ok )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Init_Face                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a given TrueType face object.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    resource   :: The source font resource.                            */
+  /*    face_index :: The index of the font face in the resource.          */
+  /*    face       :: The newly built face object.                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Init_Face( FT_Stream  stream,
+                          TT_Long    face_index,
+                          TT_Face    face )
+  {
+    TT_Error         error;
+    SFNT_Interface*  sfnt;
+
+    sfnt = (SFNT_Interface*)face->sfnt;
+    if (!sfnt)
+    {
+      /* look-up the SFNT driver */
+      FT_Driver  sfnt_driver;
+      
+      sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" );
+      if (!sfnt_driver)
+        return FT_Err_Invalid_File_Format;
+        
+      sfnt = (SFNT_Interface*)(sfnt_driver->interface.format_interface);
+      if (!sfnt)
+        return FT_Err_Invalid_File_Format;
+        
+      face->sfnt       = sfnt;
+      face->goto_table = sfnt->goto_table;
+    }
+    
+    /* create input stream from resource */
+    if ( FILE_Seek(0) )
+      goto Exit;
+
+    /* Load collection directory if present, then font directory */
+    error = sfnt->load_directory( face, stream, face_index );
+    if ( error ) goto Exit;
+
+    face->root.num_faces = face->ttc_header.DirCount;
+    if ( face->root.num_faces < 1 )
+      face->root.num_faces = 1;
+
+    /* If we're performing a simple font format check, exit immediately */
+    if ( face_index < 0 )
+      return TT_Err_Ok;
+
+    /* Load tables */
+
+    if ( LOAD_( header )        ||
+         LOAD_( max_profile )   ||
+
+         (error = sfnt->load_metrics( face, stream, 0 )) != TT_Err_Ok  ||
+         /* load the `hhea' & `hmtx' tables at once */
+
+         (error = sfnt->load_metrics( face, stream, 1 )) != TT_Err_Ok ||
+         /* try to load the `vhea' & `vmtx' at once if present */
+
+         LOAD_( charmaps )      ||
+         LOAD_( names )         ||
+         LOAD_( os2 )           ||
+         LOAD_( psnames )       ||
+
+         /* the optional tables */
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+         LOAD_( sbits )  ||
+#endif
+         LOAD_( hdmx )          ||
+         LOAD_( gasp )          ||
+         LOAD_( kerning )       ||
+
+         (error = TT_Load_Locations( face, stream )) != TT_Err_Ok ||
+         (error = TT_Load_CVT      ( face, stream )) != TT_Err_Ok ||
+         (error = TT_Load_Programs ( face, stream )) != TT_Err_Ok )
+
+      goto Exit;
+
+#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
+    if ( ( error = TT_Extension_Create( face ) ) != TT_Err_Ok )
+      goto Exit;
+#endif
+
+    face->root.family_name = Get_Name( face, TT_NAME_ID_FONT_FAMILY );
+    face->root.style_name  = Get_Name( face, TT_NAME_ID_FONT_SUBFAMILY );
+
+  Exit:
+    return error;
+  }
+
+
+#undef LOAD_
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_Face                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finalizes a given face object.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: A pointer to the face object to destroy.                   */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Done_Face( TT_Face  face )
+  {
+    TT_UShort  n;
+    FT_Memory  memory = face->root.memory;
+
+    SFNT_Interface*  sfnt = face->sfnt;
+    
+    if (sfnt)
+    {
+      /* destroy the postscript names table if it is supported */
+      if (sfnt->load_psnames)
+        sfnt->free_psnames( face );
+        
+      /* destroy the embedded bitmaps table if it is supported */
+      if (sfnt->load_sbits)
+        sfnt->free_sbits( face );
+    }
+
+    /* freeing the kerning table */
+    FREE( face->kern_pairs );
+    face->num_kern_pairs = 0;
+
+    /* freeing the collection table */
+    FREE( face->ttc_header.TableDirectory );
+    face->ttc_header.DirCount = 0;
+
+    /* freeing table directory */
+    FREE( face->dir_tables );
+    face->num_tables = 0;
+
+    /* freeing the locations table */
+    FREE( face->glyph_locations );
+    face->num_locations = 0;
+
+    /* freeing the character mapping tables */
+    if (sfnt && sfnt->load_charmaps )
+    {
+      for ( n = 0; n < face->num_charmaps; n++ )
+        sfnt->free_charmap( face, &face->charmaps[n].cmap );
+    }
+
+    FREE( face->charmaps );
+    face->num_charmaps = 0;
+
+    FREE( face->root.charmaps );
+    face->root.num_charmaps = 0;
+    face->root.charmap      = 0;
+
+    /* freeing the CVT */
+    FREE( face->cvt );
+    face->cvt_size = 0;
+
+    /* freeing the horizontal metrics */
+    FREE( face->horizontal.long_metrics );
+    FREE( face->horizontal.short_metrics );
+
+    /* freeing the vertical ones, if any */
+    if ( face->vertical_info )
+    {
+      FREE( face->vertical.long_metrics  );
+      FREE( face->vertical.short_metrics );
+      face->vertical_info = 0;
+    }
+
+    /* freeing the programs */
+    FREE( face->font_program );
+    FREE( face->cvt_program );
+    face->font_program_size = 0;
+    face->cvt_program_size  = 0;
+
+    /* freeing the gasp table */
+    FREE( face->gasp.gaspRanges );
+    face->gasp.numRanges = 0;
+
+    /* freeing the name table */
+    sfnt->free_names( face );
+
+    /* freeing the hdmx table */
+    sfnt->free_hdmx( face );
+
+    /* freeing family and style name */
+    FREE( face->root.family_name );
+    FREE( face->root.style_name );
+    
+    face->sfnt = 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*                           SIZE  FUNCTIONS                             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Init_Size                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a new TrueType size object.                            */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    size :: A handle to the size object.                               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Init_Size( TT_Size  size )
+  {
+    TT_Face    face   = (TT_Face)size->root.face;
+    FT_Memory  memory = face->root.memory;
+    TT_Error   error;
+    TT_Int     i;
+    TT_UShort  n_twilight;
+
+    TT_MaxProfile*  maxp = &face->max_profile;
+    TT_ExecContext  exec;
+
+    size->ttmetrics.valid = FALSE;
+
+    size->max_function_defs    = maxp->maxFunctionDefs;
+    size->max_instruction_defs = maxp->maxInstructionDefs;
+
+    size->num_function_defs    = 0;
+    size->num_instruction_defs = 0;
+
+    size->max_func = 0;
+    size->max_ins  = 0;
+
+    size->cvt_size     = face->cvt_size;
+    size->storage_size = maxp->maxStorage;
+
+    /* Set default metrics */
+    {
+      FT_Size_Metrics*  metrics  = &size->root.metrics;
+      TT_Size_Metrics*  metrics2 = &size->ttmetrics;
+
+      metrics->x_ppem = 0;
+      metrics->y_ppem = 0;
+
+      metrics2->rotated   = FALSE;
+      metrics2->stretched = FALSE;
+
+      /* set default compensation (all 0) */
+      for ( i = 0; i < 4; i++ )
+        metrics2->compensations[i] = 0;
+    }
+
+    /* allocate function defs, instruction defs, cvt and storage area */
+    if ( ALLOC_ARRAY( size->function_defs,
+                      size->max_function_defs,
+                      TT_DefRecord )                ||
+
+         ALLOC_ARRAY( size->instruction_defs,
+                      size->max_instruction_defs,
+                      TT_DefRecord )                ||
+
+         ALLOC_ARRAY( size->cvt,
+                      size->cvt_size, TT_Long )     ||
+
+         ALLOC_ARRAY( size->storage,
+                      size->storage_size, TT_Long ) )
+
+      goto Fail_Memory;
+
+    /* reserve twilight zone */
+    n_twilight = maxp->maxTwilightPoints;
+    error = TT_New_GlyphZone( memory, &size->twilight, n_twilight, 0 );
+    if ( error )
+      goto Fail_Memory;
+
+    size->twilight.n_points = n_twilight;
+
+    /* set `face->interpreter' according to the debug hook present */
+    {
+      FT_Library  library = face->root.driver->library;
+      
+      face->interpreter = (TT_Interpreter)
+                            library->debug_hooks[ FT_DEBUG_HOOK_TRUETYPE ];
+      if (!face->interpreter)
+        face->interpreter = (TT_Interpreter)TT_RunIns;
+    }
+
+    /* Fine, now execute the font program! */
+    exec = size->context;
+    if (!size->debug)
+      exec = TT_New_Context( face );
+    /* size objects used during debugging have their own context */
+
+    if ( !exec )
+    {
+      error = TT_Err_Could_Not_Find_Context;
+      goto Fail_Memory;
+    }
+
+    size->GS = tt_default_graphics_state;
+    TT_Load_Context( exec, face, size );
+
+    exec->callTop   = 0;
+    exec->top       = 0;
+
+    exec->period    = 64;
+    exec->phase     = 0;
+    exec->threshold = 0;
+
+    {
+      FT_Size_Metrics*  metrics    = &exec->metrics;
+      TT_Size_Metrics*  tt_metrics = &exec->tt_metrics;
+
+
+      metrics->x_ppem    = 0;
+      metrics->y_ppem    = 0;
+      metrics->x_scale   = 0;
+      metrics->y_scale   = 0;
+
+      tt_metrics->ppem   = 0;
+      tt_metrics->scale  = 0;
+      tt_metrics->ratio  = 0x10000;
+    }
+
+    exec->instruction_trap = FALSE;
+
+    exec->cvtSize = size->cvt_size;
+    exec->cvt     = size->cvt;
+
+    exec->F_dot_P = 0x10000L;
+
+    /* allow font program execution */
+    TT_Set_CodeRange( exec,
+                      tt_coderange_font,
+                      face->font_program,
+                      face->font_program_size );
+
+    /* disable CVT and glyph programs coderange */
+    TT_Clear_CodeRange( exec, tt_coderange_cvt );
+    TT_Clear_CodeRange( exec, tt_coderange_glyph );
+
+    if ( face->font_program_size > 0 )
+    {
+      error = TT_Goto_CodeRange( exec, tt_coderange_font, 0 );
+      if ( !error )
+        error = face->interpreter( exec );
+
+      if ( error )
+        goto Fail_Exec;
+    }
+    else
+      error = TT_Err_Ok;
+
+    TT_Save_Context( exec, size );
+
+    if ( !size->debug )
+      TT_Done_Context( exec );
+
+    size->ttmetrics.valid = FALSE;
+    return error;
+
+  Fail_Exec:
+    if ( !size->debug )
+      TT_Done_Context( exec );
+
+  Fail_Memory:
+    TT_Done_Size( size );
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_Size                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType size object finalizer.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size :: A handle to the target size object.                        */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  TT_Done_Size( TT_Size  size )
+  {
+    FT_Memory  memory = size->root.face->memory;
+
+
+    if ( size->debug )
+    {
+      /* the debug context must be deleted by the debugger itself */
+      size->context = NULL;
+      size->debug   = FALSE;
+    }
+
+    FREE( size->cvt );
+    size->cvt_size = 0;
+
+    /* free storage area */
+    FREE( size->storage );
+    size->storage_size = 0;
+
+    /* twilight zone */
+    TT_Done_GlyphZone( memory, &size->twilight );
+
+    FREE( size->function_defs );
+    FREE( size->instruction_defs );
+    size->num_function_defs    = 0;
+    size->max_function_defs    = 0;
+    size->num_instruction_defs = 0;
+    size->max_instruction_defs = 0;
+
+    size->max_func = 0;
+    size->max_ins  = 0;
+
+    size->ttmetrics.valid = FALSE;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Reset_Size                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Resets a TrueType size when resolutions and character dimensions   */
+  /*    have been changed.                                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size :: A handle to the target size object.                        */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Reset_Size( TT_Size  size )
+  {
+    TT_ExecContext    exec;
+    TT_Error          error;
+    TT_UShort         i, j;
+    TT_Face           face;
+
+    FT_Size_Metrics*  metrics;
+
+    if ( size->ttmetrics.valid )
+      return TT_Err_Ok;
+
+    face = (TT_Face)size->root.face;
+
+    metrics = &size->root.metrics;
+
+    if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
+      return TT_Err_Invalid_PPem;
+
+    /* compute new transformation */
+    if ( metrics->x_ppem >= metrics->y_ppem )
+    {
+      size->ttmetrics.scale   = metrics->x_scale;
+      size->ttmetrics.ppem    = metrics->x_ppem;
+      size->ttmetrics.x_ratio = 0x10000;
+      size->ttmetrics.y_ratio = FT_MulDiv( metrics->y_ppem,
+                                           0x10000L,
+                                           metrics->x_ppem );
+    }
+    else
+    {
+      size->ttmetrics.scale   = metrics->y_scale;
+      size->ttmetrics.ppem    = metrics->y_ppem;
+      size->ttmetrics.x_ratio = FT_MulDiv( metrics->x_ppem,
+                                           0x10000L,
+                                           metrics->y_ppem );
+      size->ttmetrics.y_ratio = 0x10000;
+    }
+
+    /* Compute root ascender, descender, test height, and max_advance */
+    metrics->ascender = ( FT_MulFix( face->root.ascender,
+                                     metrics->y_scale ) + 32 ) & -64;
+
+    metrics->descender = ( FT_MulFix( face->root.descender,
+                                      metrics->y_scale ) + 32 ) & -64;
+
+    metrics->height = ( FT_MulFix( face->root.height,
+                                   metrics->y_scale ) + 32 ) & -64;
+
+    metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
+                                        metrics->x_scale ) + 32 ) & -64;
+
+    /* Scale the cvt values to the new ppem.          */
+    /* We use by default the y ppem to scale the CVT. */
+
+    for ( i = 0; i < size->cvt_size; i++ )
+      size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
+
+    /* All twilight points are originally zero */
+    for ( j = 0; j < size->twilight.n_points; j++ )
+    {
+      size->twilight.org[j].x = 0;
+      size->twilight.org[j].y = 0;
+      size->twilight.cur[j].x = 0;
+      size->twilight.cur[j].y = 0;
+    }
+
+    /* clear storage area */
+    for ( i = 0; i < size->storage_size; i++ )
+      size->storage[i] = 0;
+
+    size->GS = tt_default_graphics_state;
+
+    /* get execution context and run prep program */
+    if ( size->debug )
+      exec = size->context;
+    else
+      exec = TT_New_Context( face );
+    /* debugging instances have their own context */
+
+    if ( !exec )
+      return TT_Err_Could_Not_Find_Context;
+
+    TT_Load_Context( exec, face, size );
+
+    TT_Set_CodeRange( exec,
+                      tt_coderange_cvt,
+                      face->cvt_program,
+                      face->cvt_program_size );
+
+    TT_Clear_CodeRange( exec, tt_coderange_glyph );
+
+    exec->instruction_trap = FALSE;
+
+    exec->top     = 0;
+    exec->callTop = 0;
+
+    if ( face->cvt_program_size > 0 )
+    {
+      error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
+      if ( error )
+        goto Fin;
+
+      if ( !size->debug )
+        error = face->interpreter( exec );
+    }
+    else
+      error = TT_Err_Ok;
+
+    size->GS = exec->GS;
+    /* save default graphics state */
+
+  Fin:
+    TT_Save_Context( exec, size );
+
+    if ( !size->debug )
+      TT_Done_Context( exec );
+    /* debugging instances keep their context */
+
+    if ( !error )
+      size->ttmetrics.valid = TRUE;
+
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Init_GlyphSlot                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType glyph slot initializer.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    slot :: The glyph record to build.                                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Init_GlyphSlot( TT_GlyphSlot  slot )
+  {
+    /* allocate the outline space */
+    FT_Face     face    = slot->face;
+    FT_Library  library = face->driver->library;
+
+
+    FT_TRACE4(( "TT.Init_GlyphSlot: Creating outline maxp = %d, maxc = %d\n",
+                face->max_points, face->max_contours ));
+
+    return FT_New_Outline( library,
+                           face->max_points + 2,
+                           face->max_contours,
+                           &slot->outline );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_GlyphSlot                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType glyph slot finalizer.                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    slot :: A handle to the glyph slot object.                         */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  TT_Done_GlyphSlot( TT_GlyphSlot  slot )
+  {
+    FT_Library  library = slot->face->driver->library;
+
+
+    FT_Done_Outline( library, &slot->outline );
+    return;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Init_Driver                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a given TrueType driver object.                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver :: A handle to the target driver object.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Init_Driver( TT_Driver  driver )
+  {
+    /* init extension registry if needed */
+#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
+    return TT_Init_Extensions( driver );
+#else
+    UNUSED( driver );
+
+    return TT_Err_Ok;
+#endif
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_Driver                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finalizes a given TrueType driver.                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver :: A handle to the target TrueType driver.                  */
+  /*                                                                       */
+  LOCAL_FUNC
+  void  TT_Done_Driver( TT_Driver  driver )
+  {
+    /* destroy extensions registry if needed */
+#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
+    TT_Done_Extensions( driver );
+#endif
+
+    /* destroy the execution context */
+    if ( driver->context )
+    {
+      TT_Destroy_Context( driver->context, driver->root.memory );
+      driver->context = NULL;
+    }
+  }
+
+
+/* END */
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
new file mode 100644
index 0000000..e4befb5
--- /dev/null
+++ b/src/truetype/ttobjs.h
@@ -0,0 +1,594 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttobjs.h                                                               */
+/*                                                                         */
+/*    Objects manager (specification).                                     */
+/*                                                                         */
+/*  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 TTOBJS_H
+#define TTOBJS_H
+
+
+#include <ftobjs.h>
+#include <tttypes.h>
+#include <ttconfig.h>
+#include <tterrors.h>
+
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Driver                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a TrueType driver object.                              */
+  /*                                                                       */
+  typedef struct TT_DriverRec_*  TT_Driver;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_Instance                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a TrueType size object.                                */
+  /*                                                                       */
+  typedef struct TT_SizeRec_*  TT_Size;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    TT_GlyphSlot                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a TrueType glyph slot object.                          */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This is a direct typedef of FT_GlyphSlot, as there is nothing      */
+  /*    specific about the TrueType glyph slot.                            */
+  /*                                                                       */
+  typedef FT_GlyphSlot  TT_GlyphSlot;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_GraphicsState                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType graphics state used during bytecode interpretation.   */
+  /*                                                                       */
+  typedef struct  TT_GraphicsState_
+  {
+    TT_UShort      rp0;
+    TT_UShort      rp1;
+    TT_UShort      rp2;
+
+    TT_UnitVector  dualVector;
+    TT_UnitVector  projVector;
+    TT_UnitVector  freeVector;
+
+    TT_Long        loop;
+    TT_F26Dot6     minimum_distance;
+    TT_Int         round_state;
+
+    TT_Bool        auto_flip;
+    TT_F26Dot6     control_value_cutin;
+    TT_F26Dot6     single_width_cutin;
+    TT_F26Dot6     single_width_value;
+    TT_Short       delta_base;
+    TT_Short       delta_shift;
+
+    TT_Byte        instruct_control;
+    TT_Bool        scan_control;
+    TT_Int         scan_type;
+
+    TT_UShort      gep0;
+    TT_UShort      gep1;
+    TT_UShort      gep2;
+
+  } TT_GraphicsState;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  EXECUTION SUBTABLES                                                  */
+  /*                                                                       */
+  /*  These sub-tables relate to instruction execution.                    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#define TT_MAX_CODE_RANGES  3
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* There can only be 3 active code ranges at once:                       */
+  /*   - the Font Program                                                  */
+  /*   - the CVT Program                                                   */
+  /*   - a glyph's instructions set                                        */
+  /*                                                                       */
+  typedef enum  TT_CodeRange_Tag_
+  {
+    tt_coderange_none = 0,
+    tt_coderange_font,
+    tt_coderange_cvt,
+    tt_coderange_glyph
+
+  } TT_CodeRange_Tag;
+
+
+  typedef struct  TT_CodeRange_
+  {
+    TT_Byte*  base;
+    TT_ULong  size;
+
+  } TT_CodeRange;
+
+  typedef TT_CodeRange  TT_CodeRangeTable[TT_MAX_CODE_RANGES];
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Defines a function/instruction definition record.                     */
+  /*                                                                       */
+  typedef struct  TT_DefRecord_
+  {
+    TT_Int   range;      /* in which code range is it located? */
+    TT_Long  start;      /* where does it start?               */
+    TT_UInt  opc;        /* function #, or instruction code    */
+    TT_Bool  active;     /* is it active?                      */
+
+  } TT_DefRecord, *TT_DefArray;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This type defining a set of glyph points will be used to represent    */
+  /* each zone (regular and twilight) during instructions decoding.        */
+  /*                                                                       */
+  typedef struct  TT_GlyphZone_
+  {
+    TT_UShort   n_points;   /* number of points in zone    */
+    TT_Short    n_contours; /* number of contours          */
+
+    TT_Vector*  org;        /* original point coordinates  */
+    TT_Vector*  cur;        /* current point coordinates   */
+
+    TT_Byte*    touch;      /* current touch flags         */
+    TT_UShort*  contours;   /* contour end points          */
+
+  } TT_GlyphZone;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Subglyph transformation record.                                       */
+  /*                                                                       */
+  typedef struct  TT_Transform_
+  {
+    TT_Fixed    xx, xy;     /* transformation matrix coefficients */
+    TT_Fixed    yx, yy;
+    TT_F26Dot6  ox, oy;     /* offsets        */
+
+  } TT_Transform;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Subglyph loading record.  Used to load composite components.          */
+  /*                                                                       */
+  typedef struct  TT_SubglyphRec_
+  {
+    TT_Long       index;        /* subglyph index; initialized with -1 */
+    TT_Bool       is_scaled;    /* is the subglyph scaled?             */
+    TT_Bool       is_hinted;    /* should it be hinted?                */
+    TT_Bool       preserve_pps; /* preserve phantom points?            */
+
+    TT_Long       file_offset;
+
+    TT_BBox       bbox;
+    TT_Pos        left_bearing;
+    TT_Pos        advance;
+
+    TT_GlyphZone  zone;
+
+    TT_Long       arg1;         /* first argument                      */
+    TT_Long       arg2;         /* second argument                     */
+
+    TT_UShort     element_flag; /* current load element flag           */
+
+    TT_Transform  transform;    /* transformation matrix               */
+
+    TT_Vector     pp1, pp2;     /* phantom points                      */
+
+  } TT_SubGlyphRec, *TT_SubGlyph_Stack;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* A note regarding non-squared pixels:                                  */
+  /*                                                                       */
+  /* (This text will probably go into some docs at some time, for now, it  */
+  /*  is kept here to explain some definitions in the TIns_Metrics         */
+  /*  record).                                                             */
+  /*                                                                       */
+  /* The CVT is a one-dimensional array containing values that control     */
+  /* certain important characteristics in a font, like the height of all   */
+  /* capitals, all lowercase letter, default spacing or stem width/height. */
+  /*                                                                       */
+  /* These values are found in FUnits in the font file, and must be scaled */
+  /* to pixel coordinates before being used by the CVT and glyph programs. */
+  /* Unfortunately, when using distinct x and y resolutions (or distinct x */
+  /* and y pointsizes), there are two possible scalings.                   */
+  /*                                                                       */
+  /* A first try was to implement a `lazy' scheme where all values were    */
+  /* scaled when first used.  However, while some values are always used   */
+  /* in the same direction, some others are used under many different      */
+  /* circumstances and orientations.                                       */
+  /*                                                                       */
+  /* I have found a simpler way to do the same, and it even seems to work  */
+  /* in most of the cases:                                                 */
+  /*                                                                       */
+  /* - All CVT values are scaled to the maximum ppem size.                 */
+  /*                                                                       */
+  /* - When performing a read or write in the CVT, a ratio factor is used  */
+  /*   to perform adequate scaling.  Example:                              */
+  /*                                                                       */
+  /*     x_ppem = 14                                                       */
+  /*     y_ppem = 10                                                       */
+  /*                                                                       */
+  /*   We choose ppem = x_ppem = 14 as the CVT scaling size.  All cvt      */
+  /*   entries are scaled to it.                                           */
+  /*                                                                       */
+  /*     x_ratio = 1.0                                                     */
+  /*     y_ratio = y_ppem/ppem (< 1.0)                                     */
+  /*                                                                       */
+  /*   We compute the current ratio like:                                  */
+  /*                                                                       */
+  /*   - If projVector is horizontal,                                      */
+  /*       ratio = x_ratio = 1.0                                           */
+  /*                                                                       */
+  /*   - if projVector is vertical,                                        */
+  /*       ratio = y_ratio                                                 */
+  /*                                                                       */
+  /*   - else,                                                             */
+  /*       ratio = sqrt( (proj.x * x_ratio) ^ 2 + (proj.y * y_ratio) ^ 2 ) */
+  /*                                                                       */
+  /*   Reading a cvt value returns                                         */
+  /*     ratio * cvt[index]                                                */
+  /*                                                                       */
+  /*   Writing a cvt value in pixels:                                      */
+  /*     cvt[index] / ratio                                                */
+  /*                                                                       */
+  /*   The current ppem is simply                                          */
+  /*     ratio * ppem                                                      */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Metrics used by the TrueType size and context objects.                */
+  /*                                                                       */
+  typedef struct  TT_Size_Metrics_
+  {
+    /* for non-square pixels */
+    TT_Long     x_ratio;
+    TT_Long     y_ratio;
+
+    TT_UShort   ppem;               /* maximum ppem size              */
+    TT_Long     ratio;              /* current ratio                  */
+    TT_Fixed    scale;
+
+    TT_F26Dot6  compensations[4];   /* device-specific compensations  */
+
+    TT_Bool     valid;
+
+    TT_Bool     rotated;            /* `is the glyph rotated?'-flag   */
+    TT_Bool     stretched;          /* `is the glyph stretched?'-flag */
+
+  } TT_Size_Metrics;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* FreeType execution context type.                                      */
+  /*                                                                       */
+  /* This is a forward declaration; the full specification is in the file  */
+  /* `ttinterp.h'.                                                         */
+  /*                                                                       */
+  typedef struct TT_ExecContextRec_*  TT_ExecContext;
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* TrueType size class.                                                */
+  /*                                                                     */
+  typedef struct  TT_SizeRec_
+  {
+    FT_SizeRec         root;
+
+    TT_Size_Metrics    ttmetrics;
+
+    TT_UInt            num_function_defs; /* number of function definitions */
+    TT_UInt            max_function_defs;
+    TT_DefArray        function_defs;     /* table of function definitions  */
+
+    TT_UInt            num_instruction_defs;  /* number of ins. definitions */
+    TT_UInt            max_instruction_defs;
+    TT_DefArray        instruction_defs;      /* table of ins. definitions  */
+
+    TT_UInt            max_func;
+    TT_UInt            max_ins;
+
+    TT_CodeRangeTable  codeRangeTable;
+
+    TT_GraphicsState   GS;
+
+    TT_ULong           cvt_size;      /* the scaled control value table */
+    TT_Long*           cvt;
+
+    TT_UShort          storage_size; /* The storage area is now part of */
+    TT_Long*           storage;      /* the instance                    */
+
+    TT_GlyphZone       twilight;     /* The instance's twilight zone    */
+
+    /* debugging variables */
+
+    /* When using the debugger, we must keep the */
+    /* execution context tied to the instance    */
+    /* object rather than asking it on demand.   */
+
+    TT_Bool            debug;
+    TT_ExecContext     context;
+
+  } TT_SizeRec;
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /* TrueType driver class.                                              */
+  /*                                                                     */
+  typedef struct  TT_DriverRec_
+  {
+    FT_DriverRec    root;
+    TT_ExecContext  context;  /* execution context */
+
+    void*           extension_component;
+
+  } TT_DriverRec;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_New_GlyphZone                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Allocates a new glyph zone.                                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory      :: A handle to the current memory object.              */
+  /*                                                                       */
+  /*    maxPoints   :: The capacity of glyph zone in points.               */
+  /*                                                                       */
+  /*    maxContours :: The capacity of glyph zone in contours.             */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    pts         :: A pointer to the target glyph zone record.          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+ LOCAL_DEF
+ TT_Error  TT_New_GlyphZone( FT_Memory      memory,
+                             TT_GlyphZone*  pts,
+                             TT_UShort      maxPoints,
+                             TT_Short       maxContours );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_GlyphZone                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Deallocates a glyph zone.                                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to the current memory object.                   */
+  /*                                                                       */
+  /*    pts    :: A pointer to the target glyph zone record.               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Done_GlyphZone( FT_Memory      memory,
+                               TT_GlyphZone*  pts );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Init_Face                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a given TrueType face object.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    resource   :: The source font resource.                            */
+  /*    face_index :: The index of the font face in the resource.          */
+  /*    face       :: The newly built face object.                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Init_Face( FT_Stream  stream,
+                          TT_Long    face_index,
+                          TT_Face    face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_Face                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finalizes a given face object.                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face :: The target face object to finalize.                        */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Done_Face( TT_Face  face );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Init_Size                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a new TrueType size object.                            */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size :: A handle to the size object.                               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Init_Size( TT_Size  size );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_Size                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType size object finalizer.                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size :: A handle to the target size object.                        */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Done_Size( TT_Size  size );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Reset_Size                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Resets a TrueType size when resolutions and character dimensions   */
+  /*    have been changed.                                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size :: A handle to the target size object.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Reset_Size( TT_Size  size );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Init_GlyphSlot                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType glyph slot initializer.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    glyph :: The glyph record to build.                                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Init_GlyphSlot( TT_GlyphSlot  slot );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_GlyphSlot                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    The TrueType glyph slot finalizer.                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    glyph :: A handle to the glyph slot object.                        */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Done_GlyphSlot( TT_GlyphSlot  slot );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Init_Driver                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initializes a given TrueType driver object.                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver :: A handle to the target driver object.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Init_Driver( TT_Driver  driver );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Done_Driver                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finalizes a given TrueType driver.                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    driver :: A handle to the target TrueType driver.                  */
+  /*                                                                       */
+  LOCAL_DEF
+  void  TT_Done_Driver( TT_Driver  driver );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif /* TTOBJS_H */
+
+
+/* END */
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
new file mode 100644
index 0000000..7b4a690
--- /dev/null
+++ b/src/truetype/ttpload.c
@@ -0,0 +1,260 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttpload.h                                                              */
+/*                                                                         */
+/*    TrueType glyph data/program tables loader (body).                    */
+/*                                                                         */
+/*  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 <ftdebug.h>
+#include <ftobjs.h>
+#include <ftstream.h>
+
+#include <ttpload.h>
+#include <tttags.h>
+#include <tterrors.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_ttload
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Locations                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the locations table.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Locations( TT_Face    face,
+                               FT_Stream  stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+    TT_Short   LongOffsets;
+    TT_ULong   table_len;
+
+    FT_TRACE2(( "Locations " ));
+    LongOffsets = face->header.Index_To_Loc_Format;
+
+    error = face->goto_table( face, TTAG_loca, stream, &table_len );
+    if (error)
+    {
+      error = TT_Err_Locations_Missing;
+      goto Exit;
+    }
+
+    if ( LongOffsets != 0 )
+    {
+      face->num_locations = (TT_UShort)(table_len >> 2);
+
+      FT_TRACE2(( "(32 bits offsets): %12d ", face->num_locations ));
+
+      if ( ALLOC_ARRAY( face->glyph_locations,
+                        face->num_locations,
+                        TT_Long ) )
+        goto Exit;
+
+      if ( ACCESS_Frame( face->num_locations * 4L ) )
+        goto Exit;
+
+      {
+        TT_Long*  loc   = face->glyph_locations;
+        TT_Long*  limit = loc + face->num_locations;
+
+        for ( ; loc < limit; loc++ )
+          *loc = GET_Long();
+      }
+
+      FORGET_Frame();
+    }
+    else
+    {
+      face->num_locations = (TT_UShort)(table_len >> 1);
+
+      FT_TRACE2(( "(16 bits offsets): %12d ",
+                   face->num_locations ));
+
+      if ( ALLOC_ARRAY( face->glyph_locations,
+                        face->num_locations,
+                        TT_Long ) )
+        goto Exit;
+
+      if ( ACCESS_Frame( face->num_locations * 2L ) )
+        goto Exit;
+      {
+        TT_Long*  loc   = face->glyph_locations;
+        TT_Long*  limit = loc + face->num_locations;
+
+        for ( ; loc < limit; loc++ )
+          *loc = (TT_Long)((TT_ULong)GET_UShort() * 2);
+      }
+      FORGET_Frame();
+    }
+
+    FT_TRACE2(( "loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_CVT                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the control value table into a face object.                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_CVT( TT_Face    face,
+                         FT_Stream  stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+    TT_ULong   table_len;
+
+    FT_TRACE2(( "CVT " ));
+
+    error = face->goto_table( face, TTAG_cvt, stream, &table_len );
+    if (error)
+    {
+      FT_TRACE2(( "is missing!\n" ));
+
+      face->cvt_size = 0;
+      face->cvt      = NULL;
+      error          = TT_Err_Ok;
+
+      goto Exit;
+    }
+
+    face->cvt_size = table_len / 2;
+
+    if ( ALLOC_ARRAY( face->cvt,
+                      face->cvt_size,
+                      TT_Short ) )
+      goto Exit;
+
+    if ( ACCESS_Frame( face->cvt_size * 2L ) )
+      goto Exit;
+
+    {
+      TT_Short*  cur   = face->cvt;
+      TT_Short*  limit = cur + face->cvt_size;
+
+      for ( ; cur <  limit; cur++ )
+        *cur = GET_Short();
+    }
+
+    FORGET_Frame();
+    FT_TRACE2(( "loaded\n" ));
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Progams                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the font program and the cvt program.                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  TT_Error  TT_Load_Programs( TT_Face    face,
+                              FT_Stream  stream )
+  {
+    TT_Error   error;
+    FT_Memory  memory = stream->memory;
+    TT_ULong   table_len;
+
+    FT_TRACE2(( "Font program " ));
+
+    error = TT_Err_Ok;
+
+    /* The font program is optional */
+    error = face->goto_table( face, TTAG_fpgm, stream, &table_len );
+    if (error)
+    {
+      face->font_program      = NULL;
+      face->font_program_size = 0;
+      FT_TRACE2(( "is missing!\n" ));
+    }
+    else
+    {
+      face->font_program_size = table_len;
+
+      if ( ALLOC( face->font_program,
+                  face->font_program_size ) ||
+
+           FILE_Read( (void*)face->font_program,
+                      face->font_program_size )   )
+        goto Exit;
+
+      FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
+    }
+
+    FT_TRACE2(( "Prep program " ));
+
+    error = face->goto_table( face, TTAG_prep, stream, &table_len );
+    if (error)
+    {
+      face->cvt_program      = NULL;
+      face->cvt_program_size = 0;
+
+      FT_TRACE2(( "is missing!\n" ));
+    }
+    else
+    {
+      face->cvt_program_size = table_len;
+
+      if ( ALLOC( face->cvt_program,
+                  face->cvt_program_size )           ||
+
+           FILE_Read( (void*)face->cvt_program,
+                      face->cvt_program_size ) )
+        return error;
+
+      FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
+    }
+
+  Exit:
+    return error;
+  }
+
+
+/* END */
diff --git a/src/truetype/ttpload.h b/src/truetype/ttpload.h
new file mode 100644
index 0000000..bb7c517
--- /dev/null
+++ b/src/truetype/ttpload.h
@@ -0,0 +1,92 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttpload.h                                                              */
+/*                                                                         */
+/*    TrueType glyph data/program tables loader (specification).           */
+/*                                                                         */
+/*  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 TTPLOAD_H
+#define TTPLOAD_H
+
+#include <tttypes.h>
+
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Locations                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the locations table.                                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: The input stream.                                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Locations( TT_Face    face,
+                               FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_CVT                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the control value table into a face object.                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_CVT( TT_Face    face,
+                         FT_Stream  stream );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Load_Progams                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the font program and the cvt program.                        */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face   :: A handle to the target face object.                      */
+  /*    stream :: A handle to the input stream.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    TrueType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_DEF
+  TT_Error  TT_Load_Programs( TT_Face    face,
+                              FT_Stream  stream );
+
+#endif /* TTPLOAD_H */
+
+
+/* END */
diff --git a/src/truetype/tttags.h b/src/truetype/tttags.h
new file mode 100644
index 0000000..73bbfc0
--- /dev/null
+++ b/src/truetype/tttags.h
@@ -0,0 +1,60 @@
+/***************************************************************************/
+/*                                                                         */
+/*  tttags.h                                                               */
+/*                                                                         */
+/*    Tags for TrueType tables (specification only).                       */
+/*                                                                         */
+/*  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 TTAGS_H
+#define TTAGS_H
+
+
+#include <freetype.h>   /* for MAKE_TT_TAG() */
+
+
+#define TTAG_cmap  FT_MAKE_TAG( 'c', 'm', 'a', 'p' )
+#define TTAG_cvt   FT_MAKE_TAG( 'c', 'v', 't', ' ' )
+#define TTAG_EBDT  FT_MAKE_TAG( 'E', 'B', 'D', 'T' )
+#define TTAG_EBLC  FT_MAKE_TAG( 'E', 'B', 'L', 'C' )
+#define TTAG_EBSC  FT_MAKE_TAG( 'E', 'B', 'S', 'C' )
+#define TTAG_fpgm  FT_MAKE_TAG( 'f', 'p', 'g', 'm' )
+#define TTAG_gasp  FT_MAKE_TAG( 'g', 'a', 's', 'p' )
+#define TTAG_glyf  FT_MAKE_TAG( 'g', 'l', 'y', 'f' )
+#define TTAG_GSUB  FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
+#define TTAG_hdmx  FT_MAKE_TAG( 'h', 'd', 'm', 'x' )
+#define TTAG_head  FT_MAKE_TAG( 'h', 'e', 'a', 'd' )
+#define TTAG_hhea  FT_MAKE_TAG( 'h', 'h', 'e', 'a' )
+#define TTAG_hmtx  FT_MAKE_TAG( 'h', 'm', 't', 'x' )
+#define TTAG_kern  FT_MAKE_TAG( 'k', 'e', 'r', 'n' )
+#define TTAG_loca  FT_MAKE_TAG( 'l', 'o', 'c', 'a' )
+#define TTAG_LTSH  FT_MAKE_TAG( 'L', 'T', 'S', 'H' )
+#define TTAG_maxp  FT_MAKE_TAG( 'm', 'a', 'x', 'p' )
+#define TTAG_name  FT_MAKE_TAG( 'n', 'a', 'm', 'e' )
+#define TTAG_OS2   FT_MAKE_TAG( 'O', 'S', '/', '2' )
+#define TTAG_OTTO  FT_MAKE_TAG( 'O', 'T', 'T', 'O' )
+#define TTAG_PCLT  FT_MAKE_TAG( 'P', 'C', 'L', 'T' )
+#define TTAG_post  FT_MAKE_TAG( 'p', 'o', 's', 't' )
+#define TTAG_prep  FT_MAKE_TAG( 'p', 'r', 'e', 'p' )
+#define TTAG_true  FT_MAKE_TAG( 't', 'r', 'u', 'e' )
+#define TTAG_ttc   FT_MAKE_TAG( 't', 't', 'c', ' ' )
+#define TTAG_ttcf  FT_MAKE_TAG( 't', 't', 'c', 'f' )
+#define TTAG_VDMX  FT_MAKE_TAG( 'V', 'D', 'M', 'X' )
+#define TTAG_vhea  FT_MAKE_TAG( 'v', 'h', 'e', 'a' )
+#define TTAG_vmtx  FT_MAKE_TAG( 'v', 'm', 't', 'x' )
+
+
+#endif /* TTAGS_H */
+
+
+/* END */
diff --git a/src/type1/rules.mk b/src/type1/rules.mk
new file mode 100644
index 0000000..adae99c
--- /dev/null
+++ b/src/type1/rules.mk
@@ -0,0 +1,167 @@
+#****************************************************************************
+#*                                                                          *
+#*  Type1 driver Makefile                                                   *
+#*                                                                          *
+#*  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.                                         *
+#*                                                                          *
+#****************************************************************************
+
+
+#****************************************************************************
+#*                                                                          *
+#*  IMPORTANT NOTE: This Makefile is intended for GNU Make!                 *
+#*                  If you provide Makefiles for other make utilities,      *
+#*                  please place them in `freetype/lib/arch/<system>'.      *
+#*                                                                          *
+#*                                                                          *
+#*  This file is to be included by the FreeType Makefile.lib, located in    *
+#*  the `freetype/lib' directory.  Here is the list of the variables that   *
+#*  must be defined to use it:                                              *
+#*                                                                          *
+#*                                                                          *
+#*     BASE_DIR:    The location of the base layer's directory.  This is    *
+#*                  usually `freetype/lib/base'.                            *
+#*                                                                          *
+#*     ARCH_DIR:    The location of the architecture-dependent directory.   *
+#*                  This is usually `freetype/lib/arch/<system>'.           *
+#*                                                                          *
+#*     DRIVERS_DIR: The location of the font driver sub-dirs, usually       *
+#*                  `freetype/lib/drivers'.                                 *
+#*                                                                          *
+#*     OBJ_DIR:     The location where the compiled object(s) file will be  *
+#*                  placed.                                                 *
+#*                                                                          *
+#*     BASE_H:      A list of pathnames to the base layer's header files on *
+#*                  which the driver depends.                               *
+#*                                                                          *
+#*     FT_CFLAGS:   A set of flags used for compilation of object files.    *
+#*                  This contains at least the include paths of the arch    *
+#*                  and base directories + optimization + warnings + ANSI   *
+#*                  compliance.                                             *
+#*                                                                          *
+#*     FT_IFLAG:    The flag used to specify an include path on the         *
+#*                  compiler command line.  For example, with GCC, this is  *
+#*                  `-I', while some other compilers use `/i=' or `-J',     *
+#*                  etc.                                                    *
+#*                                                                          *
+#*     FT_OBJ:      The suffix of an object file for the platform; can be   *
+#*                  `o', `obj', `coff', `tco', etc. depending on the        *
+#*                  platform.                                               *
+#*                                                                          *
+#*                                                                          *
+#*  It also updates the following variables defined and used in the main    *
+#*  Makefile:                                                               *
+#*                                                                          *
+#*     DRV_OBJ_S:            The list of driver object files in             *
+#*                           single-object mode.                            *
+#*                                                                          *
+#*     DRV_OBJ_M:            The list of driver object files in             *
+#*                           multiple-objects mode.                         *
+#*                                                                          *
+#*     FTINIT_DRIVER_PATHS:  The list of include paths used to compile the  *
+#*                           `ftinit' component which registers all font    *
+#*                            drivers in the FT_Init_FreeType() function.   *
+#*                                                                          *
+#*     FTINIT_DRIVER_H:      The list of header dependencies used to        *
+#*                           compile the `ftinit' component.                *
+#*                                                                          *
+#*     FTINIT_DRIVER_MACROS: The list of macros to be defined when          *
+#*                           compiling the `ftinit' component.              *
+#*                                                                          *
+#*  `Single-object compilation' means that each font driver is compiled     *
+#*  into a single object file.  This is useful to get rid of all            *
+#*  driver-specific entries.                                                *
+#*                                                                          *
+#****************************************************************************
+
+
+# Type1 driver directory
+#
+T1_DIR  := $(SRC_)type1
+T1_DIR_ := $(T1_DIR)$(SEP)
+
+
+# additional include flags used when compiling the driver
+#
+T1_INCLUDE := $(SHARED) $(T1_DIR)
+T1_COMPILE := $(FT_CC) $(T1_INCLUDE:%=$I%)
+
+
+# Type1 driver sources (i.e., C files)
+#
+T1_DRV_SRC := $(T1_DIR_)t1objs.c    \
+              $(T1_DIR_)t1load.c    \
+              $(T1_DIR_)t1parse.c   \
+              $(T1_DIR_)t1tokens.c  \
+              $(T1_DIR_)t1driver.c  \
+	      $(T1_DIR_)t1encode.c  \
+              $(T1_DIR_)t1hinter.c  \
+              $(T1_DIR_)t1gload.c
+
+
+# Type1 driver headers
+#
+T1_DRV_H := $(T1_DIR_)t1errors.h    \
+            $(T1_DIR_)t1config.h    \
+            $(T1SHARED_H)           \
+            $(T1_DRV_SRC:%.c=%.h)
+
+
+# driver object(s)
+#
+#   T1_DRV_OBJ_M is used during `debug' builds
+#   T1_DRV_OBJ_S is used during `release' builds
+#
+T1_DRV_OBJ_M := $(T1_DRV_SRC:$(T1_DIR_)%.c=$(OBJ_)%.$O) \
+                $(T1SHARED:$(T1SHARED_DIR_)%.c=$(OBJ_)%.$O)
+T1_DRV_OBJ_S := $(OBJ_)type1.$O
+
+
+
+# driver root source file(s)
+#
+T1_DRV_SRC_M := $(T1_DRV_SRC) $(T1SHARED_SRC)
+T1_DRV_SRC_S := $(T1_DIR_)type1.c
+
+
+# driver - single object
+#
+#  the driver is recompiled if any of the header or source files is changed
+#
+$(T1_DRV_OBJ_S): $(BASE_H) $(T1_DRV_H) $(T1_DRV_SRC) $(T1_DRV_SRC_S)
+	$(T1_COMPILE) $T$@ $(T1_DRV_SRC_S)
+
+
+
+# driver - multiple objects
+#
+#   All objects are recompiled if any of the header files is changed
+#
+$(OBJ_)t1%.$O: $(T1_DIR_)t1%.c $(BASE_H) $(T1_DRV_H)
+	$(T1_COMPILE) $T$@ $<
+
+$(OBJ_)t1%.$O: $(T1SHARED_DIR_)t1%.c $(BASE_H) $(T1SHARED_H)
+	$(T1_COMPILE) $T$@ $<
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(T1_DRV_OBJ_S)
+DRV_OBJS_M += $(T1_DRV_OBJ_M)
+
+
+# update 'ftinit' variables
+#
+FTINIT_DRIVER_PATHS  += $(T1_DIR) $(T1SHARED_DIR)
+FTINIT_DRIVER_H      += $(T1_DRV_H)
+FTINIT_DRIVER_MACROS += FT_SUPPORT_TYPE1
+
+
+# END
diff --git a/src/type1/t1config.h b/src/type1/t1config.h
new file mode 100644
index 0000000..a72b177
--- /dev/null
+++ b/src/type1/t1config.h
@@ -0,0 +1,45 @@
+/*******************************************************************
+ *
+ *  t1config.h
+ *
+ *    Type 1 driver configuration file
+ *
+ *  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 T1CONFIG_H
+#define T1CONFIG_H
+
+/* T1_MAX_STACK_DEPTH is the maximal depth of the token stack used */
+/* by the Type 1 parser (see t1load.c). A minimum of 16 is required */
+/*                                                                 */
+#define T1_MAX_STACK_DEPTH  16
+
+/* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */
+/* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is   */
+/* required                                                        */
+#define T1_MAX_DICT_DEPTH   5
+
+/* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */
+/* calls during glyph loading                                          */
+#define T1_MAX_SUBRS_CALLS   8
+
+
+/* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity */
+#define T1_MAX_CHARSTRINGS_OPERANDS  32
+
+
+/* Define T1_CONFIG_OPTION_DISABLE_HINTER if you want to generate  */
+/* a driver with no hinter. This can be useful to debug the parser */
+/*                                                                 */
+#undef  T1_CONFIG_OPTION_DISABLE_HINTER
+
+#endif /* T1CONFIG_H */
diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c
new file mode 100644
index 0000000..0c974be
--- /dev/null
+++ b/src/type1/t1driver.c
@@ -0,0 +1,279 @@
+/*******************************************************************
+ *
+ *  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 <ftdebug.h>
+#include <ftstream.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_t1driver
+
+  /******************************************************************/
+  /*                                                                */
+  /* <Function> Set_Char_Sizes                                      */
+  /*                                                                */
+  /* <Description>                                                  */
+  /*    A driver method used to reset a size's character sizes      */
+  /*    (horizontal and vertical) expressed in fractional points.   */
+  /*                                                                */
+  /* <Input>                                                        */
+  /*    size        :: handle to target size object                 */
+  /*    char_width  :: character width expressed in 26.6 points     */
+  /*    char_height :: character height expressed in 26.6 points    */
+  /*                                                                */
+  /* <Return>                                                       */
+  /*    FreeType error code. 0 means success                        */
+  /*                                                                */
+  static
+  T1_Error  Set_Char_Sizes( T1_Size      size,
+                            T1_F26Dot6   char_width,
+                            T1_F26Dot6   char_height,
+                            T1_UInt      horz_resolution,
+                            T1_UInt      vert_resolution )
+  {
+    FT_Size_Metrics*  metrics;
+    T1_Face           face;
+  
+    if (!size)
+      return T1_Err_Invalid_Size_Handle;
+    
+    if ( char_width  < 1*64 ) char_width = 1*64;
+    if ( char_height < 1*64 ) char_height = 1*64;
+
+    metrics = &size->root.metrics;
+    face    = (T1_Face)size->root.face;
+    
+    metrics->x_ppem = ( char_width  * horz_resolution + 36 )/72;
+    metrics->y_ppem = ( char_height * vert_resolution + 36 )/72;
+    
+    metrics->x_ppem = ( metrics->x_ppem + 32 ) & -64;
+    metrics->y_ppem = ( metrics->y_ppem + 32 ) & -64;
+    
+    metrics->x_scale = FT_MulDiv( metrics->x_ppem, 0x10000,
+                                  face->root.units_per_EM );
+    
+    metrics->y_scale = FT_MulDiv( metrics->y_ppem, 0x10000,
+                                  face->root.units_per_EM );
+
+    metrics->x_ppem >>= 6;
+    metrics->y_ppem >>= 6;
+    
+    size->valid = FALSE;
+
+    return T1_Reset_Size( size );
+  }
+
+
+  /******************************************************************/
+  /*                                                                */
+  /* <Function> Set_Pixel_Sizes                                     */
+  /*                                                                */
+  /* <Description>                                                  */
+  /*    A driver method used to reset a size's character sizes      */
+  /*    (horizontal and vertical) expressed in integer pixels.      */
+  /*                                                                */
+  /* <Input>                                                        */
+  /*    size         :: handle to target size object                */
+  /*                                                                */
+  /*    pixel_width  :: character width expressed in 26.6 points    */
+  /*                                                                */
+  /*    pixel_height :: character height expressed in 26.6 points   */
+  /*                                                                */
+  /*    char_size    :: the corresponding character size in points  */
+  /*                    This value is only sent to the TrueType     */
+  /*                    bytecode interpreter, even though 99% of    */
+  /*                    glyph programs will simply ignore it. A     */
+  /*                    safe value there is the maximum of the      */
+  /*                    pixel width and height (multiplied by       */
+  /*                    64 to make it a 26.6 fixed float !)         */
+  /* <Return>                                                       */
+  /*    FreeType error code. 0 means success                        */
+  /*                                                                */
+  static
+  T1_Error  Set_Pixel_Sizes( T1_Size     size,
+                             T1_Int      pixel_width,
+                             T1_Int      pixel_height )
+  {
+    FT_Size_Metrics*   metrics;
+    T1_Face            face;
+  
+    if (!size)
+      return T1_Err_Invalid_Size_Handle;
+    
+    if ( pixel_width  < 1 ) pixel_width = 1;
+    if ( pixel_height < 1 ) pixel_height = 1;
+  
+    metrics = &size->root.metrics;
+    face    = (T1_Face)size->root.face;
+  
+    metrics->x_ppem    = pixel_width;
+    metrics->y_ppem    = pixel_height;
+  
+    metrics->x_scale = FT_MulDiv( metrics->x_ppem * 64,
+                                  0x10000, face->root.units_per_EM );
+  
+    metrics->y_scale = FT_MulDiv( metrics->y_ppem * 64,
+                                  0x10000, face->root.units_per_EM );
+  
+    size->valid = 0;
+  
+    return T1_Reset_Size(size);
+  }
+
+
+  /******************************************************************/
+  /*                                                                */
+  /* <Struct> FT_DriverInterface                                    */
+  /*                                                                */
+  /* <Description>                                                  */
+  /*    A structure used to hold a font driver's basic interface    */
+  /*    used by the high-level parts of FreeType (or other apps)    */
+  /*                                                                */
+  /*    Most scalable drivers provide a specialized interface to    */
+  /*    access format-specific features. It can be retrieved with   */
+  /*    a call to the "get_format_interface", and should be defined */
+  /*    in each font driver header (e.g. ttdriver.h, t1driver.h,..) */
+  /*                                                                */
+  /*    All fields are function pointers ..                         */
+  /*                                                                */
+  /*                                                                */
+  /* <Fields>                                                       */
+  /*                                                                */
+  /*    new_engine ::                                               */
+  /*        used to create and initialise a new driver object       */
+  /*                                                                */
+  /*    done_engine ::                                              */
+  /*        used to finalise and destroy a given driver object      */
+  /*                                                                */
+  /*    get_format_interface ::                                     */
+  /*        return a typeless pointer to the format-specific        */
+  /*        driver interface.                                       */
+  /*                                                                */
+  /*    new_face ::                                                 */
+  /*        create a new face object from a resource                */
+  /*                                                                */
+  /*    done_face ::                                                */
+  /*        discards a face object, as well as all child objects    */
+  /*        ( sizes, charmaps, glyph slots )                        */
+  /*                                                                */
+  /*    get_face_properties ::                                      */
+  /*        return generic face properties                          */
+  /*                                                                */
+  /*    get_kerning ::                                              */
+  /*        return the kerning vector corresponding to a pair       */
+  /*        of glyphs, expressed in unscaled font units.            */
+  /*                                                                */
+  /*    new_size ::                                                 */
+  /*        create and initialise a new scalable size object.       */
+  /*                                                                */
+  /*    new_fixed_size ::                                           */
+  /*        create and initialise a new fixed-size object.          */
+  /*                                                                */
+  /*    done_size ::                                                */
+  /*        finalize a given face size object.                      */
+  /*                                                                */
+  /*    set_size_resolutions ::                                     */
+  /*        reset a scalable size object's output resolutions       */
+  /*                                                                */
+  /*    set_size_char_sizes ::                                      */
+  /*        reset a scalable size object's character size           */
+  /*                                                                */
+  /*    set_pixel_sizes ::                                          */
+  /*        reset a face size object's pixel dimensions. Applies    */
+  /*        to both scalable and fixed faces.                       */
+  /*                                                                */
+  /*    new_glyph_slot ::                                           */
+  /*        create and initialise a new glyph slot                  */
+  /*                                                                */
+  /*    done_glyph_slot ::                                          */
+  /*        discard a given glyph slot                              */
+  /*                                                                */
+  /*    load_glyph ::                                               */
+  /*        load a given glyph into a given slot                    */
+  /*                                                                */
+  /*    get_glyph_metrics ::                                        */
+  /*        return a loaded glyph's metrics.                        */
+  /*                                                                */
+
+  EXPORT_FUNC
+  const  FT_DriverInterface  t1_driver_interface =
+  {
+    sizeof( FT_DriverRec ),
+    sizeof( T1_FaceRec ),
+    sizeof( T1_SizeRec ),
+    sizeof( T1_GlyphSlotRec ),
+    
+    "type1",
+    1,
+    2,
+
+    0,   /* format interface */
+
+    (FTDriver_initDriver)           T1_Init_Driver,
+    (FTDriver_doneDriver)           T1_Done_Driver,
+    (FTDriver_getInterface)         0,
+
+    (FTDriver_initFace)             T1_Init_Face,
+    (FTDriver_doneFace)             T1_Done_Face,
+    (FTDriver_getKerning)           0,
+
+    (FTDriver_initSize)             T1_Init_Size,
+    (FTDriver_doneSize)             T1_Done_Size,
+    (FTDriver_setCharSizes)         Set_Char_Sizes,
+    (FTDriver_setPixelSizes)        Set_Pixel_Sizes,
+
+    (FTDriver_initGlyphSlot)        T1_Init_GlyphSlot,
+    (FTDriver_doneGlyphSlot)        T1_Done_GlyphSlot,
+    (FTDriver_loadGlyph)            T1_Load_Glyph,
+
+    (FTDriver_getCharIndex)         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
+  FT_DriverInterface*  getDriverInterface( void )
+  {
+    return &t1_driver_interface;
+  }
+  
+#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
+
+
diff --git a/src/type1/t1driver.h b/src/type1/t1driver.h
new file mode 100644
index 0000000..61a16b0
--- /dev/null
+++ b/src/type1/t1driver.h
@@ -0,0 +1,77 @@
+/*******************************************************************
+ *
+ *  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 <t1objs.h>
+#include <t1errors.h>
+
+  EXPORT_DEF
+  const  FT_DriverInterface  t1_driver_interface;
+
+
+/*************************************************************************
+ *
+ *  Here is a template of the code that should appear in each
+ *  font driver's _interface_ file (the one included by "ftinit.c").
+ *
+ *  It is used to build, at compile time, a simple linked list of
+ *  the interfaces of the drivers which have been #included in 
+ *  "ftinit.c". See the source code of the latter file for details
+ *
+ *  (Note that this is only required when you want your driver included
+ *   in the set of default drivers loaded by FT_Init_FreeType. Other
+ *   drivers can still be added manually at runtime with FT_Add_Driver.
+ *
+ * {
+ *   #ifdef FTINIT_DRIVER_CHAIN
+ *
+ *   static
+ *   const FT_DriverChain  ftinit_<FORMAT>_driver_chain =
+ *   {
+ *     FT_INIT_LAST_DRIVER_CHAIN,
+ *     &<FORMAT>_driver_interface
+ *   };
+ * 
+ *   #undef  FT_INIT_LAST_DRIVER_CHAIN
+ *   #define FT_INIT_LAST_DRIVER_CHAIN   &ftinit_<FORMAT>_driver_chain
+ *
+ *   #endif 
+ * }
+ *
+ *  replace <FORMAT> with your driver's prefix
+ *
+ *************************************************************************/
+
+#ifdef FTINIT_DRIVER_CHAIN
+
+  static
+  const FT_DriverChain  ftinit_t1_driver_chain =
+  {
+    FT_INIT_LAST_DRIVER_CHAIN,
+    &t1_driver_interface
+  };
+
+#undef  FT_INIT_LAST_DRIVER_CHAIN
+#define FT_INIT_LAST_DRIVER_CHAIN   &ftinit_t1_driver_chain
+
+#endif /* FTINIT_DRIVER_CHAIN */ 
+
+
+#endif /* T1DRIVER_H */
+
diff --git a/src/type1/t1encode.c b/src/type1/t1encode.c
new file mode 100644
index 0000000..9c91027
--- /dev/null
+++ b/src/type1/t1encode.c
@@ -0,0 +1,332 @@
+/***************************************************************************/
+/*                                                                         */
+/*  t1encode.c                                                             */
+/*                                                                         */
+/*    Type 1 standard encoding tables definitions (body).                  */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/*                                                                         */
+/*  This file is included by both the Type1 and Type2 driver.              */
+/*  It should never be compiled directly.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+#include <ftobjs.h>
+#include <t1types.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_standard_strings:                                                 */
+  /*                                                                       */
+  /*     This array contains the Adobe Standard Glyph Names ordered by     */
+  /*     SID.  It was taken from the CFF specification.                    */
+  /*                                                                       */
+  LOCAL_FUNC
+  const T1_String*  t1_standard_strings[] =
+  {
+  /*   0 */
+    ".notdef", "space", "exclam", "quotedbl", "numbersign",
+    "dollar", "percent", "ampersand", "quoteright", "parenleft",
+  /*  10 */
+    "parenright", "asterisk", "plus", "comma", "hyphen",
+    "period", "slash", "zero", "one", "two",
+  /*  20 */
+    "three", "four", "five", "six", "seven",
+    "height", "nine", "colon", "semicolon", "less",
+  /*  30 */
+    "equal", "greater", "question", "at", "A",
+    "B", "C", "D", "E", "F",
+  /*  40 */
+    "G", "H", "I", "J", "K",
+    "L", "M", "N", "O", "P",
+  /*  50 */
+    "Q", "R", "S", "T", "U",
+    "V", "W", "X", "Y", "Z",
+  /*  60 */
+    "bracketleft", "backslash", "bracketright", "asciicircum", "underscore",
+    "quoteleft", "a", "b", "c", "d",
+  /*  70 */
+    "e", "f", "g", "h", "i",
+    "j", "k", "l", "m", "n",
+  /*  80 */
+    "o", "p", "q", "r", "s",
+    "t", "u", "v", "w", "x",
+  /*  90 */
+    "y", "z", "braceleft", "bar", "braceright",
+    "asciitilde", "exclamdown", "cent", "sterling", "fraction",
+  /* 100 */
+    "yen", "florin", "section", "currency", "quotesingle",
+    "quotedblleft", "quillemotleft", "guilsinglleft", "guilsinglright", "fi",
+  /* 110 */
+    "fl", "endash", "dagger", "daggerdbl", "periodcenter",
+    "paragraph", "bullet", "quotesinglbase", "quotedblbase", "quotedblright",
+  /* 120 */
+    "quillemotright", "ellipsis", "perthousand", "questiondown", "grave",
+    "acute", "circumflex", "tilde", "macron", "breve",
+  /* 130 */
+    "dotaccent", "dieresis", "ring", "cedilla", "hungarumlaut",
+    "ogonek", "caron", "emdash", "AE", "ordfeminine",
+  /* 140 */
+    "Lslash", "Oslash", "OE", "ordmasculine", "ae",
+   "dotlessi", "Islash", "oslash", "oe", "germandbls",
+  /* 150 */
+    "onesuperior", "logicalnot", "mu", "trademark", "Eth",
+    "onehalf", "plusminus", "Thorn", "onequarter", "divide",
+  /* 160 */
+    "brokenbar", "degree", "thorn", "threequarters", "twosuperior",
+    "regitered", "minus", "eth", "multiply", "threesuperior",
+  /* 170 */
+    "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
+    "Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex",
+  /* 180 */
+    "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis",
+    "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis",
+  /* 190 */
+    "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex",
+    "Udieresis", "Ugrave", "Yacute", "Ydieresis", "Zcaron",
+  /* 200 */
+    "aacute", "acircumflex", "adieresis", "agrave", "aring",
+    "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis",
+  /* 210 */
+    "egrave", "iacute", "icircumflex", "idieresis", "igrave",
+    "ntilde", "oacute", "ocircumflex", "odieresis", "ograve",
+  /* 220 */
+    "otilde", "scaron", "uacute", "ucircumflex", "udieresis",
+    "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall",
+  /* 230 */
+    "Hungarumlautsmall", "dollaroldstyle", "dollarsuperior", "ampersandsmall",
+      "Acutesmall",
+    "parenleftsuperior", "parenrightsuperior", "twodotenleader",
+      "onedotenleader", "zerooldstyle",
+  /* 240 */
+    "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle",
+      "fiveoldstyle",
+    "sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle",
+      "commasuperior",
+  /* 250 */
+    "threequartersemdash", "periodsuperior", "questionsmall", "asuperior",
+      "bsuperior",
+    "centsuperior", "dsuperior", "esuperior", "isuperior", "lsuperior",
+  /* 260 */
+    "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior",
+    "tsuperior", "ff", "ffi", "ffl", "parenleftinferior",
+  /* 270 */
+    "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall",
+      "Asmall",
+    "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
+  /* 280 */
+    "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall",
+    "Lsmall", "Msmall", "Nsmall", "Osmall", "Psmall",
+  /* 290 */
+    "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall",
+    "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall",
+  /* 300 */
+    "colonmonetary", "onefitted", "rupiah", "Tildesmall", "exclamdownsmall",
+    "centoldstyle", "Lslashsmall", "Scaronsmall", "Zcaronsmall",
+      "Dieresissmall",
+  /* 310 */
+    "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
+    "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall",
+      "questiondownsmall",
+  /* 320 */
+    "oneeighth", "threeeighths", "fiveeighths", "seveneighths", "onethird",
+    "twothirds", "zerosuperior", "foursuperior", "fivesuperior",
+      "sixsuperior",
+  /* 330 */
+    "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior",
+      "oneinferior",
+    "twoinferior", "threeinferior", "fourinferior", "fiveinferior",
+      "sixinferior",
+  /* 340 */
+    "seveninferior", "eightinferior", "nineinferior", "centinferior",
+      "dollarinferior",
+    "periodinferior", "commainferior", "Agravesmall", "Aacutesmall",
+      "Acircumflexsmall",
+  /* 350 */
+    "Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall",
+    "Egravesmall", "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
+      "Igravesmall",
+  /* 360 */
+    "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall",
+      "Ntildesmall",
+    "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
+      "Odieresissmall",
+  /* 370 */
+    "OEsmall", "Oslashsmall", "Ugravesmall", "Uacautesmall",
+      "Ucircumflexsmall",
+    "Udieresissmall", "Yacutesmall", "Thornsmall", "Ydieresissmall",
+      "001.000",
+  /* 380 */
+    "001.001", "001.002", "001.003", "Black", "Bold",
+    "Book", "Light", "Medium", "Regular", "Roman",
+  /* 390 */
+    "Semibold"
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_standard_encoding:                                                */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe StandardEncoding.  The    */
+  /*     table values are the SID of the standard glyphs; the table index  */
+  /*     is the character code for the encoding.                           */
+  /*                                                                       */
+  /*     Example:                                                          */
+  /*                                                                       */
+  /*       t1_standard_encoding[33] == 2                                   */
+  /*                                                                       */
+  /*     which means that the glyph name for character code 32 is          */
+  /*                                                                       */
+  /*       t1_standard_strings[2] == "exclam"                              */
+  /*                                                                       */
+  /*     (this correspond to the exclamation mark `!').                    */
+  /*                                                                       */
+  LOCAL_FUNC
+  T1_Short  t1_standard_encoding[256] =
+  {
+  /*   0 */ 
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   1,   2,   3,   4,   5,   6,   7,   8,
+      9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
+  /*  50 */
+     19,  20,  21,  22,  23,  24,  25,  26,  27,  28,
+     29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
+     39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
+     49,  50,  51,  52,  53,  54,  55,  56,  57,  58,
+     59,  60,  61,  62,  63,  64,  65,  66,  67,  68,
+  /* 100 */
+     69,  70,  71,  72,  73,  74,  75,  76,  77,  78,
+     79,  80,  81,  82,  83,  84,  85,  86,  87,  88,
+     89,  90,  91,  92,  93,  94,  95,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  /* 150 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,  96,  97,  98,  99, 100, 101, 102, 103, 104,
+    105, 106, 107, 108, 109, 110,   0, 111, 112, 113,
+    114,   0, 115, 116, 117, 118, 119, 120, 121, 122,
+      0, 123,   0, 124, 125, 126, 127, 128, 129, 130,
+  /* 200 */
+    131,   0, 132, 133,   0, 134, 135, 136, 137,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0, 138,   0, 139,   0,   0,
+      0,   0, 140, 141, 142, 143,   0,   0,   0,   0,
+      0, 144,   0,   0,   0, 145,   0,   0, 146, 147,
+  /* 250 */
+    148, 149,   0,   0,   0,   0
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_expert_encoding:                                                  */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe ExpertEncoding.  The      */
+  /*     table values are the SID of the standard glyphs; the table index  */
+  /*     is the character code for the encoding.                           */
+  /*                                                                       */
+  /*     Example:                                                          */
+  /*                                                                       */
+  /*       t1_expert_encoding[33] == 229                                   */
+  /*                                                                       */
+  /*     which means that the glyph name for character code 32 is          */
+  /*                                                                       */
+  /*       t1_standard_strings[229] == "exclamsmall"                       */
+  /*                                                                       */
+  LOCAL_FUNC
+  T1_Short  t1_expert_encoding[256] =
+  {
+  /*   0 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   1, 229, 230,   0, 231, 232, 233, 234,
+    235, 236, 237, 238,  13,  14,  15,  99, 239, 240,
+  /*  50 */
+    241, 242, 243, 244, 245, 246, 247, 248,  27,  28,
+    249, 250, 251, 252,   0, 253, 254, 255, 256, 257,
+      0,   0,   0, 258,   0,   0, 259, 260, 261, 262,
+      0,   0, 263, 264, 265,   0, 266, 109, 110, 267,
+    268, 269,   0, 270, 271, 272, 273, 274, 275, 276,
+  /* 100 */
+    277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
+    287, 288, 289, 290, 291, 292, 293, 294, 295, 296,
+    297, 298, 299, 300, 301, 302, 303,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  /* 150 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0, 304, 305, 306,   0,   0, 307, 308, 309, 310,
+    311,   0, 312,   0,   0, 312,   0,   0, 314, 315,
+      0,   0, 316, 317, 318,   0,   0,   0, 158, 155,
+    163, 319, 320, 321, 322, 323, 324, 325,   0,   0,
+  /* 200 */
+    326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+    333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+    343, 344, 345, 346, 347, 348, 349, 350, 351, 352,
+    353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
+    363, 364, 365, 366, 367, 368, 369, 370, 371, 372,
+  /* 250 */
+    373, 374, 375, 376, 377, 378
+  };
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_expert_subset_encoding:                                           */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe ExpertEncoding subset     */
+  /*     defined in the CFF specification.  It will probably evolve into   */
+  /*     another form sooner or later, as we deal with charsets            */
+  /*     differently than with encodings.                                  */
+  /*                                                                       */
+  LOCAL_FUNC
+  FT_Short  t1_expert_subset_encoding[256] =
+  {
+  /*   0 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   1,   0,   0,   0, 231, 232,   0,   0,
+    235, 236, 237, 238,  13,  14,  15,  99, 239, 240,
+  /*  50 */
+    241, 242, 243, 244, 245, 246, 247, 248,  27,  28,
+    249, 250, 251, 252,   0, 253, 254, 255, 256, 257,
+      0,   0,   0, 258,   0,   0, 259, 260, 261, 262,
+      0,   0, 263, 264, 265,   0, 266, 109, 110, 267,
+    268, 269,   0, 270,   0, 272,   0,   0,   0,   0,
+  /* 100 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0, 300, 301, 302, 303,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  /* 150 */
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0, 304, 305,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0, 314, 315,
+      0,   0,   0,   0,   0,   0,   0,   0, 158, 155,
+    163,   0, 320, 321, 322, 323, 324, 325,   0,   0,
+  /* 200 */
+    326, 150, 164, 169, 327, 328, 329, 330, 331, 332,
+    333, 334, 335, 336, 337, 338, 339, 340, 341, 342,
+    343, 344, 345, 346,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  /* 250 */
+      0,   0,   0,   0,   0,   0
+  };
+
+
+/* END */
diff --git a/src/type1/t1encode.h b/src/type1/t1encode.h
new file mode 100644
index 0000000..4a55acd
--- /dev/null
+++ b/src/type1/t1encode.h
@@ -0,0 +1,98 @@
+/***************************************************************************/
+/*                                                                         */
+/*  t1encode.h                                                             */
+/*                                                                         */
+/*    Type 1 standard encoding tables definitions (specification).         */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/*                                                                         */
+/*  This file is included by both the Type1 and Type2 driver.              */
+/*  It should never be compiled directly.                                  */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef T1ENCODE_H
+#define T1ENCODE_H
+
+#include <t1types.h>
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_standard_strings:                                                 */
+  /*                                                                       */
+  /*     This array contains the Adobe Standard Glyph Names ordered by     */
+  /*     SID.  It was taken from the CFF specification.                    */
+  /*                                                                       */
+  LOCAL_DEF
+  const T1_String*  t1_standard_strings[];
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_standard_encoding:                                                */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe StandardEncoding.  The    */
+  /*     table values are the SID of the standard glyphs; the table index  */
+  /*     is the character code for the encoding.                           */
+  /*                                                                       */
+  /*     Example:                                                          */
+  /*                                                                       */
+  /*       t1_standard_encoding[33] == 2                                   */
+  /*                                                                       */
+  /*     which means that the glyph name for character code 32 is          */
+  /*                                                                       */
+  /*       t1_standard_strings[2] == "exclam"                              */
+  /*                                                                       */
+  /*     (this correspond to the exclamation mark `!').                    */
+  /*                                                                       */
+  LOCAL_DEF
+  T1_Short  t1_standard_encoding[256];
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_expert_encoding:                                                  */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe ExpertEncoding.  The      */
+  /*     table values are the SID of the standard glyphs; the table index  */
+  /*     is the character code for the encoding.                           */
+  /*                                                                       */
+  /*     Example:                                                          */
+  /*                                                                       */
+  /*       t1_expert_encoding[33] == 229                                   */
+  /*                                                                       */
+  /*     which means that the glyph name for character code 32 is          */
+  /*                                                                       */
+  /*       t1_standard_strings[229] == "exclamsmall"                       */
+  /*                                                                       */
+  LOCAL_DEF
+  T1_Short  t1_expert_encoding[256];
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  t1_expert_subset_encoding:                                           */
+  /*                                                                       */
+  /*     A simple table used to encode the Adobe ExpertEncoding subset     */
+  /*     defined in the CFF specification.  It will probably evolve into   */
+  /*     another form sooner or later, as we deal with charsets            */
+  /*     differently than with encodings.                                  */
+  /*                                                                       */
+  LOCAL_DEF
+  T1_Short  t1_expert_subset_encoding[256];
+
+
+#endif /* T1ENCODE_H */
+
+
+/* END */
diff --git a/src/type1/t1errors.h b/src/type1/t1errors.h
new file mode 100644
index 0000000..01f5e4a
--- /dev/null
+++ b/src/type1/t1errors.h
@@ -0,0 +1,77 @@
+/*******************************************************************
+ *
+ *  t1errors.h
+ *
+ *    Type1 Error ID definitions
+ *
+ *  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 FREETYPE_H
+#error "Don't include this file! Use t1driver.h instead."
+#endif
+
+#ifndef T1ERRORS_H
+#define T1ERRORS_H
+
+  /************************ error codes declaration **************/
+
+  /* The error codes are grouped in 'classes' used to indicate the */
+  /* 'level' at which the error happened.                          */
+  /* The class is given by an error code's high byte.              */
+
+
+/* ------------- Success is always 0 -------- */
+
+#define  T1_Err_Ok                       FT_Err_Ok
+
+/* ----------- high level API errors -------- */
+  
+#define  T1_Err_Invalid_File_Format      FT_Err_Invalid_File_Format
+#define  T1_Err_Invalid_Argument         FT_Err_Invalid_Argument
+#define  T1_Err_Invalid_Driver_Handle    FT_Err_Invalid_Driver_Handle
+#define  T1_Err_Invalid_Face_Handle      FT_Err_Invalid_Face_Handle
+#define  T1_Err_Invalid_Size_Handle      FT_Err_Invalid_Size_Handle
+#define  T1_Err_Invalid_Glyph_Handle     FT_Err_Invalid_Slot_Handle
+#define  T1_Err_Invalid_CharMap_Handle   FT_Err_Invalid_CharMap_Handle
+#define  T1_Err_Invalid_Glyph_Index      FT_Err_Invalid_Glyph_Index
+
+#define  T1_Err_Unimplemented_Feature    FT_Err_Unimplemented_Feature
+#define  T1_Err_Unavailable_Outline      FT_Err_Unavailable_Outline
+#define  T1_Err_Unavailable_Bitmap       FT_Err_Unavailable_Bitmap
+#define  T1_Err_Unavailable_Pixmap       FT_Err_Unavailable_Pixmap
+#define  T1_Err_File_Is_Not_Collection   FT_Err_File_Is_Not_Collection
+
+#define  T1_Err_Invalid_Engine           FT_Err_Invalid_Driver_Handle
+
+/* ------------- internal errors ------------ */
+  
+#define  T1_Err_Out_Of_Memory            FT_Err_Out_Of_Memory
+#define  T1_Err_Unlisted_Object          FT_Err_Unlisted_Object
+
+/* ------------ general glyph outline errors ------ */
+
+#define  T1_Err_Too_Many_Points          FT_Err_Too_Many_Points
+#define  T1_Err_Too_Many_Contours        FT_Err_Too_Many_Contours
+#define  T1_Err_Too_Many_Hints           FT_Err_Too_Many_Hints
+#define  T1_Err_Invalid_Composite        FT_Err_Invalid_Composite
+#define  T1_Err_Too_Many_Edges           FT_Err_Too_Many_Edges
+#define  T1_Err_Too_Many_Strokes         FT_Err_Too_Many_Strokes
+
+
+#define  T1_Err_Syntax_Error             FT_Err_Invalid_File_Format
+#define  T1_Err_Stack_Underflow          FT_Err_Invalid_File_Format
+#define  T1_Err_Stack_Overflow           FT_Err_Invalid_File_Format
+
+#endif /* TDERRORS_H */
+
+
+/* END */
diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c
new file mode 100644
index 0000000..27fbfdc
--- /dev/null
+++ b/src/type1/t1gload.c
@@ -0,0 +1,1579 @@
+/*******************************************************************
+ *
+ *  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 <ftdebug.h>
+#include <t1encode.h>
+#include <ftstream.h>
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+#include <t1hinter.h>
+#endif
+
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********           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
+ *    funcs   :: glyph builder functions (or "methods").
+ *
+ *********************************************************************/
+
+  EXPORT_FUNC
+  void  T1_Init_Builder( T1_Builder*             builder,
+                         T1_Face                 face,
+                         T1_Size                 size,
+                         T1_GlyphSlot            glyph,
+                         const T1_Builder_Funcs* funcs )
+  {
+    builder->funcs       = *funcs;
+    builder->path_begun  = 0;
+    builder->load_points = 1;
+
+    builder->face   = face;
+    builder->size   = size;
+    builder->glyph  = glyph;
+    builder->memory = face->root.memory;
+
+    if (glyph)
+    {
+      builder->base         = glyph->root.outline;
+      builder->max_points   = glyph->max_points;
+      builder->max_contours = glyph->max_contours;
+    }
+
+    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;
+
+    builder->base.n_points   = 0;
+    builder->base.n_contours = 0;
+    builder->current         = builder->base;
+
+    builder->pass       = 0;
+    builder->hint_point = 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
+ *
+ *********************************************************************/
+
+  EXPORT_FUNC
+  void T1_Done_Builder( T1_Builder*  builder )
+  {
+    T1_GlyphSlot  glyph = builder->glyph;
+
+    if (glyph)
+    {
+      glyph->root.outline = builder->base;
+      glyph->max_points   = builder->max_points;
+      glyph->max_contours = builder->max_contours;
+    }
+  }
+
+
+
+/*********************************************************************
+ *
+ * <Function>
+ *    T1_Init_Decoder
+ *
+ * <Description>
+ *    Initialise a given Type 1 decoder for parsing
+ *
+ * <Input>
+ *    decoder :: Type 1 decoder to initialise
+ *    funcs   :: hinter functions interface
+ *
+ *********************************************************************/
+
+  EXPORT_FUNC
+  void  T1_Init_Decoder( T1_Decoder*             decoder,
+                         const T1_Hinter_Funcs*  funcs )
+  {
+    decoder->hinter = *funcs;    /* copy hinter interface */
+    decoder->top    = 0;
+    decoder->zone   = 0;
+
+    decoder->flex_state       = 0;
+    decoder->num_flex_vectors = 0;
+
+    /* Clear loader */
+    MEM_Set( &decoder->builder, 0, sizeof(decoder->builder) );
+  }
+
+
+/*********************************************************************
+ *
+ * <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
+  T1_Int    lookup_glyph_by_stdcharcode( T1_Face  face,
+                                         T1_Int   charcode )
+  {
+    T1_Int            n;
+    const T1_String*  glyph_name;
+    
+    /* check range of standard char code */
+    if (charcode < 0 || charcode > 255)
+      return -1;
+      
+    glyph_name = t1_standard_strings[t1_standard_encoding[charcode]];
+    
+    for ( n = 0; n < face->num_glyphs; n++ )
+    {
+      T1_String*  name = (T1_String*)face->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
+  T1_Error  t1operator_seac( T1_Decoder*  decoder,
+                             T1_Pos       asb,
+                             T1_Pos       adx,
+                             T1_Pos       ady,
+                             T1_Int       bchar,
+                             T1_Int       achar )
+  {
+    T1_Error     error;
+    T1_Face      face = decoder->builder.face;
+    T1_Int       bchar_index, achar_index, n_base_points;
+    FT_Outline*  cur  = &decoder->builder.current;
+    FT_Outline*  base = &decoder->builder.base;
+    T1_Vector    left_bearing, advance;
+    
+    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(( "T1.Parse_Seac : invalid seac character code arguments\n" ));
+      return T1_Err_Syntax_Error;
+    }
+
+    /* First load "bchar" in builder */
+    /* now load the unscaled outline */
+    cur->n_points   = 0;
+    cur->n_contours = 0;
+    cur->points     = base->points   + base->n_points;
+    cur->flags      = base->flags    + base->n_points;
+    cur->contours   = base->contours + base->n_contours;
+
+    error = T1_Parse_CharStrings( decoder,
+                                  face->charstrings    [bchar_index],
+                                  face->charstrings_len[bchar_index],
+                                  face->num_subrs,
+                                  face->subrs,
+                                  face->subrs_len );
+    if (error) return error;
+
+    n_base_points   = cur->n_points;
+
+    /* save the left bearing and width of the base character */
+    /* as they will be erase 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           */
+    /*                            */ 
+    cur->n_points   = 0;
+    cur->n_contours = 0;
+    cur->points     = base->points   + base->n_points;
+    cur->flags      = base->flags    + base->n_points;
+    cur->contours   = base->contours + base->n_contours;
+
+    error = T1_Parse_CharStrings( decoder,
+                                  face->charstrings    [achar_index],
+                                  face->charstrings_len[achar_index],
+                                  face->num_subrs,
+                                  face->subrs,
+                                  face->subrs_len );
+    if (error) return error;
+
+    /* adjust contours in accented character outline */
+    {
+      T1_Int  n;
+
+      for ( n = 0; n < cur->n_contours; n++ )
+        cur->contours[n] += n_base_points;
+    }
+
+    /* 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 */
+    FT_Translate_Outline( cur, adx - asb, ady );
+    
+    (void)asb;           /* ignore this parameter */
+    return T1_Err_Ok;
+  }
+
+/*********************************************************************
+ *
+ * <Function>
+ *    t1operator_flex
+ *
+ * <Description>
+ *    Implements the "flex" Type 1 operator for a Type 1 decoder
+ *
+ * <Input>
+ *    decoder   :: current Type 1 decoder
+ *    threshold :: threshold
+ *    end_x     :: position of final flex point
+ *    end_y     :: position of final flex point
+ *
+ * <Return>
+ *    Error code. 0 means success.                               
+ *
+ *********************************************************************/
+
+  static
+  T1_Error  t1operator_flex( T1_Decoder*  decoder,
+                             T1_Pos       threshold,
+                             T1_Pos       end_x,
+                             T1_Pos       end_y )
+  {
+    T1_Vector    vec;
+    T1_Vector*   flex  = decoder->flex_vectors;
+    T1_Int       n;
+
+    /* we don't even try to test the threshold in the non-hinting  */
+    /* builder, even if the flex operator is said to be a path      */
+    /* construction statement in the specification. This is better */
+    /* left to the hinter..                                        */
+
+    flex = decoder->flex_vectors;
+    vec  = *flex++;
+
+    for ( n = 0; n < 6; n++ )
+    {
+      flex->x += vec.x;
+      flex->y += vec.y;
+
+      vec = *flex++;
+    }
+
+
+    (void)threshold;
+    (void)end_x;
+    (void)end_y;
+
+    flex  = decoder->flex_vectors;
+
+    return  decoder->builder.funcs.rcurve_to( &decoder->builder,
+                                              flex[0].x, flex[0].y,
+                                              flex[1].x, flex[1].y,
+                                              flex[2].x, flex[2].y ) ||
+
+            decoder->builder.funcs.rcurve_to( &decoder->builder,
+                                              flex[3].x, flex[3].y,
+                                              flex[4].x, flex[4].y,
+                                              flex[5].x, flex[5].y );
+  }
+
+
+/*********************************************************************
+ *
+ * <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.                               
+ *
+ *********************************************************************/
+
+  EXPORT_FUNC
+  T1_Error   T1_Parse_CharStrings( T1_Decoder*  decoder,
+                                   T1_Byte*     charstring_base,
+                                   T1_Int       charstring_len,
+                                   T1_Int       num_subrs,
+                                   T1_Byte**    subrs_base,
+                                   T1_Int*      subrs_len )
+  {
+    T1_Error            error;
+    T1_Decoder_Zone*    zone;
+    T1_Byte*            ip;
+    T1_Byte*            limit;
+    T1_Builder*         builder = &decoder->builder;
+    T1_Builder_Funcs*   builds  = &builder->funcs;
+    T1_Hinter_Funcs*    hints   = &decoder->hinter;
+
+    static const T1_Int  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 */
+    };
+
+    /* 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;
+
+    /* now, execute loop */
+    while ( ip < limit )
+    {
+      T1_Int*      top      = decoder->top;
+      T1_Operator  op       = op_none;
+      T1_Long      value    = 0;
+
+      /* 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 if needed */
+      if ( op == op_none )
+      {
+        if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
+        {
+          FT_ERROR(( "T1.Parse_CharStrings : Stack overflow !!\n" ));
+          goto Syntax_Error;
+        }
+
+        *top++       = value;
+        decoder->top = top;
+      }
+
+      else if ( op == op_callothersubr ) /* check arguments differently */
+      {
+        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;
+              decoder->flex_vectors[0].x = 0;
+              decoder->flex_vectors[0].y = 0;
+            }
+            break;
+
+
+          case 2:   /* add flex vector ------------------------------- */
+            {
+              T1_Int      index;
+              T1_Vector*  flex;
+
+              if (top[0] != 0) goto Unexpected_OtherSubr;
+
+              top -= 2;
+              if (top < decoder->stack) goto Stack_Underflow;
+
+              index = decoder->num_flex_vectors++;
+              if (index >= 7)
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: too many flex vectors !\n" ));
+                goto Syntax_Error;
+              }
+
+              flex = decoder->flex_vectors + index;
+              flex->x += top[0];
+              flex->y += top[1];
+
+            }
+            break;
+
+
+          case 0:   /* end flex feature ------------------------------ */
+            {
+              if ( decoder->flex_state       == 0 ||
+                   decoder->num_flex_vectors != 7 )
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: unexpected flex end\n" ));
+                goto Syntax_Error;
+              }
+
+              if (top[0] != 3) goto Unexpected_OtherSubr;
+
+              top -= 3;
+              if (top < decoder->stack) goto Stack_Underflow;
+
+              /* now consume the remaining "pop pop setcurrentpoint" */
+              if ( ip+6 > limit ||
+                   ip[0] != 12  || ip[1] != 17 ||   /* pop */
+                   ip[2] != 12  || ip[3] != 17 ||   /* pop */
+                   ip[4] != 12  || ip[5] != 33 )    /* setcurrentpoint */
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: invalid flex charstring\n" ));
+                goto Syntax_Error;
+              }
+
+              decoder->flex_state = 0;
+              decoder->top        = top;
+
+              error = t1operator_flex( decoder, top[0], top[1], top[2] );
+            }
+            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;
+              error  = hints->change_hints(builder);
+            }
+            break;
+
+
+          default:
+            /* invalid OtherSubrs call */
+          Unexpected_OtherSubr:
+            FT_ERROR(( "T1.Parse_CharStrings: unexpected OtherSubrs [%d %d]\n",
+                     top[0], top[1] ));
+            goto Syntax_Error;
+        }
+        decoder->top = top;
+      }
+      else
+      {
+        T1_Int  num_args = args_count[op];
+
+        if ( top - decoder->stack < num_args )
+          goto Stack_Underflow;
+
+        top -= num_args;
+
+        switch (op)
+        {
+          case op_endchar:
+            error = builds->end_char( builder );
+            break;
+
+          case op_hsbw:
+            error = builds->set_bearing_point( builder, top[0], 0,
+                                                         top[1], 0 );
+            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:
+            error = builds->set_bearing_point( builder, top[0], top[1],
+                                                        top[2], top[3] );
+            break;
+
+          case op_closepath:
+            error = builds->close_path( builder );
+            break;
+
+          case op_hlineto:
+            error = builds->rline_to( builder, top[0], 0 );
+            break;
+
+          case op_hmoveto:
+            error = builds->rmove_to( builder, top[0], 0 );
+            break;
+
+          case op_hvcurveto:
+            error = builds->rcurve_to( builder, top[0], 0,
+                                                top[1], top[2],
+                                                0,      top[3] );
+            break;
+
+          case op_rlineto:
+            error = builds->rline_to( builder, top[0], top[1] );
+            break;
+
+          case op_rmoveto:
+            /* ignore operator when in flex mode */
+            if (decoder->flex_state == 0)
+              error = builds->rmove_to( builder, top[0], top[1] );
+            else
+              top += 2;
+            break;
+
+          case op_rrcurveto:
+            {
+              error = builds->rcurve_to( builder, top[0], top[1],
+                                                  top[2], top[3],
+                                                  top[4], top[5] );
+            }
+            break;
+
+          case op_vhcurveto:
+            error = builds->rcurve_to( builder,      0, top[0],
+                                                top[1], top[2],
+                                                top[3],      0 );
+            break;
+
+          case op_vlineto:
+            error = builds->rline_to( builder, 0, top[0] );
+            break;
+
+          case op_vmoveto:
+            error = builds->rmove_to( builder, 0, top[0] );
+            break;
+
+          case op_dotsection:
+            error = hints->dot_section( builder );
+            break;
+
+          case op_hstem:
+            error = hints->stem( builder, top[0], top[1], 0 );
+            break;
+
+          case op_hstem3:
+            error = hints->stem3( builder, top[0], top[1], top[2],
+                                           top[3], top[4], top[5], 0 );
+            break;
+
+          case op_vstem:
+            error = hints->stem( builder, top[0], top[1], 1 );
+            break;
+
+          case op_vstem3:
+            error = hints->stem3( builder, top[0], top[1], top[2],
+                                           top[3], top[4], top[5], 1 );
+            break;
+
+          case op_div:
+            if (top[1])
+              *top++ = top[0] / top[1];
+            else
+            {
+              FT_ERROR(( "T1.Parse_CHarStrings : division by 0\n" ));
+              goto Syntax_Error;
+            }
+            break;
+
+          case op_callsubr:
+            {
+              T1_Int  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_ERROR(( "T1.Parse_CharStrings : unexpected POP\n" ));
+            goto Syntax_Error;
+
+
+          case op_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_setcurrentpoint:
+            FT_ERROR(( "T1.Parse_CharStrings : unexpected SETCURRENTPOINT\n" ));
+            goto Syntax_Error;
+            break;
+
+          default:
+            FT_ERROR(( "T1.Parse_CharStrings : unhandled opcode %d\n", op ));
+            goto Syntax_Error;
+        }
+
+        decoder->top = top;
+      }
+    }
+
+    return error;
+
+  Syntax_Error:
+    return T1_Err_Syntax_Error;
+
+  Stack_Underflow:
+    return T1_Err_Stack_Underflow;
+  }
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> T1_Add_Points                                              */
+/*                                                                       */
+/* <Description>                                                         */
+/*    Checks that there is enough room in the current load glyph outline */
+/*    to accept "num_points" additional outline points. If not, this     */
+/*    function grows the load outline's arrays accordingly..             */
+/*                                                                       */
+/* <Input>                                                               */
+/*    builder    :: pointer to glyph builder object                      */
+/*    num_points :: number of points that will be added later            */
+/*                                                                       */
+/* <Return>                                                              */
+/*    Type1 error code. 0 means success                                  */
+/*                                                                       */
+/* <Note>                                                                */
+/*    This function does NOT update the points count in the glyph builder*/
+/*    This must be done by the caller itself, after this function is     */
+/*    invoked..                                                          */
+/*                                                                       */
+  LOCAL_FUNC
+  T1_Error  T1_Add_Points( T1_Builder*  builder,
+                           T1_Int       num_points )
+  {
+    T1_Int    new_points;
+
+    new_points = builder->base.n_points +
+                 builder->current.n_points +
+                 num_points;
+
+    if ( new_points > builder->max_points )
+    {
+      FT_Memory  memory    = builder->memory;
+      T1_Error   error;
+      T1_Int     increment = builder->current.points - builder->base.points;
+      T1_Int     current   = builder->max_points;
+
+      while ( builder->max_points < new_points )
+        builder->max_points += 16;
+
+      if ( REALLOC_ARRAY( builder->base.points,
+                          current, builder->max_points, T1_Vector )  ||
+  
+           REALLOC_ARRAY( builder->base.flags,
+                          current, builder->max_points, T1_Byte )    )
+        return error;
+    
+      builder->current.points = builder->base.points + increment;
+      builder->current.flags  = builder->base.flags  + increment;
+    }
+
+    return T1_Err_Ok;
+  }
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> T1_Add_Contours                                            */
+/*                                                                       */
+/* <Description>                                                         */
+/*    Checks that there is enough room in the current load glyph outline */
+/*    to accept "num_contours" additional contours. If not, this func    */
+/*    the load outline's arrays accordingly..                            */
+/*                                                                       */
+/* <Input>                                                               */
+/*    builder       :: pointer to glyph builder object                   */
+/*    num_contours :: number of contours that will be added later        */
+/*                                                                       */
+/* <Return>                                                              */
+/*    Type1 error code. 0 means success                                  */
+/*                                                                       */
+/* <Note>                                                                */
+/*    This function does NOT update the contours count in the load glyph */
+/*    This must be done by the caller itself, after this function is     */
+/*    invoked..                                                          */
+/*                                                                       */
+  LOCAL_FUNC
+  T1_Error  T1_Add_Contours( T1_Builder*  builder,
+                             T1_Int       num_contours )
+  {
+    T1_Int    new_contours;
+
+    new_contours = builder->base.n_contours +
+                   builder->current.n_contours +
+                   num_contours;
+
+    if ( new_contours > builder->max_contours && builder->load_points )
+    {
+      T1_Error  error;
+      FT_Memory memory = builder->memory;
+      T1_Int    increment = builder->current.contours - builder->base.contours;
+      T1_Int    current   = builder->max_contours;
+
+      while ( builder->max_contours < new_contours )
+        builder->max_contours += 4;
+
+      if ( REALLOC_ARRAY( builder->base.contours,
+                          current, builder->max_contours, T1_Short ) )
+        return error;
+  
+      builder->current.contours = builder->base.contours + increment;
+    }
+
+    return T1_Err_Ok;
+  }
+
+
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********           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.                                       *********/
+  /**********                                                   *********/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+
+
+
+  static
+  T1_Error  maxadv_sbw( T1_Decoder*  decoder,
+                        T1_Pos       sbx,
+                        T1_Pos       sby,
+                        T1_Pos       wx,
+                        T1_Pos       wy )
+  {
+    if (wx > decoder->builder.advance.x)
+      decoder->builder.advance.x = wx;
+
+    (void)sbx;
+    (void)sby;
+    (void)wy;
+    return -1;    /* return an error code to exit the Type 1 parser */
+                  /* immediately.                                   */
+  }
+
+
+  static
+  T1_Int  maxadv_error( void )
+  {
+    /* we should never reach this code, unless with a buggy font */
+    return -2;
+  }
+
+  /* the maxadv_gbuilder_interface is used when computing the maximum  */
+  /* advance width of all glyphs in a given font. We only process the */
+  /* 'sbw' operator here, and return an error for all others..        */
+
+  /* Note that "seac" is processed by the T1_Decoder                  */
+  static
+  const T1_Builder_Funcs  maxadv_builder_interface =
+  {
+    (T1_Builder_EndChar)     maxadv_error,
+    (T1_Builder_Sbw)         maxadv_sbw,
+    (T1_Builder_ClosePath)   maxadv_error,
+    (T1_Builder_RLineTo)     maxadv_error,
+    (T1_Builder_RMoveTo)     maxadv_error,
+    (T1_Builder_RCurveTo)    maxadv_error
+  };
+
+
+  /* the maxadv_interface is used when computing the maximum advance */
+  /* with of the set of glyphs in a given font file. We only process */
+  /* the "seac" operator and return immediately..                    */
+  static
+  const T1_Hinter_Funcs  maxadv_hinter_interface =
+  {
+    (T1_Hinter_DotSection)   maxadv_error,
+    (T1_Hinter_ChangeHints)  maxadv_error,
+    (T1_Hinter_Stem)         maxadv_error,
+    (T1_Hinter_Stem3)        maxadv_error,
+  };
+
+
+
+  LOCAL_FUNC
+  T1_Error  T1_Compute_Max_Advance( T1_Face  face,
+                                    T1_Int  *max_advance )
+  {
+    T1_Error    error;
+    T1_Decoder  decoder;
+    T1_Int      glyph_index;
+
+    *max_advance = 0;
+
+    /* Initialise load decoder */
+    T1_Init_Decoder( &decoder, &maxadv_hinter_interface );
+
+    T1_Init_Builder( &decoder.builder, face, 0, 0,
+                     &maxadv_builder_interface );
+
+    /* For each glyph, parse the glyph charstring and extract */
+    /* the advance width..                                    */
+    for ( glyph_index = 0; glyph_index < face->num_glyphs; glyph_index++ )
+    {
+      /* now get load the unscaled outline */
+      error = T1_Parse_CharStrings( &decoder,
+                                    face->charstrings    [glyph_index],
+                                    face->charstrings_len[glyph_index],
+                                    face->num_subrs,
+                                    face->subrs,
+                                    face->subrs_len );
+      /* ignore the error if one occured - skip to next glyph */
+      (void)error;
+    }
+
+    *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.     *********/
+  /**********                                                   *********/
+  /**********     The Type 1 hinter is located in "t1hint.c"    *********/
+  /**********                                                   *********/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+
+
+
+  static
+  T1_Error  close_open_path( T1_Builder*  builder )
+  {
+    T1_Error     error;
+    FT_Outline*  cur = &builder->current;
+    T1_Int       num_points;
+    T1_Int       first_point;
+      
+    /* Some fonts, like Hershey, are made of "open paths" which are    */
+    /* now managed directly by FreeType. In this case, it is necessary */
+    /* to close the path by duplicating its points in reverse order,   */
+    /* which is precisely the purpose of this function                 */
+
+    /* first compute the number of points to duplicate..           */
+    if (cur->n_contours > 1)
+      first_point = cur->contours[ cur->n_contours-2 ]+1;
+    else
+      first_point = 0;
+        
+    num_points = cur->n_points - first_point - 2;
+    if ( num_points > 0 )
+    {
+      T1_Vector*  source_point;
+      char*       source_flags;
+      T1_Vector*  point;
+      char*       flags;
+              
+      error = T1_Add_Points( builder, num_points );
+      if (error) return error;
+
+      point = cur->points + cur->n_points;
+      flags = cur->flags  + cur->n_points;
+        
+      source_point   = point - 2;
+      source_flags   = flags - 2;
+
+      cur->n_points += num_points;
+
+      if ( builder->load_points )  
+        do
+        {
+          *point++ = *source_point--;
+          *flags++ = *source_flags--;
+          num_points--;
+        }
+        while (num_points > 0);
+    }
+
+    builder->path_begun = 0;
+    return T1_Err_Ok;
+  }
+
+
+  static
+  T1_Error  gload_closepath( T1_Builder*  builder )
+  {
+    FT_Outline*  cur = &builder->current;
+
+    /* save current contour, if any */
+    if ( cur->n_contours > 0 )
+      cur->contours[cur->n_contours-1] = cur->n_points-1;
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+    /* hint latest points if needed - this is not strictly required      */
+    /* there, but it helps for debugging, and doesn't affect performance */
+    if ( builder->pass == 1 )
+      T1_Hint_Points( builder );
+#endif
+
+    builder->path_begun = 0;
+    return T1_Err_Ok;
+  }
+
+
+
+  static
+  T1_Error  gload_endchar( T1_Builder*  builder )
+  {
+    FT_Outline*  cur = &builder->current;
+    T1_Error     error;
+
+    /* close path if needed */
+    if (builder->path_begun)
+    {
+      error = close_open_path( builder );
+      if (error) return error;
+    }
+
+    error = gload_closepath( builder );  
+
+    builder->base.n_points   += cur->n_points;
+    builder->base.n_contours += cur->n_contours;
+
+    return error;
+  }
+
+
+
+  static
+  T1_Error  gload_sbw( T1_Builder*  builder,
+                       T1_Pos       sbx,
+                       T1_Pos       sby,
+                       T1_Pos       wx,
+                       T1_Pos       wy )
+  {
+    builder->left_bearing.x += sbx;
+    builder->left_bearing.y += sby;
+    builder->advance.x       = wx;
+    builder->advance.y       = wy;
+
+    builder->last.x = sbx;
+    builder->last.y = sby;
+    return 0;
+  }
+
+
+
+
+  static
+  T1_Error  gload_rlineto( T1_Builder*  builder,
+                           T1_Pos       dx,
+                           T1_Pos       dy )
+  {
+    T1_Error     error;
+    FT_Outline*  cur = &builder->current;
+    T1_Vector    vec;
+
+    /* grow buffer if necessary */
+    error = T1_Add_Points  ( builder, 1 );
+    if (error) return error;
+
+    if ( builder->load_points )
+    {
+      /* save point */
+      vec.x = builder->last.x + dx;
+      vec.y = builder->last.y + dy;
+
+      cur->points[cur->n_points] = vec;
+      cur->flags [cur->n_points] = FT_Curve_Tag_On;
+
+      builder->last = vec;
+    }
+    cur->n_points++;
+
+    builder->path_begun  = 1;
+    return T1_Err_Ok;
+  }
+
+
+  static
+  T1_Error  gload_rmoveto( T1_Builder*  builder,
+                           T1_Pos       dx,
+                           T1_Pos       dy )
+  {
+    T1_Error     error;
+    FT_Outline*  cur = &builder->current;
+    T1_Vector    vec;
+
+    /* in the case where "path_begun" is set, we have a rmoveto    */
+    /* after some normal path definition. When the face's paint    */
+    /* type is set to 1, this means that we have an "open path",   */
+    /* also called a 'stroke'. The FreeType raster doesn't support */
+    /* opened path, so we'll close it explicitely there..          */
+    if ( builder->path_begun && builder->face->paint_type == 1 )
+    {
+      if ( builder->face->paint_type == 1 )
+      {
+        error = close_open_path( builder );
+        if (error) return error;
+      }
+    }
+    
+    /* grow buffer if necessary */
+    error = T1_Add_Contours( builder, 1 ) ||
+            T1_Add_Points  ( builder, 1 );
+    if (error) return error;
+
+    /* save current contour, if any */
+    if ( cur->n_contours > 0 )
+      cur->contours[cur->n_contours-1] = cur->n_points-1;
+
+    if ( builder->load_points )
+    {
+      /* save point */
+      vec.x = builder->last.x + dx;
+      vec.y = builder->last.y + dy;
+      cur->points[cur->n_points] = vec;
+      cur->flags [cur->n_points] = FT_Curve_Tag_On;
+
+      builder->last = vec;
+    }
+
+    cur->n_contours++;
+    cur->n_points++;
+
+    return T1_Err_Ok;
+  }
+
+
+  static
+  T1_Error  gload_rrcurveto( T1_Builder*  builder,
+                             T1_Pos       dx1,
+                             T1_Pos       dy1,
+                             T1_Pos       dx2,
+                             T1_Pos       dy2,
+                             T1_Pos       dx3,
+                             T1_Pos       dy3 )
+  {
+    T1_Error     error;
+    FT_Outline*  cur = &builder->current;
+    T1_Vector    vec;
+    T1_Vector*   points;
+    char*        flags;
+
+    /* grow buffer if necessary */
+    error = T1_Add_Points  ( builder, 3 );
+    if (error) return error;
+
+    if ( builder->load_points )
+    {
+      /* save point */
+      points = cur->points + cur->n_points;
+      flags  = cur->flags  + cur->n_points;
+
+      vec.x = builder->last.x + dx1;
+      vec.y = builder->last.y + dy1;
+      points[0] = vec;  flags[0] = FT_Curve_Tag_Cubic;
+
+      vec.x += dx2;
+      vec.y += dy2;
+      points[1] = vec;  flags[1] = FT_Curve_Tag_Cubic;
+
+      vec.x += dx3;
+      vec.y += dy3;
+      points[2] = vec;  flags[2] = FT_Curve_Tag_On;
+
+      builder->last = vec;
+    }
+    
+    cur->n_points      += 3;
+    builder->path_begun = 1;
+    return T1_Err_Ok;
+  }
+
+
+
+
+  static
+  T1_Error  gload_ignore( void )
+  {
+    return 0;
+  }
+
+
+  static
+  const T1_Builder_Funcs  gload_builder_interface =
+  {
+    gload_endchar,
+    gload_sbw,
+    gload_closepath,
+    gload_rlineto,
+    gload_rmoveto,
+    gload_rrcurveto
+  };
+
+
+  static
+  const T1_Builder_Funcs  gload_builder_interface_null =
+  {
+    (T1_Builder_EndChar)    gload_ignore,
+    (T1_Builder_Sbw)        gload_sbw,      /* record left bearing */
+    (T1_Builder_ClosePath)  gload_ignore,
+    (T1_Builder_RLineTo)    gload_ignore,
+    (T1_Builder_RMoveTo)    gload_ignore,
+    (T1_Builder_RCurveTo)   gload_ignore
+  };
+
+
+  static
+  const T1_Hinter_Funcs   gload_hinter_interface =
+  {
+    (T1_Hinter_DotSection)   gload_ignore,   /* dotsection         */
+    (T1_Hinter_ChangeHints)  gload_ignore,   /* changehints        */
+    (T1_Hinter_Stem)         gload_ignore,   /* hstem & vstem      */
+    (T1_Hinter_Stem3)        gload_ignore,   /* hstem3 & vestem3   */
+  };
+
+
+
+
+  LOCAL_FUNC
+  T1_Error  T1_Load_Glyph( T1_GlyphSlot  glyph,
+                           T1_Size       size,
+                           T1_Int        glyph_index,
+                           T1_Int        load_flags )
+  {
+    T1_Error        error;
+    T1_Decoder      decoder;
+    T1_Face         face = (T1_Face)glyph->root.face;
+    T1_Bool         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;
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+    /*****************************************************************/
+    /*                                                               */
+    /*  Hinter overview :                                            */
+    /*                                                               */
+    /*    This is a two-pass hinter. On the first pass, the hints    */
+    /*    are all recorded by the hinter, and no point is loaded     */
+    /*    in the outline.                                            */
+    /*                                                               */
+    /*    When the first pass is finished, all stems hints are       */
+    /*    grid-fitted at once.                                       */
+    /*                                                               */
+    /*    Then, a second pass is performed to load the outline       */
+    /*    points as well as hint/scale them correctly.               */
+    /*                                                               */
+
+    if ( hinting )
+    {
+      /* Pass 1 - don't record points, simply stem hints */
+      T1_Init_Decoder( &decoder, &t1_hinter_funcs );
+      T1_Init_Builder( &decoder.builder, face, size, glyph,
+                       &gload_builder_interface_null );
+
+      glyph->hints->hori_stems.num_stems = 0;
+      glyph->hints->vert_stems.num_stems = 0;
+
+      error = T1_Parse_CharStrings( &decoder,
+                                    face->charstrings    [glyph_index],
+                                    face->charstrings_len[glyph_index],
+                                    face->num_subrs,
+                                    face->subrs,
+                                    face->subrs_len );
+
+      /* All right, pass 1 is finished, now grid-fit all stem hints */
+      T1_Hint_Stems( &decoder.builder );
+
+      /* Pass 2 - record and scale/hint the points */
+      T1_Init_Decoder( &decoder, &t1_hinter_funcs );
+      T1_Init_Builder( &decoder.builder, face, size, glyph,
+                       &gload_builder_interface );
+
+      decoder.builder.pass = 1;
+
+      error = T1_Parse_CharStrings( &decoder,
+                                    face->charstrings    [glyph_index],
+                                    face->charstrings_len[glyph_index],
+                                    face->num_subrs,
+                                    face->subrs,
+                                    face->subrs_len );
+
+      /* save new glyph tables */
+      T1_Done_Builder( &decoder.builder );
+    }
+    else
+#endif
+    {
+      T1_Init_Decoder( &decoder, &gload_hinter_interface );
+
+      T1_Init_Builder( &decoder.builder, face, size, glyph,
+                       &gload_builder_interface );
+  
+      /* now load the unscaled outline */
+      error = T1_Parse_CharStrings( &decoder,
+                                    face->charstrings    [glyph_index],
+                                    face->charstrings_len[glyph_index],
+                                    face->num_subrs,
+                                    face->subrs,
+                                    face->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)
+    {
+      FT_BBox           cbox;
+      FT_Glyph_Metrics* metrics = &glyph->root.metrics;
+
+      FT_Get_Outline_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;
+
+      /* 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.second_pass    = TRUE;
+      glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
+      glyph->root.outline.dropout_mode   = 2;
+
+      if ( hinting )
+      {
+        /* adjust the advance width                  */
+        /* XXX : TODO : consider stem hints grid-fit */
+        metrics->horiAdvance  = FT_MulFix( metrics->horiAdvance,
+                                           glyph->x_scale );
+      }
+      else if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
+      {
+        /* scale the outline and the metrics */
+        T1_Int       n;
+        FT_Outline*  cur = &decoder.builder.base;
+        T1_Vector*   vec = cur->points;
+        T1_Fixed     x_scale = glyph->x_scale;
+        T1_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 );
+        }
+
+        /* Then scale the metrics */
+        metrics->width  = FT_MulFix( metrics->width,  x_scale );
+        metrics->height = FT_MulFix( metrics->height, y_scale );
+
+        metrics->horiBearingX = FT_MulFix( metrics->horiBearingX, x_scale );
+        metrics->horiBearingY = FT_MulFix( metrics->horiBearingY, y_scale );
+        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 );
+
+      }
+    }
+
+    return error;
+  }
+
diff --git a/src/type1/t1gload.h b/src/type1/t1gload.h
new file mode 100644
index 0000000..f635b81
--- /dev/null
+++ b/src/type1/t1gload.h
@@ -0,0 +1,436 @@
+/*******************************************************************
+ *
+ *  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_Funcs                                          */
+/*                                                                       */
+/* <Description>                                                         */
+/*     a structure used to store the address of various functions        */
+/*     used by a glyph builder to implement the outline's "path          */
+/*     construction".                                                    */
+/*                                                                       */
+/*                                                                       */
+  typedef struct T1_Builder_  T1_Builder;
+
+  typedef T1_Error  (*T1_Builder_EndChar)( T1_Builder*  loader );
+
+  typedef T1_Error  (*T1_Builder_Sbw)    ( T1_Builder*  loader,
+                                           T1_Pos       sbx,
+                                           T1_Pos       sby,
+                                           T1_Pos       wx,
+                                           T1_Pos       wy );
+
+  typedef T1_Error  (*T1_Builder_ClosePath)( T1_Builder*  loader );
+
+  typedef T1_Error  (*T1_Builder_RLineTo)( T1_Builder*  loader,
+                                           T1_Pos       dx,
+                                           T1_Pos       dy );
+
+  typedef T1_Error  (*T1_Builder_RMoveTo)( T1_Builder*  loader,
+                                           T1_Pos       dx,
+                                           T1_Pos       dy );
+
+  typedef T1_Error  (*T1_Builder_RCurveTo)( T1_Builder*  loader,
+                                            T1_Pos       dx1,
+                                            T1_Pos       dy1,
+                                            T1_Pos       dx2,
+                                            T1_Pos       dy2,
+                                            T1_Pos       dx3,
+                                            T1_Pos       dy3 );
+
+  typedef struct T1_Builder_Funcs_
+  {
+    T1_Builder_EndChar    end_char;
+    T1_Builder_Sbw        set_bearing_point;
+    T1_Builder_ClosePath  close_path;
+    T1_Builder_RLineTo    rline_to;
+    T1_Builder_RMoveTo    rmove_to;
+    T1_Builder_RCurveTo   rcurve_to;
+
+  } T1_Builder_Funcs;
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Structure> T1_Builder                                                */
+/*                                                                       */
+/* <Description>                                                         */
+/*     a structure used during glyph loading to store its outline.       */
+/*                                                                       */
+/* <Fields>                                                              */
+/*    system :: current system object                                    */
+/*    face   :: current face object                                      */
+/*    size   :: current size 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            */
+/*                                                                       */
+/*    pass     :: pass number for multi-pass hinters                     */
+/*                                                                       */
+/*    funcs    :: table of builder functions used to perform             */
+/*                the outline's path construction                        */
+/*                                                                       */
+/*    hint_point :: index of next point to hint..                        */
+/*                                                                       */
+/*                                                                       */
+/*                                                                       */
+/*                                                                       */
+
+  struct T1_Builder_
+  {
+    FT_Memory     memory;
+    T1_Face       face;
+    T1_Size       size;
+    T1_GlyphSlot  glyph;
+
+    FT_Outline    current;       /* the current glyph outline   */
+    FT_Outline    base;          /* the composite glyph outline */
+
+    T1_Int        max_points;    /* capacity of base outline in points   */
+    T1_Int        max_contours;  /* capacity of base outline in contours */
+
+    T1_Vector     last;
+
+    T1_Fixed      scale_x;
+    T1_Fixed      scale_y;
+
+    T1_Pos        pos_x;
+    T1_Pos        pos_y;
+
+    T1_Vector     left_bearing;
+    T1_Vector     advance;
+
+    T1_BBox       bbox;          /* bounding box */
+    T1_Bool       path_begun;
+    T1_Bool       load_points;
+
+    T1_Int        pass;
+    T1_Int        hint_point;
+
+    /* path construction function interface */
+    T1_Builder_Funcs  funcs;
+  };
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Structure> T1_Hinter_Funcs                                           */
+/*                                                                       */
+/* <Description>                                                         */
+/*     a structure used to store the address of various functions        */
+/*     used by a Type 1 hinter to perform outline hinting.               */
+/*                                                                       */
+ 
+  typedef T1_Error  (*T1_Hinter_ChangeHints)( T1_Builder*  builder );
+
+  typedef T1_Error  (*T1_Hinter_DotSection)( T1_Builder*  builder );
+
+  typedef T1_Error  (*T1_Hinter_Stem)( T1_Builder*  builder,
+                                       T1_Pos       pos,
+                                       T1_Pos       width,
+                                       T1_Bool      vertical );
+
+
+  typedef T1_Error  (*T1_Hinter_Stem3)( T1_Builder*  builder,
+                                        T1_Pos       pos0,
+                                        T1_Pos       width0,
+                                        T1_Pos       pos1,
+                                        T1_Pos       width1,
+                                        T1_Pos       pos2,
+                                        T1_Pos       width2,
+                                        T1_Bool      vertical );
+
+  typedef struct T1_Hinter_Func_
+  {
+    T1_Hinter_ChangeHints     change_hints;
+    T1_Hinter_DotSection      dot_section;
+    T1_Hinter_Stem            stem;
+    T1_Hinter_Stem3           stem3;
+
+  } T1_Hinter_Funcs;
+
+
+
+  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;
+
+
+
+
+  /* execution context charstring zone */
+  typedef struct T1_Decoder_Zone_
+  {
+    T1_Byte*  base;
+    T1_Byte*  limit;
+    T1_Byte*  cursor;
+
+  } T1_Decoder_Zone;
+
+
+  typedef struct T1_Decoder_
+  {
+    T1_Builder         builder;
+    T1_Hinter_Funcs    hinter;
+
+    T1_Int             stack[ T1_MAX_CHARSTRINGS_OPERANDS ];
+    T1_Int*            top;
+
+    T1_Decoder_Zone    zones[ T1_MAX_SUBRS_CALLS+1 ];
+    T1_Decoder_Zone*   zone;
+
+    T1_Int             flex_state;
+    T1_Int             num_flex_vectors;
+    T1_Vector          flex_vectors[7];
+
+  } T1_Decoder;
+
+
+
+/*********************************************************************
+ *
+ * <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
+ *    funcs   :: glyph builder functions (or "methods").
+ *
+ * <Note>
+ *    This function is exported for now because it is used by the
+ *    "t1dump" utility. Later, it will be accessed through a
+ *    format-specific extension
+ *
+ *********************************************************************/
+
+  EXPORT_DEF
+  void  T1_Init_Builder( T1_Builder*             builder,
+                         T1_Face                 face,
+                         T1_Size                 size,
+                         T1_GlyphSlot            glyph,
+                         const T1_Builder_Funcs* funcs );
+
+/*********************************************************************
+ *
+ * <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
+ *
+ * <Note>
+ *    This function is exported for now because it is used by the
+ *    "t1dump" utility. Later, it will be accessed through a
+ *    format-specific extension
+ *
+ *********************************************************************/
+
+  EXPORT_DEF
+  void T1_Done_Builder( T1_Builder*  builder );
+
+
+/*********************************************************************
+ *
+ * <Function>
+ *    T1_Init_Decoder
+ *
+ * <Description>
+ *    Initialise a given Type 1 decoder for parsing
+ *
+ * <Input>
+ *    decoder :: Type 1 decoder to initialise
+ *    funcs   :: hinter functions interface
+ *
+ * <Note>
+ *    This function is exported for now because it is used by the
+ *    "t1dump" utility. Later, it will be accessed through a
+ *    format-specific extension
+ *
+ *********************************************************************/
+
+  EXPORT_DEF
+  void  T1_Init_Decoder( T1_Decoder*             decoder,
+                         const T1_Hinter_Funcs*  funcs );
+
+
+
+  /* Compute the maximum advance width of a font through quick parsing */
+  LOCAL_DEF
+  T1_Error  T1_Compute_Max_Advance( T1_Face  face,
+                                    T1_Int  *max_advance );
+
+
+  /* This function is exported, because it is used by the T1Dump utility */
+  EXPORT_DEF
+  T1_Error   T1_Parse_CharStrings( T1_Decoder*  decoder,
+                                   T1_Byte*     charstring_base,
+                                   T1_Int       charstring_len,
+                                   T1_Int       num_subrs,
+                                   T1_Byte**    subrs_base,
+                                   T1_Int*      subrs_len );
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> T1_Add_Points                                              */
+/*                                                                       */
+/* <Description>                                                         */
+/*    Checks that there is enough room in the current load glyph outline */
+/*    to accept "num_points" additional outline points. If not, this     */
+/*    function grows the load outline's arrays accordingly..             */
+/*                                                                       */
+/* <Input>                                                               */
+/*    builder    :: pointer to glyph builder object                      */
+/*    num_points :: number of points that will be added later            */
+/*                                                                       */
+/* <Return>                                                              */
+/*    Type1 error code. 0 means success                                  */
+/*                                                                       */
+/* <Note>                                                                */
+/*    This function does NOT update the points count in the glyph loader */
+/*    This must be done by the caller itself, after this function is     */
+/*    invoked..                                                          */
+/*                                                                       */
+  LOCAL_DEF
+  T1_Error  T1_Add_Points( T1_Builder*  builder,
+                           T1_Int       num_points );
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> T1_Add_Contours                                            */
+/*                                                                       */
+/* <Description>                                                         */
+/*    Checks that there is enough room in the current load glyph outline */
+/*    to accept "num_contours" additional contours. If not, this func    */
+/*    the load outline's arrays accordingly..                            */
+/*                                                                       */
+/* <Input>                                                               */
+/*    builder      :: pointer to glyph builder object                    */
+/*    num_contours :: number of contours that will be added later        */
+/*                                                                       */
+/* <Return>                                                              */
+/*    Type1 error code. 0 means success                                  */
+/*                                                                       */
+/* <Note>                                                                */
+/*    This function does NOT update the contours count in the load glyph */
+/*    This must be done by the caller itself, after this function is     */
+/*    invoked..                                                          */
+/*                                                                       */
+  LOCAL_DEF
+  T1_Error  T1_Add_Contours( T1_Builder*  builder,
+                             T1_Int       num_contours );
+
+
+  LOCAL_DEF
+  T1_Error  T1_Load_Glyph( T1_GlyphSlot  glyph,
+                           T1_Size       size,
+                           T1_Int        glyph_index,
+                           T1_Int        load_flags );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* T1GLOAD_H */
diff --git a/src/type1/t1hinter.c b/src/type1/t1hinter.c
new file mode 100644
index 0000000..7e2d0ab
--- /dev/null
+++ b/src/type1/t1hinter.c
@@ -0,0 +1,1269 @@
+/*******************************************************************
+ *
+ *  t1hinter.c                                                 1.2
+ *
+ *    Type1 hinter.         
+ *
+ *  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.
+ *
+ *
+ *  The Hinter is in charge of fitting th scaled outline to the
+ *  pixel grid in order to considerably improve the quality of
+ *  the Type 1 font driver's output..
+ *
+ ******************************************************************/
+
+#include <ftdebug.h>
+#include <t1objs.h>
+#include <t1hinter.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_t1hint    /* for debugging/tracing */
+
+
+#undef  ONE_PIXEL
+#define ONE_PIXEL  64
+
+#undef  ROUND
+#define ROUND(x)   (( x + ONE_PIXEL/2 ) & -ONE_PIXEL)
+
+#undef  SCALE
+#define SCALE(val)   FT_MulFix( val, scale )
+
+/* various constants used to describe the alignment of a horizontal */
+/* stem with regards to the blue zones                              */
+#define T1_ALIGN_NONE    0
+#define T1_ALIGN_BOTTOM  1
+#define T1_ALIGN_TOP     2
+#define T1_ALIGN_BOTH    3
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    t1_set_blue_zones
+ *
+ * <Description>
+ *    Set a size object's blue zones during reset. This will compute
+ *    the "snap" zone corresponding to each blue zone.
+ *
+ * <Input>
+ *    size  :: handle to target size object
+ *
+ * <Return>
+ *    Error code. 0 means success
+ *
+ * <Note>
+ *    This functions does the following :
+ *
+ *      1. It extracts the bottom and top blue zones from the
+ *         face object.
+ *
+ *      2. Each zone is then grown by  BlueFuzz, overlapping 
+ *         is eliminated by adjusting the zone edges appropriately
+ *
+ *      3. For each zone, we keep its original font units position, its
+ *         original scaled position, as well as its grown/adjusted
+ *         edges.
+ *
+ ************************************************************************/
+
+      /* ultra simple bubble sort (not a lot of elements, mostly */
+      /* pre-sorted, no need for quicksort)                      */
+      static
+      void  t1_sort_blues( T1_Int*  blues,
+                           T1_Int   count )
+      {
+        T1_Int  i, swap;
+        T1_Int* cur;
+    
+        for ( i = 2; i < count; i += 2 )
+        {
+          cur = blues + i;
+          do
+          {
+            if ( cur[-1] < cur[0] )
+              break;
+    
+            swap = cur[-2]; cur[-2] = cur[0]; cur[0] = swap;
+            swap = cur[-1]; cur[-1] = cur[1]; cur[1] = swap;
+            cur -= 2;
+          }
+          while ( cur > blues );
+        }
+      }
+
+
+  static
+  T1_Error  t1_set_blue_zones( T1_Size  size )
+  {
+    T1_Face          face = (T1_Face)size->root.face;
+    T1_Private*      priv = &face->private_dict;
+    T1_Int           n;
+    T1_Int           blues[24];
+    T1_Int           num_bottom;
+    T1_Int           num_top;
+    T1_Int           num_blues;
+    T1_Size_Hints*   hints = size->hints;
+    T1_Snap_Zone*    zone;
+    T1_Pos           pix, orus;
+    T1_Pos           min, max, threshold;
+    T1_Fixed         scale;
+    T1_Bool          is_bottom;
+
+    /**********************************************************************/
+    /*                                                                    */
+    /*  COPY BOTTOM AND TOP BLUE ZONES IN LOCAL ARRAYS                    */
+    /*                                                                    */
+    /*                                                                    */
+
+    /* First of all, check the sizes of the /BlueValues and /OtherBlues */
+    /* tables. They all must contain an even number of arguments        */
+    if ( priv->num_other_blues & 1 ||
+         priv->num_blues       & 1 )
+    {
+      FT_ERROR(( "T1.Copy_Blues : odd number of blue values\n" ));
+      return T1_Err_Syntax_Error;
+    }
+
+    /* copy the bottom blue zones from /OtherBlues           */
+    num_top    = 0;
+    num_bottom = priv->num_other_blues;
+
+    for ( n = 0; n < num_bottom; n ++ )
+      blues[n] = priv->other_blues[n];
+
+    /* Add the first blue zone in /BlueValues to the table */
+    num_top = priv->num_blues - 2;
+    if ( num_top >= 0 )
+    {
+      blues[ num_bottom ] = priv->blue_values[0];
+      blues[num_bottom+1] = priv->blue_values[1];
+
+      num_bottom += 2;
+    }
+
+    /* sort the bottom blue zones */
+    t1_sort_blues( blues, num_bottom );
+
+    hints->num_bottom_zones = num_bottom >> 1;
+
+    /* now copy the /BlueValues to the top of the blues array */
+    if ( num_top > 0 )
+    {
+      for ( n = 0; n < num_top; n++ )
+        blues[ num_bottom+n ] = priv->blue_values[n+2];
+
+      /* sort the top blue zones */
+      t1_sort_blues( blues + num_bottom, num_top );
+    }
+    else
+      num_top = 0;
+
+    num_blues             = num_top + num_bottom;
+    hints->num_blue_zones = ( num_blues ) >> 1;
+
+    /**********************************************************************/
+    /*                                                                    */
+    /*    BUILD BLUE SNAP ZONES FROM THE LOCAL BLUES ARRAYS               */
+    /*                                                                    */
+    /*                                                                    */
+
+    scale     = size->root.metrics.y_scale;
+    zone      = hints->blue_zones;
+    threshold = ONE_PIXEL/4;   /* 0.25 pixels */
+
+    for ( n = 0; n < num_blues; n += 2, zone ++ )
+    {
+      is_bottom = ( n < num_bottom ? 1 : 0 );
+
+      orus = blues[n+is_bottom];  /* get alignement coordinate */
+      pix  = SCALE( orus );       /* scale it                  */
+
+      min  = SCALE( blues[ n ] - priv->blue_fuzz );
+      max  = SCALE( blues[n+1] + priv->blue_fuzz );
+
+      if ( min > pix - threshold ) min = pix - threshold;
+      if ( max < pix + threshold ) max = pix + threshold;
+
+      zone->orus = orus;
+      zone->pix  = pix;
+      zone->min  = min;
+      zone->max  = max;
+    }
+
+    /* adjust edges in case of overlap */
+    zone = hints->blue_zones;
+    for ( n = 0; n < num_blues-2; n += 2, zone ++ )
+    {
+      if ( n != num_bottom-2         &&
+           zone[0].max > zone[1].min )
+      {
+        zone[0].max = zone[1].min = (zone[0].pix+zone[1].pix)/2;
+      }
+    }
+
+    
+    /* Compare the current pixel size with the BlueScale value */
+    /* to know wether to supress overshoots..                  */
+    
+    hints->supress_overshoots = 
+      ( size->root.metrics.y_ppem < FT_MulFix(1000,priv->blue_scale) );
+
+    /* Now print the new blue values in tracing mode */
+#ifdef FT_DEBUG_LEVEL_TRACE
+    
+    FT_TRACE2(( "Blue Zones for size object at $%08lx :\n", (long)size ));
+    FT_TRACE2(( "   orus    pix    min   max\n" ));
+    FT_TRACE2(( "-------------------------------\n" ));
+    
+    zone = hints->blue_zones;
+    for ( n = 0; n < hints->num_blue_zones; n++ )
+    {
+      FT_TRACE2(( "    %3d   %.2f   %.2f  %.2f\n",
+                zone->orus, 
+                zone->pix/64.0,
+                zone->min/64.0, 
+                zone->max/64.0 ));
+      zone++;
+    }
+    FT_TRACE2(( "\nOver shoots are %s\n\n",
+              hints->supress_overshoots ? "supressed" : "active" ));
+
+#endif /* DEBUG_LEVEL_TRACE */
+                               
+    return T1_Err_Ok;
+  }
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    t1_set_snap_zones
+ *
+ * <Description>
+ *    This function set a size object's stem snap zones.
+ *
+ * <Input>
+ *    size :: handle to target size object
+ *
+ * <Return>
+ *    Error code. 0 means success
+ *
+ * <Note>
+ *    This function performs the following :
+ *
+ *      1. It reads and scales the stem snap widths from the parent face
+ *     
+ *      2. A "snap zone" is computed for each snap width, by "growing"
+ *         it with a threshold of a 1/2 pixel. Overlapping is avoided
+ *         through proper edge adjustment.
+ *
+ *      3. Each width whose zone contain the scaled standard set width
+ *         is removed from the table
+ *
+ *      4. Finally, the standard set width is scaled, and its correponding
+ *         "snap zone" is inserted into the sorted snap zones table
+ *
+ ************************************************************************/
+
+  static
+  T1_Error  t1_set_snap_zones( T1_Size  size )
+  {
+    T1_Int         n, direction, n_zones, num_zones;
+    T1_Snap_Zone*  zone;
+    T1_Snap_Zone*  base_zone;
+    T1_Short*      orgs;
+    T1_Pos         standard_width;
+    T1_Fixed       scale;
+
+    T1_Face          face = (T1_Face)size->root.face;
+    T1_Private*      priv = &face->private_dict;
+    T1_Size_Hints*  hints = size->hints;
+
+    /* start with horizontal snap zones */
+    direction      = 0;
+    standard_width = priv->standard_width;
+    n_zones        = priv->num_snap_widths;
+    base_zone      = hints->snap_widths;
+    orgs           = priv->stem_snap_widths;
+    scale          = size->root.metrics.x_scale;
+    
+    while (direction < 2)
+    {
+      /*****************************************************************/
+      /*                                                               */
+      /*  Read and scale stem snap widths table from the physical      */
+      /*  font record.                                                 */
+      /*                                                               */
+      T1_Pos  prev, orus, pix, min, max, threshold;
+      
+      threshold = ONE_PIXEL/4;
+      zone      = base_zone;
+
+      if ( n_zones > 0 )
+      {
+        orus = *orgs++;
+        pix  = SCALE( orus );
+        min  = pix-threshold;
+        max  = pix+threshold;
+
+        zone->orus = orus;
+        zone->pix  = pix;
+        zone->min  = min;
+        prev       = pix;
+
+        for ( n = 1; n < n_zones; n++ )
+        {
+          orus = *orgs++;
+          pix  = SCALE( orus );
+
+          if ( pix-prev < 2*threshold )
+          {
+            min = max = (pix+prev)/2;
+          }
+          else
+            min = pix-threshold;
+
+          zone->max = max;
+          zone++;
+          zone->orus = orus;
+          zone->pix  = pix;
+          zone->min  = min;
+
+          max  = pix+threshold;
+          prev = pix;
+        }
+        zone->max = max;
+      }
+
+      /* print the scaled stem snap values in tracing modes */
+#ifdef FT_DEBUG_LEVEL_TRACE
+      
+      FT_TRACE2(( "Set_Snap_Zones : first %s pass\n", 
+                direction ? "vertical" : "horizontal" ));
+                
+      FT_TRACE2(( "Scaled original stem snap zones :\n" ));
+      FT_TRACE2(( "   orus   pix   min   max\n" ));
+      FT_TRACE2(( "-----------------------------\n" ));
+      
+      zone = base_zone;
+      for ( n = 0; n < n_zones; n++, zone++ )
+        FT_TRACE2(( "  %3d  %.2f  %.2f  %.2f\n",
+                  zone->orus,
+                  zone->pix/64.0,
+                  zone->min/64.0,
+                  zone->max/64.0 ));
+      FT_TRACE2(( "\n" ));
+      
+      FT_TRACE2(( "Standard width = %d\n", standard_width ));
+#endif
+
+      /*****************************************************************/
+      /*                                                               */
+      /*  Now, each snap width which is in the range of the standard   */
+      /*  set width will be removed from the list..                    */
+      /*                                                               */
+
+      if ( standard_width > 0 )
+      {
+        T1_Snap_Zone*  parent;
+        T1_Pos         std_pix, std_min, std_max;
+
+        std_pix = SCALE( standard_width );        
+
+        std_min = std_pix-threshold;
+        std_max = std_pix+threshold;
+
+        num_zones = 0;
+        zone      = base_zone;
+        parent    = base_zone;
+
+        for ( n = 0; n < n_zones; n++ )
+        {
+          if ( zone->pix >= std_min && zone->pix <= std_max )
+          {
+            /* this zone must be removed from the list */
+            if ( std_min > zone->min ) std_min = zone->min;
+            if ( std_max < zone->max ) std_max = zone->max;
+          }
+          else
+          {
+            *parent++ = *zone;
+            num_zones++;
+          }
+          zone++;
+        }
+        
+        /**********************************************/
+        /*  Now, insert the standard width zone       */
+        
+        zone = base_zone+num_zones;
+        while ( zone > base_zone && zone[-1].pix > std_max )
+        {
+          zone[0] = zone[-1];
+          zone --;
+        }
+        
+        /* check border zones */
+        if ( zone > base_zone && zone[-1].max > std_min )
+          zone[-1].max = std_min;
+          
+        if ( zone < base_zone+num_zones && zone[1].min < std_max )
+          zone[1].min = std_max;
+        
+        zone->orus = standard_width;
+        zone->pix  = std_pix;
+        zone->min  = std_min;
+        zone->max  = std_max;
+        
+        num_zones++;
+      }
+      else
+        num_zones = n_zones;
+
+      /* save total number of stem snaps now */
+      if (direction) hints->num_snap_heights = num_zones;
+                else hints->num_snap_widths  = num_zones;
+
+      /* print the scaled stem snap values in tracing modes */
+#ifdef FT_DEBUG_LEVEL_TRACE
+      
+      FT_TRACE2(( "Set_Snap_Zones : second %s pass\n", 
+                direction ? "vertical" : "horizontal" ));
+                
+      FT_TRACE2(( "Scaled clipped stem snap zones :\n" ));
+      FT_TRACE2(( "   orus   pix   min   max\n" ));
+      FT_TRACE2(( "-----------------------------\n" ));
+      
+      zone = base_zone;
+      for ( n = 0; n < num_zones; n++, zone++ )
+        FT_TRACE2(( "  %3d  %.2f  %.2f  %.2f\n",
+                  zone->orus,
+                  zone->pix/64.0,
+                  zone->min/64.0,
+                  zone->max/64.0 ));
+      FT_TRACE2(( "\n" ));
+      
+      FT_TRACE2(( "Standard width = %d\n", standard_width ));
+#endif
+     
+      /* continue with vertical snap zone */
+      direction++;
+      standard_width = priv->standard_height;
+      n_zones        = priv->num_snap_heights;
+      base_zone      = hints->snap_heights;
+      orgs           = priv->stem_snap_heights;
+      scale          = size->root.metrics.y_scale;
+    }
+
+    return T1_Err_Ok;
+  }
+  
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_New_Size_Hinter
+ *
+ * <Description>
+ *    Allocates a new hinter structure for a given size object
+ *
+ * <Input>
+ *    size :: handle to target size object
+ *
+ * <Return>
+ *    Error code. 0 means success
+ *
+ ************************************************************************/
+
+  LOCAL_FUNC
+  T1_Error  T1_New_Size_Hinter( T1_Size  size )
+  {
+    FT_Memory  memory = size->root.face->memory;
+    
+    return MEM_Alloc( size->hints, sizeof(*size->hints) );
+  }
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_Done_Size_Hinter
+ *
+ * <Description>
+ *    Releases a given size object's hinter structure
+ *
+ * <Input>
+ *    size :: handle to target size object
+ *
+ ************************************************************************/
+
+  LOCAL_FUNC
+  void      T1_Done_Size_Hinter( T1_Size  size )
+  {
+    FT_Memory  memory = size->root.face->memory;
+
+    FREE( size->hints );
+  }
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_Reset_Size_Hinter
+ *
+ * <Description>
+ *    Recomputes hinting information when a given size object has
+ *    changed its resolutions/char sizes/pixel sizes
+ *
+ * <Input>
+ *    size :: handle to size object
+ *
+ * <Return>
+ *    Error code. 0 means success
+ *
+ ************************************************************************/
+
+  LOCAL_FUNC
+  T1_Error  T1_Reset_Size_Hinter( T1_Size  size )
+  {
+    return t1_set_blue_zones(size) || t1_set_snap_zones(size);
+  }
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_New_Glyph_Hinter
+ *
+ * <Description>
+ *    Allocates a new hinter structure for a given glyph slot
+ *
+ * <Input>
+ *    glyph :: handle to target glyph slot
+ *
+ * <Return>
+ *    Error code. 0 means success
+ *
+ ************************************************************************/
+
+  LOCAL_FUNC
+  T1_Error  T1_New_Glyph_Hinter( T1_GlyphSlot  glyph )
+  {
+    FT_Memory  memory = glyph->root.face->memory;
+    
+    return MEM_Alloc( glyph->hints, sizeof(*glyph->hints) );
+  }
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_Done_Glyph_Hinter
+ *
+ * <Description>
+ *    Releases a given glyph slot's hinter structure
+ *
+ * <Input>
+ *    glyph :: handle to glyph slot
+ *
+ ************************************************************************/
+
+  LOCAL_FUNC
+  void  T1_Done_Glyph_Hinter( T1_GlyphSlot  glyph )
+  {
+    FT_Memory  memory = glyph->root.face->memory;
+
+    FREE( glyph->hints );
+  }
+
+
+
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********              HINTED GLYPH LOADER                  *********/
+  /**********                                                   *********/
+  /**********   The following code is in charge of the first    *********/
+  /**********   and second pass when loading a single outline   *********/
+  /**********                                                   *********/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+
+  static
+  T1_Error   t1_hinter_ignore( void )
+  {
+    /* do nothing, used for "dotsection" which is unsupported for now */
+    return 0;
+  }
+
+  static
+  T1_Error   t1_hinter_stem( T1_Builder*  builder,
+                             T1_Pos       pos,
+                             T1_Int       width,
+                             T1_Bool      vertical )
+  {
+    T1_Stem_Table*   stem_table;
+    T1_Stem_Hint*    stems;
+    T1_Stem_Hint*    cur_stem;
+    T1_Int           min, max, n, num_stems;
+    T1_Bool          new_stem;
+    T1_Glyph_Hints*  hinter = builder->glyph->hints;
+
+    /* select the appropriate stem array */
+    stem_table = vertical ? &hinter->vert_stems : &hinter->hori_stems;
+    stems      = stem_table->stems;
+    num_stems  = stem_table->num_stems;
+
+    /* Compute minimum and maximum orus for the stem */
+    min = pos + ( vertical
+                ? builder->left_bearing.x
+                : builder->left_bearing.y );
+
+    if ( width >= 0 )
+      max = min + width;
+    else
+    {
+      /* a negative width indicates a ghost stem */
+      if ( width == -21 )
+        min += width;
+
+      max = min;
+    }
+
+    /* now scan the array. If we find a stem with the same borders */
+    /* simply activate it..                                        */
+    cur_stem = stems;
+    new_stem = 1;
+
+    for ( n = 0; n < num_stems; n++, cur_stem++ )
+    {
+      if ( cur_stem->min_edge.orus == min &&
+           cur_stem->max_edge.orus == max )
+      {
+        /* This stem is already in the table, simply activate it */
+        if ( (cur_stem->hint_flags & T1_HINT_FLAG_ACTIVE) == 0)
+        {
+          cur_stem->hint_flags  |= T1_HINT_FLAG_ACTIVE;
+          stem_table->num_active ++;
+        }
+        new_stem = 0;
+        break;
+      }
+    }
+
+    /* add a new stem to the array when necessary */
+    if (new_stem)
+    {
+      if (cur_stem >= stems + T1_HINTER_MAX_EDGES)
+      {
+        FT_ERROR(( "T1.Hinter : too many stems in glyph charstring\n" ));
+        return T1_Err_Syntax_Error;
+      }
+
+      /* on the first pass, we record the stem, otherwise, this is */
+      /* a bug in the glyph loader !!                              */
+      if ( builder->pass == 0 )
+      {
+        cur_stem->min_edge.orus = min;
+        cur_stem->max_edge.orus = max;
+        cur_stem->hint_flags    = T1_HINT_FLAG_ACTIVE;
+
+        stem_table->num_stems++;
+        stem_table->num_active++;
+      }
+      else
+      {
+        FT_ERROR(( "T1.Hinter : fatal glyph loader bug - pass2-stem\n" ));
+        return T1_Err_Syntax_Error;
+      }
+    }
+
+    return T1_Err_Ok;
+  }
+
+
+  static
+  T1_Error   t1_hinter_stem3( T1_Builder*  builder,
+                              T1_Pos       pos0,
+                              T1_Int       width0,
+                              T1_Pos       pos1,
+                              T1_Int       width1,
+                              T1_Pos       pos2,
+                              T1_Int       width2,
+                              T1_Bool      vertical )
+  {
+    /* For now, don't be elitist and simply call "stem" 3 times */
+    return t1_hinter_stem( builder, pos0, width0, vertical ) ||
+           t1_hinter_stem( builder, pos1, width1, vertical ) ||
+           t1_hinter_stem( builder, pos2, width2, vertical );
+  }
+
+
+  static
+  T1_Error  t1_hinter_changehints( T1_Builder*  builder )
+  {
+    T1_Int           dimension;
+    T1_Stem_Table*   stem_table;
+    T1_Glyph_Hints*  hinter = builder->glyph->hints;
+
+    /* if we're in the second pass of glyph hinting, we must    */
+    /* call the function T1_Hint_Points on the builder in order */
+    /* to force the fit the latest points to the pixel grid     */
+    if ( builder->pass == 1 )
+      T1_Hint_Points( builder );
+
+    /* Simply de-activate all hints in all arrays */
+    stem_table = &hinter->hori_stems;
+
+    for ( dimension = 2; dimension > 0; dimension-- )
+    {
+      T1_Stem_Hint*  cur   = stem_table->stems;
+      T1_Stem_Hint*  limit = cur + stem_table->num_stems;
+
+      for ( ; cur < limit; cur++ )
+        cur->hint_flags &= ~T1_HINT_FLAG_ACTIVE;
+
+      stem_table->num_active = 0;
+      stem_table = &hinter->vert_stems;
+    }
+
+    return T1_Err_Ok;
+  }
+
+
+  LOCAL_FUNC
+  const T1_Hinter_Funcs  t1_hinter_funcs =
+  {
+    (T1_Hinter_ChangeHints)  t1_hinter_changehints,
+    (T1_Hinter_DotSection)   t1_hinter_ignore,
+    (T1_Hinter_Stem)         t1_hinter_stem,
+    (T1_Hinter_Stem3)        t1_hinter_stem3
+  };
+
+
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********              STEM HINTS MANAGEMENT                *********/
+  /**********                                                   *********/
+  /**********   The following code is in charge of computing    *********/
+  /**********   the placement of each scaled stem hint..        *********/
+  /**********                                                   *********/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+
+/************************************************************************
+ *
+ * <Function>
+ *    t1_sort_hints
+ *
+ * <Description>
+ *    Sort the list of active stems in increasing order, through
+ *    the "sort" indexing table
+ *
+ * <Input>
+ *    table  :: a stem hints table
+ *
+ ************************************************************************/
+
+  static
+  void  t1_sort_hints( T1_Stem_Table*  table )
+  {
+    T1_Int         num_stems   = table->num_stems;
+    T1_Int         num_active  = 0;
+    T1_Int*        sort        = table->sort;
+    T1_Stem_Hint*  stems       = table->stems;
+    T1_Int         n;
+
+    /* record active stems in sort table */
+    for ( n = 0; n < num_stems; n++ )
+    {
+      if ( stems[n].hint_flags & T1_HINT_FLAG_ACTIVE )
+        sort[num_active++] = n;
+    }
+
+    /* now sort the indices. There are usually very few stems, */
+    /* and they are pre-sorted in 90% cases, so we choose a    */
+    /* simple bubble sort (quicksort would be slower)..        */
+    for ( n = 1; n < num_active; n++ )
+    {
+      T1_Int        p   = n-1;
+      T1_Stem_Hint* cur = stems + sort[n];
+
+      do
+      {
+        T1_Int         swap;
+        T1_Stem_Hint*  prev = stems + sort[p];
+
+        /* note that by definition, the active stems cannot overlap    */
+        /* so we simply compare their "min" to sort them..             */
+        /* (we could compare their max, this wouldn't change anything) */
+        if ( prev->min_edge.orus <= cur->min_edge.orus )
+          break;
+
+        /* swap elements */
+        swap      = sort[ p ];
+        sort[ p ] = sort[p+1];
+        sort[p+1] = swap;
+        p--;
+      }
+      while ( p >= 0 );
+    }
+
+    table->num_active = num_active;
+  }
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    t1_hint_horizontal_stems
+ *
+ * <Description>
+ *    Compute the location of each scaled horizontal stem hint.
+ *    This takes care of the blue zones and the horizontal stem
+ *    snap table
+ *
+ * <Input>
+ *    table     :: the horizontal stem hints table
+ *    hints     :: the current size's hint structure
+ *    blueShift :: the value of the /BlueShift as taken from the
+ *                 face object.                               
+ *    scale     :: the 16.16 scale used to convert outline
+ *                 units to 26.6 pixels
+ *
+ * <Note>
+ *    For now, all stems are hinted independently from each other.
+ *    It might be necessary, for better performance, to introduce
+ *    the notion of "controlled" hints describing things like
+ *    counter-stems, stem3 as well as overlapping stems control.
+ *
+ ************************************************************************/
+
+  static
+  void  t1_hint_horizontal_stems( T1_Stem_Table*  table,
+                                  T1_Size_Hints*  hints,
+                                  T1_Pos          blueShift,
+                                  T1_Fixed        scale )
+  {
+    T1_Stem_Hint*  stem      = table->stems;
+    T1_Stem_Hint*  limit     = stem + table->num_stems;
+
+    /* first of all, scale the blueShift */
+    blueShift = SCALE(blueShift);
+
+    /* then scan the horizontal stem table */
+    for ( ; stem < limit; stem++ )
+    {
+      T1_Pos  bottom_orus = stem->min_edge.orus;
+      T1_Pos  top_orus    = stem->max_edge.orus;
+
+      T1_Pos  top_pix     = SCALE( top_orus );
+      T1_Pos  bottom_pix  = SCALE( bottom_orus );
+      T1_Pos  width_pix   = top_pix - bottom_pix;
+
+      T1_Pos  bottom      = bottom_pix;
+      T1_Pos  top         = top_pix;
+      T1_Int  align       = T1_ALIGN_NONE;
+
+      /******************************************************************/
+      /* Snap pixel width if in stem snap range                         */
+      {
+        T1_Snap_Zone*  zone       = hints->snap_heights;
+        T1_Snap_Zone*  zone_limit = zone + hints->num_snap_heights;
+
+        for ( ; zone < zone_limit; zone++ )
+        {
+          if ( width_pix < zone->min )
+            break;
+
+          if ( width_pix <= zone->max )
+          {
+            width_pix = zone->pix;
+            break;
+          }
+        }
+      }
+
+      /******************************************************************/
+      /* round width - minimum 1 pixel if this isn't a ghost stem       */
+      if ( width_pix > 0 )
+        width_pix = ( width_pix < ONE_PIXEL ? ONE_PIXEL : ROUND(width_pix) );
+
+
+      /******************************************************************/
+      /* Now check for bottom blue zones alignement                     */
+      {
+        T1_Int         num_blues  = hints->num_bottom_zones;
+        T1_Snap_Zone*  blue       = hints->blue_zones;
+        T1_Snap_Zone*  blue_limit = blue + num_blues;
+
+        for ( ; blue < blue_limit; blue++ )
+        {
+          if ( bottom_pix < blue->min )
+            break;
+
+          if ( bottom_pix <= blue->max )
+          {
+            align  = T1_ALIGN_BOTTOM;
+            bottom = ROUND( blue->pix );
+
+            /* implements blue shift */
+            if (!hints->supress_overshoots)
+            {
+              T1_Pos  delta = blue->pix - bottom_pix;
+              
+              delta   = ( delta < blueShift ? 0 : ROUND( delta ) );
+              bottom -= delta;
+            }
+          }
+        }
+      }
+
+
+      /******************************************************************/
+      /* Check for top blue zones alignement */
+      {
+        T1_Int         num_blues  = hints->num_blue_zones - 
+                                    hints->num_bottom_zones;
+
+        T1_Snap_Zone*  blue       = hints->blue_zones +
+                                    hints->num_bottom_zones;
+
+        T1_Snap_Zone*  blue_limit = blue + num_blues;
+
+        for ( ; blue < blue_limit; blue++ )
+        {
+          if ( top_pix < blue->min )
+            break;
+
+          if ( top_pix <= blue->max )
+          {
+            align  |= T1_ALIGN_TOP;
+            top     = ROUND( blue->pix );
+
+            /* implements blue shift */
+            if (!hints->supress_overshoots)
+            {
+              T1_Pos  delta = top - blue->pix;
+              
+              delta  = ( delta < blueShift ? 0 : ROUND( delta ) );
+              top   += delta;
+            }
+          }
+        }
+      }
+
+
+      /******************************************************************/
+      /* compute the hinted stem position, according to its alignment   */
+      switch (align)
+      {
+        case T1_ALIGN_BOTTOM:  /* bottom zone alignement */
+          bottom_pix = bottom;
+          top_pix    = bottom + width_pix;
+          break;
+          
+        case T1_ALIGN_TOP:  /* top zone alignement */
+          top_pix    = top;
+          bottom_pix = top - width_pix;
+          
+          break;
+          
+        case T1_ALIGN_BOTH:  /* bottom+top zone alignement */
+          bottom_pix = bottom;
+          top_pix    = top;
+          break;
+          
+        default:  /* no alignement */
+
+          /* XXXX : TODO : Add management of controlled stems */        
+          bottom = ( SCALE(bottom_orus+top_orus) - width_pix )/2;
+        
+          bottom_pix = ROUND(bottom);
+          top_pix    = bottom_pix + width_pix;
+      }
+      
+      stem->min_edge.pix = bottom_pix;
+      stem->max_edge.pix = top_pix;
+    }
+  }
+
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    t1_hint_vertical_stems
+ *
+ * <Description>
+ *    Compute the location of each scaled vertical stem hint.
+ *    This takes care of the vertical stem snap table
+ *
+ * <Input>
+ *    table     :: the vertical stem hints table
+ *    hints     :: the current size's hint structure
+ *    scale     :: the 16.16 scale used to convert outline
+ *                 units to 26.6 pixels
+ *
+ * <Note>
+ *    For now, all stems are hinted independently from each other.
+ *    It might be necessary, for better performance, to introduce
+ *    the notion of "controlled" hints describing things like
+ *    counter-stems, stem3 as well as overlapping stems control.
+ *
+ ************************************************************************/
+
+  /* compute the location of each scaled vertical stem hint. */
+  /* Take care of blue zones and stem snap table             */
+  static
+  void  t1_hint_vertical_stems( T1_Stem_Table*  table,
+                                T1_Size_Hints*  hints,
+                                T1_Fixed        scale )
+  {
+    T1_Stem_Hint*  stem  = table->stems;
+    T1_Stem_Hint*  limit = stem + table->num_stems;
+
+    for ( ; stem < limit; stem++ )
+    {
+      T1_Pos  stem_left  = stem->min_edge.orus;
+      T1_Pos  stem_right = stem->max_edge.orus;
+      T1_Pos  width_pix, left;
+
+      width_pix = SCALE( stem_right - stem_left );
+
+      /* Snap pixel width if in stem snap range */
+      {
+        T1_Snap_Zone*  zone       = hints->snap_widths;
+        T1_Snap_Zone*  zone_limit = zone + hints->num_snap_widths;
+
+        for ( ; zone < zone_limit; zone++ )
+        {
+          if ( width_pix < zone->min )
+            break;
+
+          if ( width_pix <= zone->max )
+          {
+            width_pix = zone->pix;
+            break;
+          }
+        }
+      }
+   
+      /* round width - minimum 1 pixel if this isn't a ghost stem */
+      if ( width_pix > 0 )
+        width_pix = ( width_pix < ONE_PIXEL ? ONE_PIXEL :
+                                              ROUND( width_pix ) );
+
+      /* now place the snapped and rounded stem   */
+
+      /* XXXX : TODO : implement controlled stems for the overlapping */
+      /*               cases..                                        */
+
+      left = ( SCALE(stem_left+stem_right) - width_pix )/2;
+
+      stem->min_edge.pix = ROUND(left);
+      stem->max_edge.pix = stem->min_edge.pix + width_pix;
+    }
+  }
+
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    t1_hint_point
+ *
+ * <Description>
+ *    Grid-fit a coordinate with regards to a given stem hints table
+ *
+ * <Input>
+ *    table  :: the source stem hints table
+ *    coord  :: original coordinate, expressed in font units
+ *    scale  :: the 16.16 scale used to convert font units into
+ *              26.6 pixels
+ *
+ * <Return>
+ *    the hinted/scaled value in 26.6 pixels
+ *
+ * <Note>
+ *    For now, all stems are hinted independently from each other.
+ *    It might be necessary, for better performance, to introduce
+ *    the notion of "controlled" hints describing things like
+ *    counter-stems, stem3 as well as overlapping stems control.
+ *
+ ************************************************************************/
+
+  static
+  T1_Pos  t1_hint_point( T1_Stem_Table*  table,
+                         T1_Pos          coord,
+                         T1_Fixed        scale )
+  {
+    T1_Int         num_active = table->num_active;
+    T1_Int         n;
+    T1_Stem_Hint*  prev = 0;
+    T1_Stem_Hint*  cur  = 0;
+    T1_Edge*       min;
+    T1_Edge*       max;
+    T1_Pos         delta;
+
+    /* only hint when there is at least one stem defined */
+    if (num_active <= 0)
+      return SCALE(coord);
+
+    /* scan the stem table to determine placement of coordinate */
+    /* relative to the list of sorted and stems                 */
+    for ( n = 0; n < num_active; n++, prev = cur )
+    {
+      cur = table->stems + table->sort[n];
+
+      /* is it on the left of the current edge ? */
+      delta = cur->min_edge.orus - coord;
+      if ( delta == 0 ) return cur->min_edge.pix;
+
+      if (delta > 0)
+      {
+        /* if this is the left of the first edge, simply shift */
+        if (!prev) return cur->min_edge.pix - SCALE(delta);
+
+        /* otherwise, interpolate between the maximum of the */
+        /* previous stem, and the minimum of the current one */
+        min = &prev->max_edge;
+        max = &cur->min_edge;
+        goto Interpolate;
+      }
+
+      /* is it within the current edge ? */
+      delta = cur->max_edge.orus - coord;
+      if ( delta == 0 ) return cur->max_edge.pix;
+
+      if (delta > 0)
+      {
+        /* interpolate within the stem */
+        min = &cur->min_edge;
+        max = &cur->max_edge;
+        goto Interpolate;
+      }
+    }
+
+    /* apparently, this coordinate is on the right of the last stem */
+    delta = coord - cur->max_edge.orus;
+    return cur->max_edge.pix + SCALE(delta);
+
+  Interpolate:
+    return min->pix +
+            FT_MulDiv( coord     - min->orus,
+                       max->pix  - min->pix,
+                       max->orus - min->orus );
+  }
+
+
+
+
+
+
+#if 1
+
+/************************************************************************
+ *
+ * <Function>
+ *   T1_Hint_Points
+ *
+ * <Description>
+ *   this function grid-fits several points in a given Type 1 builder
+ *   at once. 
+ *
+ * <Input>
+ *   builder  :: handle to target Type 1 builder
+ *   first    :: first point to hint in builder's current outline
+ *   last     :: last point to hint in builder's current outline
+ *
+ ************************************************************************/
+
+  LOCAL_FUNC
+  void  T1_Hint_Points( T1_Builder*  builder )
+  {
+    T1_Int    first   = builder->hint_point;
+    T1_Int    last    = builder->current.n_points-1;
+
+    T1_Size   size    = builder->size;
+    T1_Fixed  scale_x = size->root.metrics.x_scale;
+    T1_Fixed  scale_y = size->root.metrics.y_scale;
+
+    T1_Glyph_Hints*  hints      = builder->glyph->hints;
+    T1_Stem_Table*   hori_stems = &hints->hori_stems;
+    T1_Stem_Table*   vert_stems = &hints->vert_stems;
+
+    T1_Vector*  cur   = builder->current.points + first;
+    T1_Vector*  limit = cur + last - first + 1;
+
+    /* first of all, sort the active stem hints */
+    t1_sort_hints( hori_stems );
+    t1_sort_hints( vert_stems );
+
+    for ( ; cur < limit; cur++ )
+    {
+      cur->x = t1_hint_point( vert_stems, cur->x, scale_x );
+      cur->y = t1_hint_point( hori_stems, cur->y, scale_y );
+    }
+
+    builder->hint_point = builder->current.n_points;
+  }
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_Hint_Stems
+ *
+ * <Description>
+ *    This function is used to compute the location of each stem hint
+ *    between the first and second passes of the glyph loader on the
+ *    charstring.
+ *
+ * <Input>
+ *    builder :: handle to target builder
+ *
+ ************************************************************************/
+
+  LOCAL_FUNC
+  void  T1_Hint_Stems( T1_Builder*  builder )
+  {
+    T1_Glyph_Hints*  hints = builder->glyph->hints;
+    T1_Private*      priv  = &builder->face->private_dict;
+
+    T1_Size   size    = builder->size;
+    T1_Fixed  scale_x = size->root.metrics.x_scale;
+    T1_Fixed  scale_y = size->root.metrics.y_scale;
+
+    t1_hint_horizontal_stems( &hints->hori_stems,
+                              builder->size->hints,
+                              priv->blue_shift,
+                              scale_y );
+
+    t1_hint_vertical_stems( &hints->vert_stems,
+                            builder->size->hints,
+                            scale_x );
+  }
+
+#endif
diff --git a/src/type1/t1hinter.h b/src/type1/t1hinter.h
new file mode 100644
index 0000000..4bf753a
--- /dev/null
+++ b/src/type1/t1hinter.h
@@ -0,0 +1,380 @@
+/*******************************************************************
+ *
+ *  t1hinter.h                                                 1.2
+ *
+ *    Type1 hinter.         
+ *
+ *  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.
+ *
+ *
+ *  The Hinter is in charge of fitting th scaled outline to the
+ *  pixel grid in order to considerably improve the quality of
+ *  the Type 1 font driver's output..
+ *
+ ******************************************************************/
+
+#ifndef T1HINTER_H
+#define T1HINTER_H
+
+#include <t1objs.h>
+#include <t1gload.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+
+/************************************************************************
+ *
+ * <Struct>
+ *   T1_Snap_Zone
+ *
+ * <Description>
+ *   A "snap zone" is used to model either a blue zone or a stem width
+ *   at a given character size. It is made of a minimum and maximum
+ *   edge, defined in 26.6 pixels, as well as one "original" and
+ *   "scaled" position.
+ *
+ *   the position corresponds to the stem width (for stem snap zones)
+ *   or to the blue position (for blue zones)
+ *
+ * <Fields>
+ *   orus  :: original position in font units
+ *   pix   :: current position in sub-pixel units
+ *   min   :: minimum boundary in sub-pixel units
+ *   max   :: maximim boundary in sub-pixel units
+ *
+ ************************************************************************/
+
+  typedef struct T1_Snap_Zone_
+  {
+    T1_Pos  orus;
+    T1_Pos  pix; 
+    T1_Pos  min; 
+    T1_Pos  max;  
+  
+  } T1_Snap_Zone;
+
+
+/************************************************************************
+ *
+ * <Struct>
+ *   T1_Edge
+ *
+ * <Description>
+ *   A very simply structure used to model an stem edge
+ *
+ * <Fields>
+ *   orus  :: original edge position in font units
+ *   pix   :: scaled edge position in sub-pixel units
+ *
+ ************************************************************************/
+
+  typedef struct T1_Edge_
+  {
+    T1_Pos  orus;
+    T1_Pos  pix;  
+  
+  } T1_Edge;
+
+
+/************************************************************************
+ *
+ * <Struct>
+ *    T1_Stem_Hint
+ *
+ * <Description>
+ *    A simple structure used to model a stem hint
+ *
+ * <Fields>
+ *    min_edge   :: the hint's minimum edge
+ *    max_edge   :: the hint's maximum edge
+ *    hint_flags :: some flags describing the stem properties
+ *
+ * <Note>
+ *    the min and max edges of a ghost stem have the same position,
+ *    even if they're coded in a weird way in the charstrings
+ *
+ ************************************************************************/
+
+  typedef struct T1_Stem_Hint_
+  {
+    T1_Edge  min_edge;
+    T1_Edge  max_edge;
+    T1_Int   hint_flags;
+
+  } T1_Stem_Hint;
+
+
+#define T1_HINT_FLAG_ACTIVE      1    /* indicates an active stem */
+#define T1_HINT_FLAG_MIN_BORDER  2    /* unused for now..         */
+#define T1_HINT_FLAG_MAX_BORDER  4    /* unused for now..         */
+
+
+/* hinter's configuration constants */
+#define T1_HINTER_MAX_BLUES    24    /* maximum number of blue zones      */
+#define T1_HINTER_MAX_SNAPS    16    /* maximum number of stem snap zones */
+#define T1_HINTER_MAX_EDGES    64    /* maximum number of stem hints      */
+
+
+/************************************************************************
+ *
+ * <Struct>
+ *   T1_Size_Hints
+ *
+ * <Description>
+ *   A structure used to model the hinting information related to
+ *   a size object
+ *
+ * <Fields>
+ *   supress_overshoots :: a boolean flag to tell when overshoot
+ *                         supression should occur.
+ *
+ *   num_blue_zones     :: the total number of blue zones (top+bottom)
+ *   num_bottom_zones   :: the number of bottom zones
+ *
+ *   blue_zones         :: the blue zones table. bottom zones are
+ *                         stored first in the table, followed by
+ *                         all top zones
+ *
+ *   num_stem_snapH     :: number of horizontal stem snap zones
+ *   stem_snapH         :: horizontal stem snap zones
+ *
+ *   num_stem_snapV     :: number of vertical stem snap zones
+ *   stem_snapV         :: vertical stem snap zones
+ *
+ ************************************************************************/
+
+  struct T1_Size_Hints_
+  {
+    T1_Bool       supress_overshoots;
+
+    T1_Int        num_blue_zones;
+    T1_Int        num_bottom_zones;
+    T1_Snap_Zone  blue_zones[ T1_HINTER_MAX_BLUES ];
+
+    T1_Int        num_snap_widths;
+    T1_Snap_Zone  snap_widths[ T1_HINTER_MAX_SNAPS ];
+
+    T1_Int        num_snap_heights;
+    T1_Snap_Zone  snap_heights[ T1_HINTER_MAX_SNAPS ];
+  };
+
+
+
+/************************************************************************
+ *
+ * <Struct>
+ *    T1_Stem_Table
+ *
+ * <Description>
+ *    A simple structure used to model a set of stem hints in a
+ *    single direction during the loading of a given glyph outline.
+ *    Not all stem hints are active at a time. Moreover, stems must
+ *    be sorted regularly
+ *
+ * <Fields>
+ *    num_stems   :: total number of stems in table
+ *    num_active  :: number of active stems in table
+ *
+ *    stems       :: the table of all stems
+ *    sort        :: a table of indices into the stems table, used
+ *                   to keep a sorted list of the active stems
+ *
+ ************************************************************************/
+
+  typedef struct T1_Stem_Table_
+  {
+    T1_Int        num_stems;
+    T1_Int        num_active;
+
+    T1_Stem_Hint  stems[ T1_HINTER_MAX_EDGES ];
+    T1_Int        sort [ T1_HINTER_MAX_EDGES ];
+
+  } T1_Stem_Table;
+
+
+
+/************************************************************************
+ *
+ * <Struct>
+ *   T1_Glyph_Hints
+ *
+ * <Description>
+ *   A structure used to model the stem hints of a given glyph outline
+ *   during glyph loading. 
+ *
+ * <Fields>
+ *   hori_stems  :: horizontal stem hints table
+ *   vert_stems  :: vertical stem hints table
+ *
+ ************************************************************************/
+
+  struct T1_Glyph_Hints_
+  {
+    T1_Stem_Table  hori_stems;
+    T1_Stem_Table  vert_stems;
+  };
+
+
+
+/************************************************************************
+ *
+ * <Data>
+ *    t1_hinter_funcs
+ *
+ * <Description>
+ *    A table containing the address of various functions used during
+ *    the loading of an hinted scaled outline
+ *
+ ************************************************************************/
+
+  LOCAL_DEF
+  const T1_Hinter_Funcs  t1_hinter_funcs;
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_New_Size_Hinter
+ *
+ * <Description>
+ *    Allocates a new hinter structure for a given size object
+ *
+ * <Input>
+ *    size :: handle to target size object
+ *
+ * <Return>
+ *    Error code. 0 means success
+ *
+ ************************************************************************/
+
+  LOCAL_DEF
+  T1_Error  T1_New_Size_Hinter( T1_Size  size );
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_Done_Size_Hinter
+ *
+ * <Description>
+ *    Releases a given size object's hinter structure
+ *
+ * <Input>
+ *    size :: handle to target size object
+ *
+ ************************************************************************/
+
+  LOCAL_DEF
+  void      T1_Done_Size_Hinter( T1_Size  size );
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_Reset_Size_Hinter
+ *
+ * <Description>
+ *    Recomputes hinting information when a given size object has
+ *    changed its resolutions/char sizes/pixel sizes
+ *
+ * <Input>
+ *    size :: handle to size object
+ *
+ * <Return>
+ *    Error code. 0 means success
+ *
+ ************************************************************************/
+
+  LOCAL_DEF
+  T1_Error  T1_Reset_Size_Hinter( T1_Size  size );
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_New_Glyph_Hinter
+ *
+ * <Description>
+ *    Allocates a new hinter structure for a given glyph slot
+ *
+ * <Input>
+ *    glyph :: handle to target glyph slot
+ *
+ * <Return>
+ *    Error code. 0 means success
+ *
+ ************************************************************************/
+
+  LOCAL_DEF
+  T1_Error  T1_New_Glyph_Hinter( T1_GlyphSlot  glyph );
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_Done_Glyph_Hinter
+ *
+ * <Description>
+ *    Releases a given glyph slot's hinter structure
+ *
+ * <Input>
+ *    glyph :: handle to glyph slot
+ *
+ ************************************************************************/
+
+  LOCAL_DEF
+  void      T1_Done_Glyph_Hinter( T1_GlyphSlot  glyph );
+
+
+
+
+/************************************************************************
+ *
+ * <Function>
+ *   T1_Hint_Points
+ *
+ * <Description>
+ *   this function grid-fits several points in a given Type 1 builder
+ *   at once. 
+ *
+ * <Input>
+ *   builder  :: handle to target Type 1 builder
+ *
+ ************************************************************************/
+
+  LOCAL_DEF
+  void  T1_Hint_Points( T1_Builder*  builder );
+
+
+/************************************************************************
+ *
+ * <Function>
+ *    T1_Hint_Stems
+ *
+ * <Description>
+ *    This function is used to compute the location of each stem hint
+ *    between the first and second passes of the glyph loader on the
+ *    charstring.
+ *
+ * <Input>
+ *    builder :: handle to target builder
+ *
+ ************************************************************************/
+
+  LOCAL_DEF
+  void  T1_Hint_Stems( T1_Builder*  builder );
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* T1HINTER_H */
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
new file mode 100644
index 0000000..de5a347
--- /dev/null
+++ b/src/type1/t1load.c
@@ -0,0 +1,1458 @@
+#include <ftdebug.h>
+
+#include <t1types.h>
+#include <t1encode.h>
+#include <t1tokens.h>
+#include <t1config.h>
+#include <t1parse.h>
+
+#include <stdio.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_t1load
+
+  typedef  T1_Error  (*T1_Parse_Func)( T1_Parser*  parser );
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> Init_T1_Parser                                             */
+/*                                                                       */
+/* <Description>                                                         */
+/*    Initialise a given parser object to build a given T1_Face          */
+/*                                                                       */
+/* <Input>                                                               */
+/*    parser  :: handle to the newly built parser object                 */
+/*    face    :: handle to target T1 face object                         */
+/*                                                                       */
+  LOCAL_FUNC
+  void  Init_T1_Parser( T1_Parser*    parser,
+                        T1_Face       face,
+                        T1_Tokenizer  tokenizer )
+  {
+    parser->error     = 0;
+    parser->face      = face;
+    parser->tokenizer = tokenizer;
+    parser->top       = parser->stack;
+    parser->limit     = parser->stack + T1_MAX_STACK_DEPTH;
+
+    parser->state_index    = 0;
+    parser->state_stack[0] = dict_none;
+
+	parser->encoding_type    = encoding_none;
+    parser->encoding_names   = 0;
+    parser->encoding_offsets = 0;
+    parser->encoding_lengths = 0;
+
+    parser->dump_tokens      = 0;
+    face->private_dict.lenIV = 4;  /* XXX : is it sure ?? */
+  }
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> Next_T1_Token                                              */
+/*                                                                       */
+/* <Description>                                                         */
+/*    grabs the next significant token from a parser's input stream.     */
+/*    this function ignores a number of tokens, and translates           */
+/*    alternate forms into their common ones..                           */
+/*                                                                       */
+/* <Input>                                                               */
+/*    parser  :: handle to source parser                                 */
+/*                                                                       */
+/* <Output>                                                              */
+/*    token   :: the extracted token descriptor                          */
+/*                                                                       */
+/* <Return>                                                              */
+/*    Error code. 0 means success                                        */
+/*                                                                       */
+  LOCAL_FUNC
+  T1_Error  Next_T1_Token( T1_Parser*  parser,
+                           T1_Token*   token )
+  {
+    T1_Error      error;
+    T1_Tokenizer  tokzer = parser->tokenizer;
+
+  L1:
+    error = Read_Token( tokzer );
+    if (error) return error;
+
+    /* We now must ignore a number of tokens like "dup", "executeonly", */
+    /* "readonly", etc...                                               */
+    *token = tokzer->token;
+    if ( token->kind == tok_keyword )
+      switch( token->kind2 )
+      {
+        case key_dup:
+        case key_execonly:
+        case key_readonly:
+        case key_noaccess:
+        case key_userdict:
+          /* do nothing - loop */
+          goto L1;
+
+        /* We also translate some other keywords from their alternative */
+        /* to their "normal" form..                                     */
+
+        case key_NP_alternate:
+          token->kind2 = key_NP;
+          break;
+
+        case key_RD_alternate:
+          token->kind2 = key_RD;
+          break;
+
+        case key_ND_alternate:
+          token->kind2 = key_ND;
+          break;
+
+        default:
+          ;
+      }
+
+    /* Dump the token when requested. This feature is only available */
+    /* in the 'error' and 'trace' debug levels..                     */
+#if defined( FT_DEBUG_LEVEL_ERROR ) || defined( FT_DEBUG_LEVEL_TRACE )
+    if ( parser->dump_tokens )
+    {
+      T1_String  temp_string[128];
+      T1_Int     len;
+
+      len = token->len;
+      if ( len > 127 ) len = 127;
+      strncpy( temp_string,
+               (T1_String*)tokzer->base + token->start,
+               len );
+      temp_string[len] = '\0';
+      FT_ERROR(( "%s\n", temp_string ));
+    }
+#endif
+
+    return T1_Err_Ok;
+  }
+
+
+
+  static
+  T1_Error  Expect_Keyword( T1_Parser*    parser,
+                            T1_TokenType  keyword )
+  {
+    T1_Token  token;
+    T1_Error  error;
+
+    error = Next_T1_Token( parser, &token );
+    if (error) goto Exit;
+
+    if ( token.kind  != tok_keyword ||
+         token.kind2 != keyword     )
+    {
+      error = T1_Err_Syntax_Error;
+      FT_ERROR(( "T1.Parse: keyword '%s' expected.\n",
+               t1_keywords[ keyword - key_first_ ] ));
+    }
+
+  Exit:
+    return error;
+  }
+
+
+
+  static
+  T1_Error  Expect_Keyword2( T1_Parser*    parser,
+                             T1_TokenType  keyword1,
+                             T1_TokenType  keyword2 )
+  {
+    T1_Token  token;
+    T1_Error  error;
+
+    error = Next_T1_Token( parser, &token );
+    if (error) goto Exit;
+
+    if ( token.kind  != tok_keyword  ||
+         ( token.kind2 != keyword1 &&
+           token.kind2 != keyword2 ) )
+    {
+      error = T1_Err_Syntax_Error;
+      FT_ERROR(( "T1.Parse: keyword '%s' or '%s' expected.\n",
+               t1_keywords[ keyword1 - key_first_ ],
+               t1_keywords[ keyword2 - key_first_ ] ));
+    }
+
+  Exit:
+    return error;
+  }
+
+
+
+  static
+  void  Parse_Encoding( T1_Parser*  parser )
+  {
+	T1_Token*     token  = parser->top+1;
+	FT_Memory     memory = parser->face->root.memory;
+	T1_Encoding*  encode = &parser->face->encoding;
+	T1_Error      error  = 0;
+
+	if (token->kind  == tok_keyword &&
+        (token->kind2 == key_StandardEncoding ||
+         token->kind2 == key_ExpertEncoding   )  )
+	{
+	  encode->num_chars  = 256;
+	  encode->code_first = 32;
+	  encode->code_last  = 255;
+
+	  if ( ALLOC_ARRAY( encode->char_index, 256, T1_Short ) )
+		goto Exit;
+
+	  encode->char_name = 0;  /* no need to store glyph names */
+
+	  /* Now copy the encoding */
+	  switch (token->kind2)
+	  {
+		  case key_ExpertEncoding : parser->encoding_type = encoding_expert;
+		  default                 : parser->encoding_type = encoding_standard; break;
+	  }
+    }
+	else
+	{
+	  FT_ERROR(( "T1.Parse_Encoding: invalid encoding type\n" ));
+	  error = T1_Err_Syntax_Error;
+    }
+
+  Exit:
+    parser->error = error;
+  }
+
+
+
+
+
+
+
+  /**********************************************************************/
+  /*                                                                    */
+  /*                                                                    */
+  /*        IMPLEMENTATION OF THE "DEF" KEYWORD DEPENDING ON            */
+  /*                     CURRENT DICTIONARY STATE                       */
+  /*                                                                    */
+  /*                                                                    */
+  /**********************************************************************/
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> Do_Def_Font                                                 */
+/*                                                                        */
+/* <Description>                                                          */
+/*    This function performs a 'def' when in the Font dictionary          */
+/*    Its purpose is to build the T1_Face attributes directly from        */
+/*    the stream..                                                        */
+/*                                                                        */
+/* <Input>                                                                */
+/*    parser :: handle to current parser.                                 */
+/*                                                                        */
+/* <Return>                                                               */
+/*    Error code. 0 means success                                         */
+/*                                                                        */
+  static
+  T1_Error  Do_Def_Font( T1_Parser*  parser )
+  {
+    T1_Token*  top   = parser->top;
+    T1_Face    face  = parser->face;
+
+    switch ( top[0].kind2 )
+    {
+      case imm_FontName:
+        /* in some cases, the /FontName is an immediate like  */
+        /* /TimesNewRoman. In this case, we simply copy the   */
+        /* token string (without the /)..                     */
+        if (top[1].kind == tok_immediate)
+        {
+          FT_Memory  memory = parser->tokenizer->memory;
+          T1_Error   error;
+          T1_Int     len = top[1].len;
+
+          if ( ALLOC( face->font_name, len+1 ) )
+          {
+            parser->error = error;
+            return error;
+          }
+
+          MEM_Copy( face->font_name,
+                    parser->tokenizer->base + top[1].start,
+                    len );
+          face->font_name[len] = '\0';
+        }
+        else
+          face->font_name = CopyString( parser );
+        break;
+
+      case imm_Encoding:
+        Parse_Encoding( parser );
+        break;
+
+      case imm_PaintType:
+        face->paint_type = (T1_Byte)CopyInteger( parser );
+        break;
+
+      case imm_FontType:
+        face->font_type = (T1_Byte)CopyInteger( parser );
+        break;
+
+      case imm_FontMatrix:
+        CopyMatrix( parser, &face->font_matrix );
+        break;
+
+      case imm_FontBBox:
+        CopyBBox( parser, &face->font_bbox );
+        break;
+
+      case imm_UniqueID:
+        face->unique_id = CopyInteger( parser );
+        break;
+
+      case imm_StrokeWidth:
+        face->stroke_width = CopyInteger( parser );
+        break;
+
+      case imm_FontID:
+        face->font_id = CopyInteger( parser );
+        break;
+
+      default:
+        /* ignore all other things */
+        parser->error = T1_Err_Ok;
+    }
+    return parser->error;
+  }
+
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> Do_Def_FontInfo                                             */
+/*                                                                        */
+/* <Description>                                                          */
+/*    This function performs a 'def' when in the FontInfo dictionary      */
+/*    Its purpose is to build the T1_FontInfo structure directly from     */
+/*    the stream..                                                        */
+/*                                                                        */
+/* <Input>                                                                */
+/*    parser :: handle to current parser.                                 */
+/*                                                                        */
+/* <Return>                                                               */
+/*    Error code. 0 means success                                         */
+/*                                                                        */
+  static
+  T1_Error  Do_Def_FontInfo( T1_Parser*  parser )
+  {
+    T1_Token*     top   = parser->top;
+    T1_FontInfo*  info  = &parser->face->font_info;
+
+    switch ( top[0].kind2 )
+    {
+      case imm_version:
+        info->version = CopyString( parser );
+        break;
+
+      case imm_Notice:
+        info->notice = CopyString( parser );
+        break;
+
+      case imm_FullName:
+        info->full_name = CopyString( parser );
+        break;
+
+      case imm_FamilyName:
+        info->family_name = CopyString( parser );
+        break;
+
+      case imm_Weight:
+        info->weight = CopyString( parser );
+        break;
+
+      case imm_ItalicAngle:
+        info->italic_angle = CopyInteger( parser );
+        break;
+
+      case imm_isFixedPitch:
+        info->is_fixed_pitch = CopyBoolean( parser );
+        break;
+
+      case imm_UnderlinePosition:
+        info->underline_position = (T1_Short)CopyInteger( parser );
+        break;
+
+      case imm_UnderlineThickness:
+        info->underline_thickness = (T1_Short)CopyInteger( parser );
+        break;
+
+      default:
+        /* ignore all other things */
+        parser->error = T1_Err_Ok;
+    }
+    return parser->error;
+  }
+
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> Do_Def_Private                                              */
+/*                                                                        */
+/* <Description>                                                          */
+/*    This function performs a 'def' when in the Private dictionary       */
+/*    Its purpose is to build the T1_Private structure directly from      */
+/*    the stream..                                                        */
+/*                                                                        */
+/* <Input>                                                                */
+/*    parser :: handle to current parser.                                 */
+/*                                                                        */
+/* <Return>                                                               */
+/*    Error code. 0 means success                                         */
+/*                                                                        */
+  static
+  T1_Error  Do_Def_Private( T1_Parser*  parser )
+  {
+    T1_Token*     top   = parser->top;
+    T1_Private*   priv  = &parser->face->private_dict;
+
+    switch ( top[0].kind2 )
+    {
+      case imm_RD: case imm_RD_alternate:    /* Ignore the definitions  */
+      case imm_ND: case imm_ND_alternate:    /* of RD, NP, ND and their */
+      case imm_NP: case imm_NP_alternate:    /* alternate forms ...     */
+        parser->error = T1_Err_Ok;
+        break;
+
+
+      case imm_BlueValues:
+        CopyArray( parser, &priv->num_blues,
+                   priv->blue_values, 14 );
+        break;
+
+
+      case imm_OtherBlues:
+        CopyArray( parser, &priv->num_other_blues,
+                   priv->other_blues, 10 );
+        break;
+
+
+      case imm_FamilyBlues:
+        CopyArray( parser, &priv->num_family_blues,
+                   priv->family_blues, 14 );
+        break;
+
+
+      case imm_FamilyOtherBlues:
+        CopyArray( parser, &priv->num_family_other_blues,
+                   priv->family_other_blues, 10 );
+        break;
+
+
+      case imm_BlueScale:
+        priv->blue_scale = CopyFloat( parser, 0x10000 );
+        break;
+
+
+      case imm_BlueShift:
+        priv->blue_shift = CopyInteger( parser );
+        break;
+
+
+      case imm_BlueFuzz:
+        priv->blue_fuzz = CopyInteger( parser );
+        break;
+
+
+      case imm_StdHW:
+        CopyArray( parser, 0, (T1_Short*)&priv->standard_width, 1 );
+        break;
+
+
+      case imm_StdVW:
+        CopyArray( parser, 0, (T1_Short*)&priv->standard_height, 1 );
+        break;
+
+
+      case imm_StemSnapH:
+        CopyArray( parser, &priv->num_snap_widths,
+                   priv->stem_snap_widths, 12 );
+        break;
+
+
+      case imm_StemSnapV:
+        CopyArray( parser, &priv->num_snap_heights,
+                   priv->stem_snap_heights, 12 );
+        break;
+
+
+      case imm_ForceBold:
+        priv->force_bold = CopyBoolean( parser );
+        break;
+
+
+      case imm_LanguageGroup:
+        priv->language_group = CopyInteger( parser );
+        break;
+
+
+      case imm_password:
+        priv->password = CopyInteger( parser );
+        break;
+
+
+      case imm_UniqueID:
+        priv->unique_id = CopyInteger( parser );
+        break;
+
+
+      case imm_lenIV:
+        priv->lenIV = CopyInteger( parser );
+        break;
+
+
+      case imm_MinFeature:
+        CopyArray( parser, 0, priv->min_feature, 2 );
+        break;
+
+
+      default:
+        /* ignore all other things */
+        parser->error = T1_Err_Ok;
+    }
+    return parser->error;
+  }
+
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> Do_Def_Error                                                */
+/*                                                                        */
+/* <Description>                                                          */
+/*    This function returns a simple syntax error when invoked. It is     */
+/*    ued for the "def" keyword when in the "encoding", "subrs",          */
+/*    "othersubrs" and "charstrings" dictionary states..                  */
+/*                                                                        */
+/* <Input>                                                                */
+/*    parser :: handle to current parser.                                 */
+/*                                                                        */
+/* <Return>                                                               */
+/*    Error code. 0 means success                                         */
+/*                                                                        */
+  static
+  T1_Error  Do_Def_Error( T1_Parser*  parser )
+  {
+    FT_ERROR(( "T1.Load : 'def' keyword encountered in bad dictionary/array\n" ));
+    parser->error = T1_Err_Syntax_Error;
+    return parser->error;
+  }
+
+
+  static
+  T1_Error  Do_Def_Ignore( T1_Parser*  parser )
+  {
+    (void)parser;
+    return T1_Err_Ok;
+  }
+
+  static
+  T1_Parse_Func   def_funcs[ dict_max ] =
+  {
+    Do_Def_Error,
+    Do_Def_Font,
+    Do_Def_FontInfo,
+    Do_Def_Ignore,
+    Do_Def_Private,
+    Do_Def_Ignore,
+    Do_Def_Ignore,
+    Do_Def_Ignore,
+    Do_Def_Ignore,
+    Do_Def_Ignore,
+    Do_Def_Ignore,
+  };
+
+
+  /**********************************************************************/
+  /*                                                                    */
+  /*                                                                    */
+  /*        IMPLEMENTATION OF THE "PUT" KEYWORD DEPENDING ON            */
+  /*                     CURRENT DICTIONARY STATE                       */
+  /*                                                                    */
+  /*                                                                    */
+  /**********************************************************************/
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> Do_Put_Encoding                                             */
+/*                                                                        */
+/* <Description>                                                          */
+/*    This function performs a 'put' when in the Encoding array           */
+/*    The glyph name is copied into the T1 recorder, and the charcode     */
+/*    and glyph name pointer are written into the face object encoding    */
+/*                                                                        */
+/* <Input>                                                                */
+/*    parser :: handle to current parser.                                 */
+/*                                                                        */
+/* <Return>                                                               */
+/*    Error code. 0 means success                                         */
+/*                                                                        */
+  static
+  T1_Error  Do_Put_Encoding( T1_Parser*  parser )
+  {
+    T1_Error      error  = T1_Err_Ok;
+    T1_Face       face   = parser->face;
+    T1_Token*     top    = parser->top;
+    T1_Encoding*  encode = &face->encoding;
+    T1_Int        index;
+
+    /* record and check the character code */
+    if ( top[0].kind != tok_number )
+    {
+      FT_TRACE4(( "T1.Parse.put: number expected\n" ));
+      goto Syntax_Error;
+    }
+    index = (T1_Int)CopyInteger( parser );
+    if (parser->error) return parser->error;
+
+    if ( index < 0 || index >= encode->num_chars )
+    {
+      FT_TRACE4(( "T1.Parse.put: invalid character code\n" ));
+      goto Syntax_Error;
+    }
+
+    /* record the immediate name */
+    if ( top[1].kind != tok_immediate )
+    {
+      FT_TRACE4(( "T1.Parse.put: immediate name expected\n" ));
+      goto Syntax_Error;
+    }
+
+    /* if the glyph name is '.notdef', store a NULL char name */
+    /* otherwise, record the glyph name..                     */
+    if ( top[1].kind == imm_notdef )
+    {
+      parser->table.elements[ index ] = 0;
+      parser->table.lengths [ index ] = 0;
+    }
+    else
+    {
+      T1_String  temp_name[128];
+      T1_Token*  token = top+1;
+      T1_Int     len   = token->len-1;
+
+      /* copy immediate name */
+      if (len > 127) len = 127;
+      MEM_Copy( temp_name, parser->tokenizer->base + token->start+1, len );
+      temp_name[len] = '\0';
+
+      error = T1_Add_Table( &parser->table, index, (T1_Byte*)temp_name, len+1 );
+
+	  /* adjust code_first and code_last */
+	  if ( index < encode->code_first )  encode->code_first = index;
+	  if ( index > encode->code_last  )  encode->code_last  = index;
+    }
+    return error;
+
+  Syntax_Error:
+    /* ignore the error, and simply clear the stack */
+    FT_TRACE4(( "T1.Put.Encoding: invalid syntax encountered\n" ));
+    parser->top = parser->stack;
+    return T1_Err_Ok;
+  }
+
+  /**********************************************************************/
+  /*                                                                    */
+  /*                                                                    */
+  /*        IMPLEMENTATION OF THE "RD" KEYWORD DEPENDING ON             */
+  /*                     CURRENT DICTIONARY STATE                       */
+  /*                                                                    */
+  /*                                                                    */
+  /**********************************************************************/
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> Do_RD_Subrs                                                 */
+/*                                                                        */
+/* <Description>                                                          */
+/*    This function performs a 'RD' when in the Subrs dictionary          */
+/*    It simply records the array of bytecodes/charstrings corresponding  */
+/*    to the sub-routine..                                                */
+/*                                                                        */
+/* <Input>                                                                */
+/*    parser :: handle to current parser.                                 */
+/*                                                                        */
+/* <Return>                                                               */
+/*    Error code. 0 means success                                         */
+/*                                                                        */
+  static
+  T1_Error  Do_RD_Subrs( T1_Parser*  parser )
+  {
+    T1_Error      error  = T1_Err_Ok;
+    T1_Face       face   = parser->face;
+    T1_Token*     top    = parser->top;
+    T1_Tokenizer  tokzer = parser->tokenizer;
+    T1_Int        index, count;
+
+    /* record and check the character code */
+    if ( top[0].kind != tok_number ||
+         top[1].kind != tok_number )
+    {
+      FT_ERROR(( "T1.Parse.put: number expected\n" ));
+      goto Syntax_Error;
+    }
+    index = (T1_Int)CopyInteger( parser );
+    error = parser->error; if (error) goto Exit;
+
+    count = (T1_Int)CopyInteger( parser );
+    error = parser->error; if (error) goto Exit;
+
+    if ( index < 0 || index >= face->num_subrs )
+    {
+      FT_ERROR(( "T1.Parse.put: invalid character code\n" ));
+      goto Syntax_Error;
+    }
+
+    /* decrypt charstring and skip them */
+    {
+      T1_Byte*  base = tokzer->base + tokzer->cursor;
+
+      t1_decrypt( base, count, 4330 );
+      tokzer->cursor += count;
+
+      base  += face->private_dict.lenIV;
+      count -= face->private_dict.lenIV;
+
+      error = T1_Add_Table( &parser->table, index, base, count );
+    }
+
+    /* consume the closing NP or 'put' */
+    error = Expect_Keyword2( parser, key_NP, key_put );
+
+  Exit:
+    return error;
+
+  Syntax_Error:
+    return T1_Err_Syntax_Error;
+  }
+
+
+/**************************************************************************/
+/*                                                                        */
+/* <Function> Do_RD_CharStrings                                           */
+/*                                                                        */
+/* <Description>                                                          */
+/*    This function performs a 'RD' when in the CharStrings dictionary    */
+/*    It simply records the array of bytecodes/charstrings corresponding  */
+/*    to the glyph program string.                                        */
+/*                                                                        */
+/* <Input>                                                                */
+/*    parser :: handle to current parser.                                 */
+/*                                                                        */
+/* <Return>                                                               */
+/*    Error code. 0 means success                                         */
+/*                                                                        */
+  static
+  T1_Error  Do_RD_Charstrings( T1_Parser*  parser )
+  {
+    T1_Error      error = T1_Err_Ok;
+    T1_Face       face  = parser->face;
+    T1_Token*     top   = parser->top;
+    T1_Tokenizer  tokzer = parser->tokenizer;
+    T1_Int        index, count;
+
+    /* check the character name argument */
+    if ( top[0].kind != tok_immediate )
+    {
+      FT_ERROR(( "T1.Parse.RD: immediate character name expected\n" ));
+      goto Syntax_Error;
+    }
+
+    /* check the count argument */
+    if ( top[1].kind != tok_number )
+    {
+      FT_ERROR(( "T1.Parse.put: number expected\n" ));
+      goto Syntax_Error;
+    }
+	parser->args++;
+    count = (T1_Int)CopyInteger( parser );
+    error = parser->error; if (error) goto Exit;
+
+    /* record the glyph name and get the corresponding glyph index */
+    if ( top[0].kind2 == imm_notdef )
+      index = 0;
+    else
+    {
+      T1_String  temp_name[128];
+      T1_Token*  token = top;
+      T1_Int     len   = token->len-1;
+
+      /* copy immediate name */
+      if (len > 127) len = 127;
+      MEM_Copy( temp_name, parser->tokenizer->base + token->start+1, len );
+      temp_name[len] = '\0';
+
+      index = parser->cur_name++;
+      error = T1_Add_Table( &parser->table, index*2, (T1_Byte*)temp_name, len+1 );
+      if (error) goto Exit;
+    }
+
+    /* decrypt and record charstring, then skip them */
+    {
+      T1_Byte*  base = tokzer->base + tokzer->cursor;
+
+      t1_decrypt( base, count, 4330 );
+      tokzer->cursor += count;  /* skip */
+
+      base  += face->private_dict.lenIV;
+      count -= face->private_dict.lenIV;
+
+      error = T1_Add_Table( &parser->table, index*2+1, base, count );
+    }
+
+    /* consume the closing ND */
+    if (!error)
+      error = Expect_Keyword( parser, key_ND );
+
+  Exit:
+    return error;
+
+  Syntax_Error:
+    return T1_Err_Syntax_Error;
+  }
+
+
+
+
+
+
+  static
+  T1_Error  Expect_Dict_Arguments( T1_Parser*    parser,
+                                   T1_Int        num_args,
+                                   T1_TokenType  immediate,
+                                   T1_DictState  new_state,
+                                   T1_Int       *count )
+  {
+    /* check that we have enough arguments in the stack, including */
+    /* the 'dict' keyword..                                        */
+    if ( parser->top - parser->stack < num_args )
+    {
+      FT_ERROR(( "T1.Parse.Dict : expecting at least %d arguments",
+               num_args ));
+      goto Syntax_Error;
+    }
+
+    /* check that we have the correct immediate, if needed */
+    if ( num_args == 2 )
+    {
+      if ( parser->top[-2].kind  != tok_immediate ||
+           parser->top[-2].kind2 != immediate     )
+      {
+        FT_ERROR(( "T1.Parse.Dict : expecting '/%s' dictionary\n",
+                 t1_immediates[ immediate - imm_first_ ] ));
+        goto Syntax_Error;
+      }
+    }
+
+	parser->args = parser->top-1;
+
+    /* check that the count argument is a number */
+    if ( parser->args->kind != tok_number )
+    {
+      FT_ERROR(( "T1.Parse.Dict : expecting numerical count argument for 'dict'\n" ));
+      goto Syntax_Error;
+    }
+    if (count)
+    {
+      *count = CopyInteger( parser );
+      if (parser->error) return parser->error;
+    }
+
+    /* save the dictionary state */
+    parser->state_stack[ ++parser->state_index ] = new_state;
+
+    /* consume the 'begin' keyword, and clear the stack */
+    parser->top -= num_args;
+    return Expect_Keyword( parser, key_begin );
+
+  Syntax_Error:
+    return T1_Err_Syntax_Error;
+  }
+
+
+
+
+
+  static
+  T1_Error  Expect_Array_Arguments( T1_Parser*  parser )
+  {
+    T1_Token*     top   = parser->top;
+    T1_Error      error = T1_Err_Ok;
+    T1_DictState  new_state;
+    T1_Int        count;
+    T1_Face       face   = parser->face;
+    FT_Memory     memory = face->root.memory;
+
+    /* Check arguments format */
+    if ( top - parser->stack < 2 )
+    {
+      FT_ERROR(( "T1.Parse.array: two arguments expected\n" ));
+      error = T1_Err_Stack_Underflow;
+      goto Exit;
+    }
+
+    parser->top -= 2;
+    top         -= 2;
+	parser->args = top + 1;
+
+    if ( top[0].kind != tok_immediate )
+    {
+      FT_ERROR(( "T1.Parse.array: first argument must be an immediate name\n" ));
+      goto Syntax_Error;
+    }
+
+    if ( top[1].kind != tok_number )
+    {
+      FT_ERROR(( "T1.Parse.array: second argument must be a number\n" ));
+      goto Syntax_Error;
+    }
+    count = (T1_Int)CopyInteger( parser );
+
+    /* Is this an array we know about ?? */
+    switch ( top[0].kind2 )
+    {
+      case imm_Encoding:
+        {
+          T1_Encoding*  encode = &face->encoding;
+
+          new_state = dict_encoding;
+
+          encode->code_first = count;
+          encode->code_last  = 0;
+          encode->num_chars  = count;
+
+          /* allocate the table of character indexes. The table of */
+          /* character names is allocated through init_t1_recorder */
+          if ( ALLOC_ARRAY( encode->char_index, count, T1_Short   ) )
+            return error;
+
+          error = T1_New_Table( &parser->table, count, memory );
+          if (error) goto Exit;
+
+		  parser->encoding_type = encoding_array;
+        }
+        break;
+
+
+      case imm_Subrs:
+        {
+          new_state       = dict_subrs;
+          face->num_subrs = count;
+
+          error = T1_New_Table( &parser->table, count, memory );
+          if (error) goto Exit;
+        }
+        break;
+
+
+      case imm_CharStrings:
+        new_state        = dict_charstrings;
+        break;
+
+
+      default:
+        new_state = dict_unknown_array;
+    }
+    parser->state_stack[ ++parser->state_index ] = new_state;
+
+  Exit:
+    return error;
+
+  Syntax_Error:
+    return T1_Err_Syntax_Error;
+  }
+
+
+
+
+  static
+  T1_Error  Finalise_Parsing( T1_Parser*  parser )
+  {
+    T1_Face    face       = parser->face;
+    FT_Memory  memory     = face->root.memory;
+    T1_Table*  strings    = &parser->table;
+	T1_Int     num_glyphs;
+	T1_Int     n;
+	T1_Error   error;
+
+    num_glyphs = face->num_glyphs = parser->cur_name;
+
+	/* allocate glyph names and charstrings arrays */
+	if ( ALLOC_ARRAY( face->glyph_names    , num_glyphs, T1_String* ) ||
+		 ALLOC_ARRAY( face->charstrings    , num_glyphs, T1_Byte* )   ||
+	     ALLOC_ARRAY( face->charstrings_len, num_glyphs, T1_Int*  )   )
+	  return error;
+
+	/* copy glyph names and charstrings offsets and lengths */
+    face->charstrings_block = strings->block;
+	for ( n = 0; n < num_glyphs; n++ )
+	{
+	  face->glyph_names[n]     = (T1_String*)strings->elements[2*n];
+	  face->charstrings[n]     = strings->elements[2*n+1];
+	  face->charstrings_len[n] = strings->lengths [2*n+1];
+    }
+
+	/* now free the old tables */
+	FREE( strings->elements );
+	FREE( strings->lengths );
+
+	/* Compute encoding if required. */
+	if (parser->encoding_type == encoding_none)
+    {
+	  FT_ERROR(( "T1.Parse.Finalise : no encoding specified in font file\n" ));
+	  return T1_Err_Syntax_Error;
+    }
+
+	{
+	  T1_Int        n;
+	  T1_Encoding*  encode = &face->encoding;
+
+	  encode->code_first = encode->num_chars-1;
+	  encode->code_last  = 0;
+
+	  for ( n = 0; n < encode->num_chars; n++ )
+	  {
+		T1_String** names;
+		T1_Int      index;
+		T1_Int      m;
+
+		switch (parser->encoding_type)
+		{
+		  case encoding_standard:
+			  index = t1_standard_encoding[n];
+			  names = (T1_String**)t1_standard_strings;
+			  break;
+
+		  case encoding_expert:
+			  index = t1_expert_encoding[n];
+			  names = (T1_String**)t1_standard_strings;
+			  break;
+
+		  default:
+		      index = n;
+			  names = (T1_String**)parser->encoding_offsets;
+		}
+		encode->char_index[n] = 0;
+		if (index)
+		{
+		  T1_String*  name = names[index];
+
+		  if ( name )
+		  {
+            T1_Int  len = strlen(name);
+
+            /* lookup glyph index from name */
+            for ( m = 0; m < num_glyphs; m++ )
+   		    {
+		  	  if ( strncmp( face->glyph_names[m], name, len ) == 0 )
+			  {
+			    encode->char_index[n] = m;
+			    break;
+		      }
+		    }
+
+		    if ( n < encode->code_first ) encode->code_first = n;
+		    if ( n > encode->code_last  ) encode->code_last  = n;
+	      }
+	    }
+	  }
+
+	  parser->encoding_type = encoding_none;
+	  FREE( parser->encoding_names );
+	  FREE( parser->encoding_lengths );
+	  FREE( parser->encoding_offsets );
+    }
+
+    return T1_Err_Ok;
+  }
+
+
+
+
+
+  LOCAL_FUNC
+  T1_Error  Parse_T1_FontProgram( T1_Parser*  parser )
+  {
+    T1_Error  error;
+
+    for (;;)
+    {
+      T1_Token      token;
+      T1_Token*     top;
+      T1_DictState  dict_state;
+      T1_Int        dict_index;
+
+      error      = Next_T1_Token( parser, &token );
+      top        = parser->top;
+      dict_index = parser->state_index;
+      dict_state = parser->state_stack[ dict_index ];
+
+      switch ( token.kind )
+      {
+        /* A keyword was detected */
+        case tok_keyword:
+          switch (token.kind2)
+          {
+            case key_dict:
+
+              switch (dict_state)
+              {
+                case dict_none:
+                   /* All right, we're beggining the font dictionary    */
+                   /* check that we only have one number argument, then */
+                   /* consume the 'begin' and change to 'dict_font'     */
+                   /* state..                                           */
+                   error = Expect_Dict_Arguments( parser, 1, tok_error,
+                                                  dict_font, 0 );
+                   if (error) goto Exit;
+                   
+                   /* clear stack from all the previous content. This   */
+                   /* could be some stupid Postscript code ...          */
+                   parser->top = parser->stack;
+                   break;
+
+
+                case dict_font:
+                   /* This must be the /FontInfo dictionary, so check */
+                   /* That we have at least two arguments, that they  */
+                   /* are "/FontInfo" and a number, then change the   */
+                   /* dictionary state..                              */
+                   error = Expect_Dict_Arguments( parser, 2, imm_FontInfo,
+                                                  dict_fontinfo, 0 );
+                   if (error) goto Exit;
+                   break;
+
+
+                case dict_none2:
+                   error = Expect_Dict_Arguments( parser, 2, imm_Private,
+                                                  dict_private, 0 );
+                   if (error) goto Exit;
+                   break;
+
+
+                case dict_private:
+                  {
+                    T1_Face  face = parser->face;
+                    T1_Int   count;
+
+                    error = Expect_Dict_Arguments( parser, 2, imm_CharStrings,
+                                                   dict_charstrings, &count );
+                    if (error) goto Exit;
+
+                    face->num_glyphs = count;
+                    error = T1_New_Table( &parser->table, count*2, face->root.memory );
+                    if (error) goto Exit;
+
+                    /* record '.notdef' as the first glyph in the font */
+                    error = T1_Add_Table( &parser->table, 0, (T1_Byte*)".notdef", 8 );
+                    parser->cur_name = 1;
+                    /* XXXXX : DO SOMETHING HERE */
+                  }
+                  break;
+
+                default:
+                   /* All other uses are invalid */
+                   FT_ERROR(( "T1.Parse: invalid use of the 'dict' keyword\n" ));
+                   goto Syntax_Error;
+              }
+              break;
+
+
+            case key_array:
+              /* Are we in an array yet ? Is so, raise an error */
+              switch (dict_state)
+              {
+                case dict_encoding:   case dict_subrs:
+                case dict_othersubrs: case dict_charstrings:
+                case dict_unknown_array:
+                  FT_ERROR(( "T1.Parse.array: nested array definitions\n" ));
+                  goto Syntax_Error;
+
+                default:
+                  ;
+              }
+              error = Expect_Array_Arguments( parser );
+              if (error) goto Exit;
+              break;
+
+
+            case key_ND:
+            case key_NP:
+            case key_def:
+              /* Are we in an array ? If so, finalise it.. */
+              switch ( dict_state )
+              {
+                case dict_encoding:    /* finish encoding array */
+                  {
+                    /* copy table names to the face object */
+                    T1_Done_Table( &parser->table );
+
+                    parser->encoding_names   = parser->table.block;
+                    parser->encoding_lengths = parser->table.lengths;
+                    parser->encoding_offsets = parser->table.elements;
+
+                    parser->state_index--;
+                  }
+                  break;
+
+
+                case dict_subrs:
+                  {
+                    T1_Face  face = parser->face;
+
+                    /* copy recorder sub-routines */
+                    T1_Done_Table( &parser->table );
+
+                    parser->subrs   = parser->table.block;
+                    face->subrs     = parser->table.elements;
+                    face->subrs_len = parser->table.lengths;
+
+                    parser->state_index--;
+                  }
+                  break;
+
+                case dict_charstrings:
+                case dict_othersubrs:
+                case dict_unknown_array:
+                  FT_ERROR(( "T1.Parser.def: unsupported array\n" ));
+                  goto Syntax_Error;
+                  break;
+
+                default:   /* normal 'def' processing */
+                  {
+                    /* Check that we have sufficient operands in the stack */
+                    if ( top >= parser->stack+2 )
+                    {
+                      /* Now check that the first operand is an immediate */
+                      /* If so, call the appropriate "def" routine based  */
+                      /* on the current parser state..                    */
+                      if ( top[-2].kind == tok_immediate )
+                      {
+                        parser->top -= 2;
+						parser->args = parser->top + 1;
+                        error = def_funcs[dict_state](parser);
+                      }
+                      else
+                      {
+                        /* This is an error, but some fonts contain some */
+                        /* stupid Postscript code. We simply ignore      */
+                        /* an invalid 'def' by clearing the stack        */
+#if 0
+                        FT_ERROR(( "T1.Parse.def: immediate expected\n" ));
+                        goto Syntax_Error;
+#else
+                        parser->top = parser->stack;
+#endif
+                      }
+                    }
+                    else
+                    {
+                      FT_ERROR(( "T1.Parse.def: not enough arguments\n" ));
+                      goto Stack_Underflow;
+                    }
+                  }
+              }
+              break;
+
+
+
+            case key_index:
+              if ( top <= parser->stack )
+              {
+                FT_ERROR(( "T1.Parse.index: not enough arguments\n" ));
+                goto Stack_Underflow;
+              }
+
+              /* simply ignore ?? */
+              parser->top --;
+              break;
+
+
+            case key_put:
+              /* Check that we have sufficient operands in stack */
+              if ( top < parser->stack+2 )
+              {
+                FT_ERROR(( "T1.Parse.put: not enough arguments\n" ));
+                goto Stack_Underflow;
+              }
+
+              parser->top -= 2;
+			  parser->args = parser->top;
+              switch (dict_state)
+              {
+                case dict_encoding:
+                  error = Do_Put_Encoding( parser );
+                  if (error) goto Exit;
+                  break;
+
+                case dict_unknown_array:   /* ignore the put */
+                  break;
+
+                default:
+#if 0
+                  FT_ERROR(( "T1.Parse.put: invalid context\n" ));
+                  goto Syntax_Error;
+#else
+                  /* invalid context, simply ignore the put and */
+                  /* clear the stack (stupid Postscript code..) */
+                  FT_TRACE4(( "T1.Parse.put: invalid context. ignored.\n" ));
+                  parser->top = parser->stack;
+#endif
+              }
+              break;
+
+
+
+            case key_RD:
+              /* Check that we have sufficient operands in stack */
+              if ( top < parser->stack+2 )
+              {
+                FT_ERROR(( "T1.Parse.RD: not enough arguments\n" ));
+                goto Stack_Underflow;
+              }
+
+              parser->top -= 2;
+			  parser->args = parser->top;
+              switch (dict_state)
+              {
+                case dict_subrs:
+                  error = Do_RD_Subrs( parser );
+                  if (error) goto Exit;
+                  break;
+
+                case dict_charstrings:
+                  error = Do_RD_Charstrings( parser );
+                  if (error) goto Exit;
+                  break;
+
+                default:
+                  FT_ERROR(( "T1.Parse.RD: invalid context\n" ));
+                  goto Syntax_Error;
+              }
+              break;
+
+
+
+            case key_end:
+              /* Were we in a dictionary or in an array ? */
+              if ( dict_index <= 0 )
+              {
+                FT_ERROR(( "T1.Parse.end: no dictionary defined\n" ));
+                goto Syntax_Error;
+              }
+
+              switch (dict_state)
+              {
+                /* Jump to the private dictionary if we're closing the */
+                /* /Font dictionary..                                  */
+                case dict_font:
+                  goto Open_Private;
+
+                /* Exit the parser when closing the CharStrings dictionary */
+                case dict_charstrings:
+                  return Finalise_Parsing( parser );
+
+                default:
+                  /* Pop the current dictionary state and return to previous */
+                  /* one. Consume the "def"..                                */
+
+                  /* Because some buggy fonts (BitStream) have incorrect     */
+                  /* syntax, we never escape from the private dictionary     */
+                  if (dict_state != dict_private)
+                    parser->state_index--;
+               
+                  error = Expect_Keyword2( parser, key_def, key_put );
+                  if (error) goto Exit;
+              }
+              break;
+
+
+
+            case key_for:
+              /* check that we have four arguments, and simply */
+              /* ignore them..                                 */
+              if ( top - parser->stack < 4 )
+              {
+                FT_ERROR(( "T1.Parse.for: not enough arguments\n" ));
+                goto Stack_Underflow;
+              }
+
+              parser->top -= 4;
+              break;
+
+
+
+            case key_currentdict:
+
+          Open_Private:
+               parser->state_index    = 0;
+               parser->state_stack[0] = dict_none2;
+               error = Open_PrivateDict( parser->tokenizer );
+               if (error) goto Exit;
+               break;
+
+
+            case key_true:
+            case key_false:
+			case key_StandardEncoding:
+			case key_ExpertEncoding:
+              goto Push_Element;
+
+
+            default:
+			  FT_ERROR(( "T1.Parser: invalid keyword in context\n" ));
+              error = T1_Err_Syntax_Error;
+          }
+          break;
+
+        /* A number was detected */
+        case tok_string:
+        case tok_program:
+        case tok_immediate:
+        case tok_array:
+        case tok_hexarray:
+        case tok_any:
+        case tok_number:                        /* push number on stack */
+
+     Push_Element:
+          if ( top >= parser->limit )
+          {
+            error = T1_Err_Stack_Overflow;
+            goto Exit;
+          }
+          else
+            *parser->top++ = token;
+          break;
+
+        /* anything else is an error per se the spec, but we     */
+        /* frequently encountre stupid postscript code in fonts, */
+        /* so just ignore them..                                 */
+        default:
+          error = T1_Err_Ok;  /* ignore token */
+      }
+
+      if (error)
+        return error;
+    }
+  Exit:
+    return error;
+
+  Syntax_Error:
+    return T1_Err_Syntax_Error;
+
+  Stack_Underflow:
+    return T1_Err_Stack_Underflow;
+  }
+
diff --git a/src/type1/t1load.h b/src/type1/t1load.h
new file mode 100644
index 0000000..9e0ee47
--- /dev/null
+++ b/src/type1/t1load.h
@@ -0,0 +1,72 @@
+/*******************************************************************
+ *
+ *  t1load.h                                                    1.0
+ *
+ *    Type1 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.
+ *
+ ******************************************************************/
+
+#ifndef T1LOAD_H
+#define T1LOAD_H
+
+#include <ftstream.h>
+#include <t1parse.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function> Init_T1_Parser                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initialise a given parser object to build a given T1_Face          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    parser  :: handle to the newly built parser object                 */
+  /*    face    :: handle to target T1 face object                         */
+  /*                                                                       */
+   LOCAL_DEF
+   void  Init_T1_Parser( T1_Parser*    parser,
+                         T1_Face       face,
+                         T1_Tokenizer  tokenizer );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function> Parse_T1_FontProgram                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Parses a given Type 1 font file and builds its face object         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    parser  :: handle to target parser object                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Error code. 0 means success..                                      */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The parser contains a handle to the target face object.            */
+  /*                                                                       */
+   LOCAL_DEF
+   T1_Error  Parse_T1_FontProgram( T1_Parser*  parser );
+
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* T1LOAD_H */
+
+
+/* END */
diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c
new file mode 100644
index 0000000..88d77f5
--- /dev/null
+++ b/src/type1/t1objs.c
@@ -0,0 +1,414 @@
+/*******************************************************************
+ *
+ *  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 <ftdebug.h>
+#include <ftstream.h>
+
+#include <t1gload.h>
+#include <t1load.h>
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+#include <t1hinter.h>
+#endif
+
+/* Required by tracing mode */
+#undef   FT_COMPONENT
+#define  FT_COMPONENT  trace_t1objs
+
+/*******************************************************************
+ *                                                                 *
+ *                         SIZE  FUNCTIONS                         *
+ *                                                                 *
+ *                                                                 *
+ *******************************************************************/
+
+/*******************************************************************
+ *
+ * <Function>  T1_Done_Size
+ *
+ * <Description>
+ *    The TrueDoc instance object destructor. Used to discard
+ *    a given instance object..
+ *
+ * <Input>
+ *    instance   :: handle to the target instance object
+ *
+ * <Return>
+ *    TrueDoc error code. 0 means success
+ *
+ ******************************************************************/
+
+  LOCAL_FUNC
+  void  T1_Done_Size( T1_Size  size )
+  {
+    if (size)
+    {
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+      T1_Done_Size_Hinter( size );
+#endif
+      size->valid = 0;
+    }
+  }
+
+
+/*******************************************************************
+ *
+ *  <Function> T1_Init_Size
+ *
+ *  <Description>
+ *     The instance object constructor
+ *
+ *  <Input>
+ *     instance  : handle to new instance object
+ *     face      : pointer to parent face object
+ *
+ *  <Return>
+ *     TrueDoc error code. 0 means success.
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  T1_Error  T1_Init_Size( T1_Size  size )
+  {
+    T1_Error    error;
+      
+    size->valid = 0;
+    
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+    error = T1_New_Size_Hinter( size );
+    return error;
+#else
+    (void)error;
+    return T1_Err_Ok;
+#endif
+  }
+
+
+/*******************************************************************
+ *
+ *  <Function> T1_Reset_Size
+ *
+ *  <Description>
+ *     Resets an instance to a new pointsize/transform.
+ *     This function is in charge of resetting the blue zones,
+ *     As well as the stem snap tables for a given size..
+ *
+ *  <Input>
+ *     instance   the instance object to destroy
+ *
+ *  <Output>
+ *     Error code.
+ *
+ ******************************************************************/
+ 
+  LOCAL_FUNC
+  T1_Error  T1_Reset_Size( T1_Size  size )
+  {
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+    return T1_Reset_Size_Hinter( size );
+#else
+    (void)size;
+    return 0;
+#endif
+  }
+
+
+/*******************************************************************
+ *                                                                 *
+ *                         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;
+
+    if (face)
+    {
+      memory = face->root.memory;
+      /* XXXX : TO DO */
+    }
+  }
+
+/*******************************************************************
+ *
+ *  <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
+  T1_Error  T1_Init_Face( FT_Stream  stream,
+                          FT_Int     face_index,
+                          T1_Face    face )
+  {
+    T1_Tokenizer  tokenizer;
+    T1_Error      error;
+
+    (void)face_index;
+    (void)face;
+
+    face->root.num_faces = 1;
+
+    /* open the tokenizer, this will also check the font format */
+    error = New_Tokenizer( stream, &tokenizer );
+    if (error) goto Fail;
+
+    /* if we just wanted to check the format, leave successfully now */
+    if (face_index < 0)
+      goto Leave;
+
+    /* check the face index */
+    if ( face_index != 0 )
+    {
+      FT_ERROR(( "T1.Init_Face : invalid face index\n" ));
+      error = T1_Err_Invalid_Argument;
+      goto Leave;
+    }
+
+    /* Now, load the font program into the face object */
+    {
+      T1_Parser  parser;
+
+      Init_T1_Parser( &parser, face, tokenizer );
+      error = Parse_T1_FontProgram( &parser );
+      if (error) goto Leave;
+
+      /* Init the face object fields */
+      /* Now set up root face fields */
+      {
+        FT_Face  root = (FT_Face)&face->root;
+        
+        root->num_glyphs   = face->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->font_info.is_fixed_pitch )
+          root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
+
+        /* 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->font_info.family_name;
+        if (root->family_name)
+        {
+          char*  full   = face->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->font_name)
+          {
+            root->family_name = face->font_name;
+            root->style_name  = "Regular";
+          }
+        }
+  
+        /* no embedded bitmap support */
+        root->num_fixed_sizes = 0;
+        root->available_sizes = 0;
+  
+        root->bbox         = face->font_bbox;
+        root->units_per_EM = 1000;
+        root->ascender     =  (T1_Short)face->font_bbox.yMax;
+        root->descender    = -(T1_Short)face->font_bbox.yMin;
+        root->height       = ((root->ascender + root->descender)*12)/10;
+  
+        /* now compute the maximum advance width */
+
+        root->max_advance_width = face->private_dict.standard_width;
+
+        /* compute max advance width for proportional fonts */
+        if (!face->font_info.is_fixed_pitch)
+        {
+          T1_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->font_info.underline_position;
+        root->underline_thickness = face->font_info.underline_thickness;
+  
+        root->max_points   = 0;
+        root->max_contours = 0;
+      }
+    }
+
+  Leave:
+    Done_Tokenizer( tokenizer );
+
+  Fail:
+    return error;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  Glyph_Destroy
+ *
+ *  Description :  The glyph object destructor.
+ *
+ *  Input  :  _glyph  typeless pointer to the glyph record to destroy
+ *
+ *  Output :  Error code.                       
+ *
+ ******************************************************************/
+
+  LOCAL_FUNC
+  void  T1_Done_GlyphSlot( T1_GlyphSlot  glyph )
+  {
+    FT_Memory  memory  = glyph->root.face->memory;
+    FT_Library library = glyph->root.face->driver->library;
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+    T1_Done_Glyph_Hinter( glyph );
+#endif
+	/* the bitmaps are created on demand */
+	FREE( glyph->root.bitmap.buffer );
+    FT_Done_Outline( library, &glyph->root.outline );
+    return;
+  }
+
+
+/*******************************************************************
+ *
+ *  Function    :  Glyph_Create
+ *
+ *  Description :  The glyph object constructor.
+ *
+ *  Input  :  glyph   glyph record to build.
+ *            face    the glyph's parent face.              
+ *
+ *  Output :  Error code.
+ *
+ ******************************************************************/
+
+  LOCAL_FUNC
+  T1_Error  T1_Init_GlyphSlot( T1_GlyphSlot  glyph )
+  {
+    FT_Library  library = glyph->root.face->driver->library;
+    T1_Error    error;
+
+    glyph->max_points         = 0;
+    glyph->max_contours       = 0;
+    glyph->root.bitmap.buffer = 0;
+
+    error = FT_New_Outline( library, 0, 0, &glyph->root.outline );
+    if (error) return error;
+
+#ifndef T1_CONFIG_OPTION_DISABLE_HINTER
+    error = T1_New_Glyph_Hinter( glyph );
+    if (error)
+      FT_Done_Outline( library, &glyph->root.outline );
+#endif
+
+    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
+  T1_Error  T1_Init_Driver( T1_Driver  driver )
+  {
+    (void)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 )
+  {
+    (void)driver;
+  }
+
+
+/* END */
diff --git a/src/type1/t1objs.h b/src/type1/t1objs.h
new file mode 100644
index 0000000..417ae53
--- /dev/null
+++ b/src/type1/t1objs.h
@@ -0,0 +1,302 @@
+/*******************************************************************
+ *
+ *  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 <ftobjs.h>
+#include <t1config.h>
+#include <t1errors.h>
+#include <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;
+    T1_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;
+
+    T1_Bool          hint;
+    T1_Bool          scaled;
+    
+    T1_Int           max_points;
+    T1_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
+  T1_Error  T1_Init_Face( FT_Stream    stream,
+                          FT_Int       face_index,
+                          T1_Face      face );
+
+
+
+/*******************************************************************
+ *
+ *  <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_Size
+ *
+ *  <Description>
+ *     Initialise a new Type 1 size object
+ *
+ *  <Input>
+ *     size  :: handle to size object
+ *
+ *  <Return>
+ *     Type 1 error code. 0 means success.
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  T1_Error  T1_Init_Size( T1_Size  size );
+
+
+
+/*******************************************************************
+ *
+ * <Function>  T1_Done_Size
+ *
+ * <Description>
+ *    The Type 1 size object finaliser.
+ *
+ * <Input>
+ *    size   :: handle to the target size object.
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  void  T1_Done_Size( T1_Size  size );
+
+
+/*******************************************************************
+ *
+ * <Function>  T1_Reset_Size
+ *
+ * <Description>
+ *    Reset a Type 1 size when resolutions and character dimensions
+ *    have been changed..
+ *
+ * <Input>
+ *    size   :: handle to the target size object.
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  T1_Error  T1_Reset_Size( T1_Size  size );
+
+
+
+/*******************************************************************
+ *
+ *  <Function> T1_Init_GlyphSlot
+ *
+ *  <Description> The TrueType glyph slot initialiser
+ *
+ *  <Input>  glyph ::  glyph record to build.
+ *
+ *  <Output> Error code.
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  T1_Error  T1_Init_GlyphSlot( T1_GlyphSlot  slot );
+
+
+
+/*******************************************************************
+ *
+ *  <Function> T1_Done_GlyphSlot
+ *
+ *  <Description> The Type 1 glyph slot finaliser
+ *
+ *  <Input>  glyph  :: handle to glyph slot object
+ *
+ *  <Output>  Error code.                       
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  void  T1_Done_GlyphSlot( T1_GlyphSlot  slot );
+
+
+
+/*******************************************************************
+ *
+ *  <Function>  T1_Init_Driver
+ *
+ *  <Description>
+ *     Initialise a given Type 1 driver object
+ *
+ *  <Input>
+ *     driver ::  handle to target driver object
+ *
+ *  <Return>
+ *     Error code.
+ *
+ ******************************************************************/
+
+  LOCAL_DEF
+  T1_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 */
diff --git a/src/type1/t1parse.c b/src/type1/t1parse.c
new file mode 100644
index 0000000..e3710b0
--- /dev/null
+++ b/src/type1/t1parse.c
@@ -0,0 +1,665 @@
+#include <ftdebug.h>
+#include <t1types.h>
+#include <t1parse.h>
+
+#include <stdio.h>  /* for sscanf */
+
+/*************************************************************************/
+/*                                                                       */
+/* <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
+  T1_Error  T1_New_Table( T1_Table*  table,
+                          T1_Int     count,
+                          FT_Memory  memory )
+  {
+	 T1_Error  error;
+
+	 table->memory = memory;
+	 if ( ALLOC_ARRAY( table->elements, count, T1_Byte* ) )
+		 return error;
+
+	 if ( ALLOC_ARRAY( table->lengths, count, T1_Byte* ) )
+	 {
+	   FREE( table->elements );
+	   return error;
+	}
+
+	table->max_elems = count;
+	table->num_elems = 0;
+
+	table->block        = 0;
+	table->capacity     = 0;
+	table->cursor       = 0;
+
+	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
+      T1_Error  reallocate_t1_table( T1_Table*  table,
+                                     T1_Int     new_size )
+      {
+        FT_Memory  memory   = table->memory;
+        T1_Byte*   old_base = table->block;
+        T1_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)
+        {
+          T1_Long   delta  = table->block - old_base;
+          T1_Byte** offset = table->elements;
+          T1_Byte** limit  = offset + table->max_elems;
+
+          if (delta)
+            for ( ; offset < limit; offset ++ )
+              if (offset[0])
+                offset[0] += delta;
+        }
+
+        return T1_Err_Ok;
+      }
+
+
+  LOCAL_FUNC
+  T1_Error  T1_Add_Table( T1_Table*  table,
+                          T1_Int     index,
+                          void*      object,
+                          T1_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 )
+    {
+      T1_Error  error;
+      T1_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.  */
+/*                                                                       */
+  LOCAL_FUNC
+  void  T1_Done_Table( T1_Table*  table )
+  {
+    FT_Memory  memory = table->memory;
+    T1_Error   error;
+    T1_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)
+    {
+      T1_Long   delta   = table->block - old_base;
+      T1_Byte** element = table->elements;
+      T1_Byte** limit   = element + table->max_elems;
+      
+      for ( ; element < limit; element++ )
+        if (element[0])
+          element[0] += delta;
+    }
+  }
+
+
+  LOCAL_FUNC
+  T1_String*   CopyString( T1_Parser*  parser )
+  {
+    T1_String*  string = NULL;
+    T1_Token*   token  = parser->args++;
+    FT_Memory   memory = parser->tokenizer->memory;
+    T1_Error    error;
+
+    if ( token->kind == tok_string )
+    {
+      int  len = token->len-2;
+
+      if ( ALLOC( string, len+1 ) )
+      {
+        parser->error = error;
+        return 0;
+      }
+
+      MEM_Copy( string, parser->tokenizer->base + token->start+1, len );
+      string[len] = '\0';
+
+      parser->error = T1_Err_Ok;
+    }
+    else
+    {
+      FT_ERROR(( "T1.CopyString : syntax error, string token expected !\n" ));
+      parser->error = T1_Err_Syntax_Error;
+    }
+    return string;
+  }
+
+
+
+  static
+  T1_Error  parse_int( T1_Byte*  base,
+                       T1_Byte*  limit,
+                       T1_Long*  result )
+  {
+    T1_Bool  sign = 0;
+    T1_Long  sum  = 0;
+
+    if (base >= limit)
+      goto Fail;
+
+    /* check sign */
+    if ( *base == '+' )
+      base++;
+
+    else if ( *base == '-' )
+    {
+      sign++;
+      base++;
+    }
+
+    /* parse digits */
+    if ( base >= limit )
+      goto Fail;
+
+    do
+    {
+      sum = ( 10*sum + (*base++ - '0') );
+
+    } while (base < limit);
+
+    if (sign)
+      sum = -sum;
+
+    *result = sum;
+    return T1_Err_Ok;
+
+  Fail:
+    FT_ERROR(( "T1.parse_integer : integer expected\n" ));
+    *result = 0;
+    return T1_Err_Syntax_Error;
+  }
+
+
+
+
+  static
+  T1_Error  parse_float( T1_Byte*  base,
+                         T1_Byte*  limit,
+                         T1_Int    scale,
+                         T1_Long*  result )
+  {
+#if 1
+    /* XXX : We're simply much too lazy to code this function  */
+    /*       properly for now.. We'll do that when the rest of */
+    /*       the driver works properly..                       */
+    char    temp[32];
+    int     len = limit-base;
+    double  value;
+
+    if (len > 31) goto Fail;
+
+    strncpy( temp, (char*)base, len );
+    temp[len] = '\0';
+    if ( sscanf( temp, "%lf", &value ) != 1 )
+      goto Fail;
+
+    *result = (T1_Long)(scale*value);
+    return 0;
+
+#else
+  T1_Byte*  cur;
+  T1_Bool   sign        = 0;  /* sign                        */
+  T1_Long   number_int  = 0;  /* integer part                */
+  T1_Long   number_frac = 0;  /* fractional part             */
+  T1_Long   exponent    = 0;  /* exponent value              */
+  T1_Int    num_frac    = 0;  /* number of fractional digits */
+
+  /* check sign */
+  if (*base == '+')
+    base++;
+
+  else if (*base == '-')
+  {
+    sign++;
+    base++;
+  }
+
+  /* find integer part */
+  cur = base;
+  while ( cur < limit )
+  {
+    T1_Byte  c = *cur;
+    if ( c == '.' || c == 'e' || c == 'E' )
+      break;
+
+    cur++;
+  }
+
+  if ( cur > base )
+  {
+    error = parse_integer( base, cur, &number_int );
+    if (error) goto Fail;
+  }
+
+  /* read fractional part, if any */
+  if ( *cur == '.' )
+  {
+    cur++;
+    base = cur;
+    while ( cur < limit )
+    {
+      T1_Byte  c = *cur;
+      if ( c == 'e' || c == 'E' )
+        break;
+      cur++;
+    }
+
+    num_frac = cur - base;
+
+    if ( cur > base )
+    {
+      error = parse_integer( base, cur, &number_frac );
+      if (error) goto Fail;
+      base = cur;
+    }
+  }
+
+  /* read exponent, if any */
+  if ( *cur == 'e' || *cur == 'E' )
+  {
+    cur++;
+    base = cur;
+    error = parse_integer( base, limit, &exponent );
+    if (error) goto Fail;
+
+    /* now check that exponent is within 'correct bounds' */
+    /* i.e. between -6 and 6                              */
+    if ( exponent < -6 || exponent > 6 )
+      goto Fail;
+  }
+
+  /* now adjust integer value and exponent for fractional part */
+  while ( num_frac > 0 )
+  {
+    number_int *= 10;
+    exponent   --;
+    num_frac--;
+  }
+
+  number_int += num_frac;
+
+  /* skip point if any, read fractional part */
+  if ( cur+1 < limit )
+  {
+    if (*cur
+  }
+
+  /* now compute scaled float value */
+  /* XXXXX : incomplete !!!         */
+#endif
+
+  Fail:
+    FT_ERROR(( "T1.parse_float : syntax error !\n" ));
+    return T1_Err_Syntax_Error;
+  }
+
+
+
+  static
+  T1_Error  parse_integer( T1_Byte*  base,
+                           T1_Byte*  limit,
+                           T1_Long*  result )
+  {
+    T1_Byte*  cur;
+
+    /* the lexical analyser accepts floats as well as integers */
+    /* now, check that we really have an int in this token     */
+    cur = base;
+    while ( cur < limit )
+    {
+      T1_Byte  c = *cur++;
+
+      if ( c == '.' || c == 'e' || c == 'E' )
+        goto Float_Number;
+    }
+
+    /* now read the number's value */
+    return parse_int( base, limit, result );
+
+  Float_Number:
+    /* We really have a float there, simply call parse_float in this */
+    /* case with a scale of '10' to perform round..                */
+    {
+      T1_Error error;
+
+      error = parse_float( base, limit, 10, result );
+      if (!error)
+      {
+        if (*result >= 0) *result = (*result+5)/10;      /* round value */
+                    else  *result = -((5-*result)/10);
+      }
+      return error;
+    }
+  }
+
+
+  LOCAL_FUNC
+  T1_Long  CopyInteger( T1_Parser*  parser )
+  {
+    T1_Long   sum   = 0;
+    T1_Token* token = parser->args++;
+
+    if ( token->kind == tok_number )
+    {
+      T1_Byte*  base  = parser->tokenizer->base + token->start;
+      T1_Byte*  limit = base + token->len;
+
+      /* now read the number's value */
+      parser->error = parse_integer( base, limit, &sum );
+      return sum;
+    }
+
+    FT_ERROR(( "T1.CopyInteger : number expected\n" ));
+    parser->args--;
+    parser->error = T1_Err_Syntax_Error;
+    return 0;
+  }
+
+
+
+  LOCAL_FUNC
+  T1_Bool   CopyBoolean( T1_Parser*  parser )
+  {
+    T1_Error  error  = T1_Err_Ok;
+    T1_Bool   result = 0;
+    T1_Token* token  = parser->args++;
+
+    if ( token->kind == tok_keyword )
+    {
+      if ( token->kind2 == key_false )
+        result = 0;
+
+      else if ( token->kind2 == key_true )
+        result = !0;
+
+      else
+        goto Fail;
+    }
+    else
+    {
+      Fail:
+        FT_ERROR(( "T1.CopyBoolean : syntax error, 'false' or 'true' expected\n" ));
+        error = T1_Err_Syntax_Error;
+    }
+    parser->error = error;
+    return result;
+  }
+
+
+
+
+  LOCAL_FUNC
+  T1_Long   CopyFloat( T1_Parser*  parser,
+                       T1_Int      scale )
+  {
+    T1_Error  error;
+    T1_Long   sum = 0;
+    T1_Token* token = parser->args++;
+
+    if ( token->kind == tok_number )
+    {
+      T1_Byte*  base  = parser->tokenizer->base + token->start;
+      T1_Byte*  limit = base + token->len;
+
+      error = parser->error = parse_float( base, limit, scale, &sum );
+      if (error) goto Fail;
+
+      return sum;
+    }
+
+  Fail:
+    FT_ERROR(( "T1.CopyFloat : syntax error !\n" ));
+    parser->error = T1_Err_Syntax_Error;
+    return 0;
+  }
+
+
+
+
+
+
+  LOCAL_FUNC
+  void  CopyBBox( T1_Parser*  parser,
+                  T1_BBox*    bbox )
+  {
+    T1_Token* token = parser->args++;
+    T1_Int    n;
+    T1_Error  error;
+
+    if ( token->kind == tok_program ||
+         token->kind == tok_array   )
+    {
+      /* get rid of '['/']', or '{'/'}' */
+      T1_Byte*  base  = parser->tokenizer->base + token->start + 1;
+      T1_Byte*  limit = base + token->len - 1;
+      T1_Byte*  cur;
+      T1_Byte*  start;
+
+      /* read each parameter independently */
+      cur = base;
+      for ( n = 0; n < 4; n++ )
+      {
+        T1_Long*  result;
+
+        /* skip whitespace */
+        while (cur < limit && *cur == ' ') cur++;
+
+        /* skip numbers */
+        start = cur;
+        while (cur < limit && *cur != ' ') cur++;
+
+        /* compute result address */
+        switch (n)
+        {
+          case 0 : result = &bbox->xMin; break;
+          case 1 : result = &bbox->yMin; break;
+          case 2 : result = &bbox->xMax; break;
+          default: result = &bbox->yMax;
+        }
+
+        error = parse_integer( start, cur, result );
+        if (error) goto Fail;
+      }
+      parser->error = 0;
+      return;
+    }
+
+  Fail:
+    FT_ERROR(( "T1.CopyBBox : syntax error !\n" ));
+    parser->error = T1_Err_Syntax_Error;
+  }
+
+
+
+
+  LOCAL_FUNC
+  void  CopyMatrix( T1_Parser*  parser,
+                    T1_Matrix*  matrix )
+  {
+    T1_Token* token = parser->args++;
+    T1_Error  error;
+
+    if ( token->kind == tok_array )
+    {
+      /* get rid of '[' and ']' */
+      T1_Byte*  base  = parser->tokenizer->base + token->start + 1;
+      T1_Byte*  limit = base + token->len - 1;
+      T1_Byte*  cur;
+      T1_Byte*  start;
+      T1_Int    n;
+
+      /* read each parameter independently */
+      cur = base;
+      for ( n = 0; n < 4; n++ )
+      {
+        T1_Long*  result;
+
+        /* skip whitespace */
+        while (cur < limit && *cur == ' ') cur++;
+
+        /* skip numbers */
+        start = cur;
+        while (cur < limit && *cur != ' ') cur++;
+
+        /* compute result address */
+        switch (n)
+        {
+          case 0 : result = &matrix->xx; break;
+          case 1 : result = &matrix->xy; break;
+          case 2 : result = &matrix->yx; break;
+          default: result = &matrix->yy;
+        }
+
+        error = parse_float( start, cur, 65536000, result );
+        if (error) goto Fail;
+      }
+      parser->error = 0;
+      return;
+    }
+
+  Fail:
+    FT_ERROR(( "T1.CopyMatrix : syntax error !\n" ));
+    parser->error = T1_Err_Syntax_Error;
+  }
+
+
+
+  LOCAL_FUNC
+  void  CopyArray( T1_Parser*  parser,
+                   T1_Byte*    num_elements,
+                   T1_Short*   elements,
+                   T1_Int      max_elements )
+  {
+    T1_Token* token = parser->args++;
+    T1_Error  error;
+
+    if ( token->kind == tok_array   ||
+         token->kind == tok_program )   /* in the case of MinFeature */
+    {
+      /* get rid of '['/']', or '{'/'}' */
+      T1_Byte*  base  = parser->tokenizer->base + token->start + 1;
+      T1_Byte*  limit = base + token->len - 2;
+      T1_Byte*  cur;
+      T1_Byte*  start;
+      T1_Int    n;
+
+      /* read each parameter independently */
+      cur = base;
+      for ( n = 0; n < max_elements; n++ )
+      {
+        T1_Long  result;
+
+        /* test end of string */
+        if (cur >= limit)
+          break;
+
+        /* skip whitespace */
+        while (cur < limit && *cur == ' ') cur++;
+
+        /* end of list ? */
+        if (cur >= limit)
+          break;
+
+        /* skip numbers */
+        start = cur;
+        while (cur < limit && *cur != ' ') cur++;
+
+        error = parse_integer( start, cur, &result );
+        if (error) goto Fail;
+
+        *elements ++ = (T1_Short)result;
+      }
+
+      if (num_elements)
+        *num_elements = (T1_Byte)n;
+
+      parser->error = 0;
+      return;
+    }
+
+  Fail:
+    FT_ERROR(( "T1.CopyArray : syntax error !\n" ));
+    parser->error = T1_Err_Syntax_Error;
+  }
+
diff --git a/src/type1/t1parse.h b/src/type1/t1parse.h
new file mode 100644
index 0000000..4bb7181
--- /dev/null
+++ b/src/type1/t1parse.h
@@ -0,0 +1,296 @@
+/*******************************************************************
+ *
+ *  t1parse.h                                                   1.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 Type1 parser component is in charge of simply parsing
+ *  the font input stream and convert simple tokens and elements
+ *  into integers, floats, matrices, strings, etc..
+ *
+ *  It is used by the Type1 loader..
+ *
+ ******************************************************************/
+
+#ifndef T1PARSE_H
+#define T1PARSE_H
+
+#include <ftstream.h>
+#include <t1tokens.h>
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/*************************************************************************
+ *
+ * <Enum> T1_DictState
+ *
+ * <Description>
+ *    An enumeration used to describe the Type 1 parser's state, i.e.
+ *    which dictionary (or array) it is scanning and processing at the
+ *    current moment..
+ *
+ */
+  typedef enum  T1_DictState_
+  {
+    dict_none = 0,
+    dict_font,          /* parsing the font dictionary              */
+    dict_fontinfo,      /* parsing the font info dictionary         */
+    dict_none2,         /* beginning to parse the encrypted section */
+    dict_private,       /* parsing the private dictionary           */
+    dict_encoding,      /* parsing the encoding array               */
+    dict_subrs,         /* parsing the subrs array                  */
+    dict_othersubrs,    /* parsing the othersubrs array (?)         */
+    dict_charstrings,   /* parsing the charstrings dictionary       */
+    dict_unknown_array, /* parsing/ignoring an unknown array        */
+    dict_unknown_dict,  /* parsing/ignoring an unknown dictionary   */
+
+    dict_max    /* do not remove from list */
+
+  } T1_DictState;
+
+
+  typedef enum T1_EncodingType_
+  {
+	encoding_none = 0,
+	encoding_array,
+	encoding_standard,
+	encoding_expert
+
+  } T1_EncodingType;
+/*************************************************************************
+ *
+ * <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
+ *
+ *    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
+ *
+ *    system   :: system object used for memory operations (alloc/realloc)
+ */
+
+  typedef struct T1_Table_
+  {
+    T1_Byte*   block;          /* current memory block           */
+    T1_Int     cursor;         /* current cursor in memory block */
+    T1_Int     capacity;       /* current size of memory block   */
+
+    T1_Int     max_elems;
+    T1_Int     num_elems;
+    T1_Byte**  elements;       /* addresses of table elements */
+    T1_Int*    lengths;        /* lengths of table elements   */
+
+    FT_Memory  memory;
+
+  } T1_Table;
+
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Struct> T1_Parser                                                    */
+/*                                                                       */
+/* <Description>                                                         */
+/*    A Type 1 parser. This object is in charge of parsing Type 1        */
+/*    ASCII streams and builds dictionaries for a T1_Face object.        */
+/*                                                                       */
+/* <Fields>                                                              */
+/*    error ::                                                           */
+/*       current error code. 0 means success                             */
+/*                                                                       */
+/*    face  ::                                                           */
+/*       the target T1_Face object being built                           */
+/*                                                                       */
+/*    tokenizer ::                                                       */
+/*       the tokenizer (lexical analyser) used for processing the        */
+/*       input stream.                                                   */
+/*                                                                       */
+/*    stack ::                                                           */
+/*       the current token stack. Note that we don't use intermediate    */
+/*       Postscript objects here !                                       */
+/*                                                                       */
+/*    top ::                                                             */
+/*       current top of token stack                                      */
+/*                                                                       */
+/*    limit ::                                                           */
+/*       current upper bound of the token stack. Used for overflow       */
+/*       checks..                                                        */
+/*                                                                       */
+/*    args ::                                                            */
+/*       arguments of a given operator. used and increased by the        */
+/*       Copy.... functions..                                            */
+/*                                                                       */
+/*    state_index ::                                                     */
+/*       index of top of the dictionary state stack                      */
+/*                                                                       */
+/*    state_stack ::                                                     */
+/*       dictionary states stack                                         */
+/*                                                                       */
+/*    table ::                                                           */
+/*       a T1_Table object used to record various kinds of               */
+/*       dictionaries or arrays (like /Encoding, /Subrs, /CharStrings)   */
+/*                                                                       */
+/*                                                                       */
+  typedef  struct  T1_Parser_
+  {
+    T1_Error      error;
+    T1_Face       face;
+
+    T1_Tokenizer  tokenizer;
+    T1_Bool       dump_tokens;
+
+    T1_Token      stack[ T1_MAX_STACK_DEPTH ];
+    T1_Token*     top;
+    T1_Token*     limit;
+    T1_Token*     args;
+
+    T1_Int        state_index;
+    T1_DictState  state_stack[ T1_MAX_DICT_DEPTH ];
+
+	T1_Table      table;
+
+	T1_Int        cur_name;
+
+	T1_EncodingType  encoding_type;
+    T1_Byte*         encoding_names;
+    T1_Int*          encoding_lengths;
+    T1_Byte**        encoding_offsets;
+
+    T1_Byte*      subrs;
+    T1_Byte*      charstrings;
+
+  } T1_Parser;
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <Function> T1_New_Table                                               */
+/*                                                                       */
+/* <Description>                                                         */
+/*    Initialise a T1_Table.                                             */
+/*                                                                       */
+/* <Input>                                                               */
+/*    table  :: address of target table                                  */
+/*    count  :: table size = maximum number of elements                  */
+/*    system :: system object to use for all subsequent reallocations    */
+/*                                                                       */
+/* <Return>                                                              */
+/*    Error code. 0 means success                                        */
+/*                                                                       */
+  LOCAL_DEF
+  T1_Error  T1_New_Table( T1_Table*  table,
+                          T1_Int     count,
+                          FT_Memory  memory );
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <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..                                                   */
+/*                                                                       */
+  LOCAL_DEF
+  T1_Error  T1_Add_Table( T1_Table*  table,
+                          T1_Int     index,
+                          void*      object,
+                          T1_Int     length );
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <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.  */
+/*                                                                       */
+  LOCAL_DEF
+  void  T1_Done_Table( T1_Table*  table );
+
+
+
+
+  LOCAL_DEF
+  T1_String*   CopyString( T1_Parser*  parser );
+
+
+  LOCAL_DEF
+  T1_Long      CopyInteger( T1_Parser*  parser );
+
+
+  LOCAL_DEF
+  T1_Bool      CopyBoolean( T1_Parser*  parser );
+
+
+  LOCAL_DEF
+  T1_Long      CopyFloat( T1_Parser*  parser,
+                          T1_Int      scale );
+
+  LOCAL_DEF
+  void         CopyBBox( T1_Parser*  parser,
+                         T1_BBox*    bbox );
+
+  LOCAL_DEF
+  void         CopyMatrix( T1_Parser*  parser,
+                           T1_Matrix*  matrix );
+
+  LOCAL_DEF
+  void  CopyArray( T1_Parser*  parser,
+                   T1_Byte*    num_elements,
+                   T1_Short*   elements,
+                   T1_Int      max_elements );
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* T1PARSE_H */
+
+
+/* END */
+
diff --git a/src/type1/t1tokens.c b/src/type1/t1tokens.c
new file mode 100644
index 0000000..7069d69
--- /dev/null
+++ b/src/type1/t1tokens.c
@@ -0,0 +1,994 @@
+/*******************************************************************
+ *
+ *  t1tokens.c
+ *
+ *  Type 1 tokenizer
+ *
+ *  Copyright 1996 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 tokenizer is in charge of loading and reading a Type1 font
+ *  file (either in PFB or PFA format), and extract successive tokens
+ *  and keywords from its two streams (i.e. the font program, and the
+ *  private dictionary).
+ *
+ *  Eexec decryption is performed automatically when entering the
+ *  private dictionary, or when retrieving char strings..
+ *
+ ******************************************************************/
+
+#include <ftstream.h>
+#include <ftdebug.h>
+
+#include <t1tokens.h>
+#include <t1load.h>
+
+#undef  READ_BUFFER_INCREMENT
+#define READ_BUFFER_INCREMENT  0x400
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_t1load
+
+  /* array of Type1 keywords supported by this engine. This table places */
+  /* the keyword in lexicographical order. It should always correspond   */
+  /* to the enums key_XXXX !!                                            */
+  /*                                                                     */
+  const  char*  t1_keywords[ key_max - key_first_ ] =
+  {
+    "-|", "ExpertEncoding", "ND", "NP", "RD", "StandardEncoding", "array",
+	"begin", "closefile", "currentdict", "currentfile", "def", "dict", "dup",
+	"eexec", "end", "executeonly", "false", "for", "index",	"noaccess",
+	"put", "readonly", "true", "userdict", "|", "|-"
+  };
+
+
+
+  const  char*  t1_immediates[ imm_max - imm_first_ ] =
+  {
+    "-|", ".notdef", "BlueFuzz", "BlueScale", "BlueShift", "BlueValues",
+    "CharStrings", "Encoding", "FamilyBlues", "FamilyName", "FamilyOtherBlues",
+    "FID", "FontBBox", "FontID", "FontInfo", "FontMatrix", "FontName",
+    "FontType", "ForceBold", "FullName", "ItalicAngle", "LanguageGroup",
+    "Metrics", "MinFeature", "ND", "NP", "Notice", "OtherBlues", "OtherSubrs",
+    "PaintType", "Private", "RD", "RndStemUp", "StdHW", "StdVW", "StemSnapH",
+    "StemSnapV", "StrokeWidth", "Subrs", "UnderlinePosition",
+    "UnderlineThickness", "UniqueID", "Weight", "isFixedPitch", "lenIV",
+    "password", "version", "|", "|-"
+  };
+
+
+  /* lexicographic comparison of two strings */
+  static
+  int  lexico_strcmp( const char*  str1,
+                      int          str1_len,
+                      const char*  str2 )
+  {
+    int  c2 = 0;
+
+    for ( ; str1_len > 0; str1_len-- )
+    {
+      int c1, diff;
+
+      c1 = *str1++;
+      c2 = *str2++;
+
+      diff = c1 - c2;
+      if (diff) return diff;
+    };
+    return -*str2;
+  }
+
+
+  /* Find a given token/name, perform binary search */
+  static
+  int  Find_Name( char*  base, int  length,
+                  const char** table, int  table_len )
+  {
+    /* performs a binary search */
+
+    T1_Int  left, right;
+
+    left  = 0;
+    right = table_len-1;
+
+    while ( right-left > 1 )
+    {
+      T1_Int  middle = left + (( right-left ) >> 1);
+      T1_Int  cmp;
+
+      cmp = lexico_strcmp( base, length, table[middle] );
+      if (!cmp) return middle;
+
+      if ( cmp < 0 )
+        right = middle;
+      else
+        left  = middle;
+    }
+
+    if ( !lexico_strcmp( base, length, table[left ] ) ) return left;
+    if ( !lexico_strcmp( base, length, table[right] ) ) return right;
+
+    return -1;
+  }
+
+
+  /* read the small PFB section header */
+  static
+  T1_Error  Read_PFB_Tag( FT_Stream  stream,
+                          T1_UShort* atag,
+                          T1_ULong*  asize )
+  {
+    T1_UShort tag;
+    T1_ULong  size;
+    T1_Error  error;
+
+    FT_TRACE2(( "Read_PFB_Tag : reading\n" ));
+
+    if ( ACCESS_Frame( 6L ) ) return error;
+
+    tag  = GET_UShort();
+    size = GET_ULong();
+
+    FORGET_Frame();
+
+    *atag  = tag;
+    *asize = (  (size        & 0xFF) << 24 ) |
+             ( ((size >> 8)  & 0xFF) << 16 ) |
+             ( ((size >> 16) & 0xFF) << 8 )  |
+             ( ((size >> 24) & 0xFF) );
+
+    FT_TRACE2(( "  tag  = %04x\n", tag    ));
+    FT_TRACE4(( "  asze = %08x\n", size   ));
+    FT_TRACE2(( "  size = %08x\n", *asize ));
+
+    return T1_Err_Ok;
+  }
+
+
+
+  static
+  T1_Error  grow( T1_Tokenizer  tokzer )
+  {
+    T1_Error   error;
+    T1_Long    left_bytes;
+    FT_Memory  memory = tokzer->memory;
+
+    left_bytes = tokzer->max - tokzer->limit;
+
+    if ( left_bytes > 0 )
+    {
+      FT_Stream stream = tokzer->stream;
+
+      if ( left_bytes > READ_BUFFER_INCREMENT )
+        left_bytes = READ_BUFFER_INCREMENT;
+
+      FT_TRACE2(( "Growing tokenizer buffer by %d bytes\n", left_bytes ));
+
+      (void)stream;  /* unused in non reentrant mode */
+
+      if ( !REALLOC( tokzer->base, tokzer->limit, 
+                     tokzer->limit + left_bytes )                 &&
+           !FILE_Read( tokzer->base + tokzer->limit, left_bytes ) )
+        tokzer->limit += left_bytes;
+    }
+    else
+    {
+      FT_ERROR(( "Unexpected end of Type1 fragment !!\n" ));
+      error = T1_Err_Invalid_File_Format;
+    }
+
+    tokzer->error = error;
+    return error;
+  }
+
+
+
+
+  LOCAL_FUNC
+  void  t1_decrypt( T1_Byte*   buffer,
+                    T1_Int     length,
+                    T1_UShort  seed )
+  {
+    while ( length > 0 )
+    {
+      T1_Byte  plain;
+
+      plain     = (*buffer ^ (seed >> 8));
+      seed      = (*buffer+seed)*52845+22719;
+      *buffer++ = plain;
+      length--;
+    }
+  }
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> New_Tokenizer                                             */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     Creates a new tokenizer from a given input stream. This function  */
+ /*     automatically recognizes "pfa" or "pfb" files. The function       */
+ /*     "Read_Token" can then be used to extract successive tokens from   */
+ /*     the stream..                                                      */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     stream  :: input stream                                           */
+ /*                                                                       */
+ /*  <Output>                                                             */
+ /*     tokenizer :: handle to new tokenizer object..                     */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+ /*  <Note>                                                               */
+ /*     This function copies the stream handle within the object. Callers */
+ /*     should not discard "stream". This is done by the Done_Tokenizer   */
+ /*     function..                                                        */
+ /*                                                                       */
+
+ LOCAL_FUNC
+ T1_Error  New_Tokenizer( FT_Stream      stream,
+                          T1_Tokenizer*  tokenizer )
+ {
+   FT_Memory     memory = stream->memory;
+   T1_Tokenizer  tokzer;
+   T1_Error      error;
+   T1_UShort     tag;
+   T1_ULong      size;
+
+   T1_Byte*      tok_base;
+   T1_ULong      tok_limit;
+   T1_ULong      tok_max;
+
+   *tokenizer = 0;
+
+   /* allocate object */
+   if ( FILE_Seek( 0L )                     ||
+        ALLOC( tokzer, sizeof(*tokzer) ) )
+     return error;
+
+   tokzer->stream = stream;
+   tokzer->memory = stream->memory;
+
+   tokzer->in_pfb     = 0;
+   tokzer->in_private = 0;
+
+   tok_base  = 0;
+   tok_limit = 0;
+   tok_max   = stream->size;
+
+   error = Read_PFB_Tag( stream, &tag, &size );
+   if (error) goto Fail;
+
+   if ( tag != 0x8001 )
+   {
+     /* assume that it is a PFA file - an error will be produced later */
+     /* if a character with value > 127 is encountered..               */
+
+     /* rewind to start of file */
+     if ( FILE_Seek(0L) ) goto Fail;
+
+     size = stream->size;
+   }
+   else
+     tokzer->in_pfb = 1;
+
+   /* if it's a memory-based resource, set up pointer */
+   if ( !stream->read )
+   {
+     tok_base  = (T1_Byte*)stream->base + stream->pos;
+     tok_limit = size;
+     tok_max   = size;
+
+     /* check that the "size" field is valid */
+     if ( FILE_Skip(size) ) goto Fail;
+   }
+   else if ( tag == 0x8001 )
+   {
+     /* read segment in memory */
+     if ( ALLOC( tok_base, size ) )
+       goto Fail;
+
+     if ( FILE_Read( tok_base, size ) )
+     {
+       FREE( tok_base );
+       goto Fail;
+     }
+
+     tok_limit = size;
+     tok_max   = size;
+   }
+
+   tokzer->base   = tok_base;
+   tokzer->limit  = tok_limit;
+   tokzer->max    = tok_max;
+   tokzer->cursor = 0;
+
+   *tokenizer = tokzer;
+   
+   /* Now check font format, we must see a '%!PS-AdobeFont-1' */
+   /* or a '%!FontType'                                       */
+   {
+     if ( 16 > tokzer->limit )
+       grow( tokzer );
+       
+     if ( tokzer->limit <= 16 ||
+          ( strncmp( (const char*)tokzer->base, "%!PS-AdobeFont-1", 16 ) &&
+            strncmp( (const char*)tokzer->base, "%!FontType", 10 )       ) )
+     {
+       FT_TRACE2(( "Not a Type1 font\n" ));
+       error = T1_Err_Invalid_File_Format;
+       goto Fail;
+     }
+   }
+   return T1_Err_Ok;
+
+ Fail:
+   FREE( tokzer );
+   return error;
+ }
+
+
+
+ /* 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;
+ }
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> Done_Tokenizer                                            */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     Closes a given tokenizer. This function will also close the       */
+ /*     stream embedded in the object..                                   */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     tokenizer :: target tokenizer object                              */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+
+ LOCAL_FUNC
+ T1_Error  Done_Tokenizer( T1_Tokenizer  tokenizer )
+ {
+   FT_Memory  memory = tokenizer->memory;
+
+   /* clear read buffer if needed (disk-based resources) */
+   if ( tokenizer->in_private || !tokenizer->stream->base )
+     FREE( tokenizer->base );
+
+   FREE( tokenizer );
+   return T1_Err_Ok;
+ }
+
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> Open_PrivateDict                                          */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     This function must be called to set the tokenizer to the private  */
+ /*     section of the Type1 file. It recognizes automatically the        */
+ /*     the kind of eexec encryption used (ascii or binary)..             */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     tokenizer :: target tokenizer object                              */
+ /*     lenIV     :: value of the "lenIV" variable..                      */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+
+ LOCAL_FUNC
+ T1_Error  Open_PrivateDict( T1_Tokenizer  tokenizer )
+ {
+   T1_Tokenizer  tokzer = tokenizer;
+   FT_Stream     stream = tokzer->stream;
+   FT_Memory     memory = tokzer->memory;
+   T1_Error      error = 0;
+
+   T1_UShort     tag;
+   T1_ULong      size;
+
+   T1_Byte*      private;
+
+   /* are we already in the private dictionary ? */
+   if ( tokzer->in_private )
+     return 0;
+
+   if ( tokzer->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..                               */
+     T1_Long  start_pos    = FILE_Pos();
+     T1_ULong private_size = 0;
+
+     do
+     {
+       error = Read_PFB_Tag( stream, &tag, &size );
+       if (error || tag != 0x8002) break;
+
+       private_size += size;
+
+       if ( FILE_Skip(size) )
+         goto Fail;
+     }
+     while (1);
+
+     /* Check that we have a private dictionary there */
+     /* and allocate private dictionary buffer        */
+     if ( private_size == 0 )
+     {
+       FT_ERROR(( "T1.Open_Private: invalid private dictionary section\n" ));
+       error = T1_Err_Invalid_File_Format;
+       goto Fail;
+     }
+
+     if ( ALLOC( private, private_size ) )
+       goto Fail;
+
+     /* read all sections into buffer */
+     if ( FILE_Seek( start_pos ) )
+       goto Fail_Private;
+
+     private_size = 0;
+     do
+     {
+       error = Read_PFB_Tag( stream, &tag, &size );
+       if (error || tag != 0x8002) { error = 0; break; }
+
+       if ( FILE_Read( private + private_size, size ) )
+         goto Fail_Private;
+
+       private_size += size;
+     }
+     while (1);
+
+     tokzer->base   = private;
+     tokzer->cursor = 0;
+     tokzer->limit  = private_size;
+     tokzer->max    = private_size;
+   }
+   else
+   {
+     char*  base;
+
+     /* we're in a PFA file, read each token until we find "eexec" */
+     while ( tokzer->token.kind2 != key_eexec )
+     {
+       error = Read_Token( tokzer );
+       if (error) goto Fail;
+     }
+
+     /* now determine wether the private dictionary is encoded in binary */
+     /* or hexadecimal ASCII format..                                    */
+
+     /* 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..                                 */
+     while ( tokzer->cursor+5 > tokzer->limit )
+     {
+       error = grow( tokzer );
+       if (error) goto Fail;
+     }
+
+     /* skip whitespace/line feed after "eexec" */
+     base = (char*)tokzer->base + tokzer->cursor + 1;
+     if ( ( hexa_value( base[0] ) | hexa_value( base[1] ) |
+            hexa_value( base[2] ) | hexa_value( base[3] ) ) < 0 )
+     {
+       /* binary encoding - "simply" read the stream */
+
+       /* if it's a memory-based resource, we need to allocate a new */
+       /* storage buffer for the private dictionary, as it needs to  */
+       /* be decrypted later..                                       */
+       if ( stream->base )
+       {
+         size = stream->size - tokzer->cursor-1; /* remaining bytes */
+
+         if ( ALLOC( private, size ) )  /* allocate private dict buffer */
+           goto Fail;
+
+         /* copy eexec-encrypted bytes */
+         MEM_Copy( private, tokzer->base + tokzer->cursor+1, size );
+
+         /* reset pointers - forget about file mapping */
+         tokzer->base   = private;
+         tokzer->limit  = size;
+         tokzer->max    = size;
+         tokzer->cursor = 0;
+       }
+       /* on the opposite, for disk based resources, we simply grow  */
+       /* the current buffer until its completion, and decrypt the   */
+       /* bytes within it. In all cases, the "base" buffer will be   */
+       /* discarded on DoneTokenizer if we're in the private dict..  */
+       else
+       {
+         /* grow the read buffer to the full file.. */
+         while ( tokzer->limit < tokzer->max )
+         {
+           error = grow( tokenizer );
+           if (error) goto Fail;
+         }
+
+         /* set up cursor to first encrypted byte */
+         tokzer->cursor++;
+       }
+     }
+     else
+     {
+       /* ASCII hexadecimal encoding.. This sucks.. */
+       T1_Byte*  write;
+       T1_Byte*  cur;
+       T1_Byte*  limit;
+       T1_Int    count;
+
+       /* Allocate a buffer, read each one byte at a time .. */
+       count = ( stream->size - tokzer->cursor );
+       size  = count/2;
+
+       if ( ALLOC( private, size ) )   /* allocate private dict buffer */
+         goto Fail;
+
+       write = private;
+       cur   = tokzer->base + tokzer->cursor;
+       limit = tokzer->base + tokzer->limit;
+
+       /* read each bytes */
+       while ( count > 0 )
+       {
+         /* ensure that we can read the next 2 bytes !! */
+         while ( cur+2 > limit )
+         {
+           int  cursor = cur - tokzer->base;
+           error = grow( tokzer );
+           if (error) goto Fail_Private;
+           cur   = tokzer->base + cursor;
+           limit = tokzer->base + tokzer->limit;
+         }
+
+         /* check for new line */
+         if ( cur[0] == '\r' || cur[0] == '\n' )
+         {
+           cur++;
+           count--;
+         }
+         else
+         {
+           int  hex1 = hexa_value(cur[0]);
+
+           /* exit if we have a non hexa-decimal digit which isn't */
+           /* a new-line character..                               */
+           if (hex1 < 0)
+             break;
+
+           /* otherwise, store byte */
+           *write++ = ( hex1 << 4 ) | hexa_value( cur[1] );
+           cur += 2;
+           count -= 2;
+         }
+       }
+
+       /* get rid of old buffer in the case of disk-based resources */
+       if ( !stream->base )
+         FREE( tokzer->base );
+
+       /* set up pointers */
+       tokzer->base   = private;
+       tokzer->limit  = size;
+       tokzer->max    = size;
+       tokzer->cursor = 0;
+     }
+   }
+
+   /* finally, decrypt the private dictionary - and skip the lenIV bytes */
+   t1_decrypt( tokzer->base, tokzer->limit, 55665 );
+   tokzer->cursor += 4;
+
+ Fail:
+   return error;
+
+ Fail_Private:
+   FREE( private );
+   goto Fail;
+ }
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> Read_Token                                                */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     Read a new token from the current input stream. This function     */
+ /*     extracts a token from the font program until "Open_PrivateDict"   */
+ /*     has been called. After this, it returns tokens from the           */
+ /*     (eexec-encrypted) private dictionnary..                           */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     tokenizer :: target tokenizer object                              */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+ /*  <Note>                                                               */
+ /*     One should use the function Read_CharStrings to read the binary   */
+ /*     charstrings from the private dict..                               */
+ /*                                                                       */
+ LOCAL_FUNC
+ T1_Error  Read_Token( T1_Tokenizer  tokenizer )
+ {
+   T1_Tokenizer tok = tokenizer;
+   T1_Long      cur, limit;
+   T1_Byte*     base;
+   char         c, starter, ender;
+   T1_Bool      token_started;
+
+   T1_TokenType  kind;
+
+   tok->error      = T1_Err_Ok;
+   tok->token.kind = tok_any;
+
+   base  = tok->base;
+   limit = tok->limit;
+   cur   = tok->cursor;
+
+   token_started = 0;
+
+   for (;;)
+   {
+     if ( cur >= limit )
+     {
+       if ( grow( tok ) ) goto Exit;
+       base  = tok->base;
+       limit = tok->limit;
+     }
+
+     c = (char)base[cur++];
+
+     /* check that we have an ASCII character */
+     if ( (T1_Byte)c > 127 )
+     {
+       FT_ERROR(( "Unexpected binary data in Type1 fragment !!\n" ));
+       tok->error = T1_Err_Invalid_File_Format;
+       goto Exit;
+     }
+
+     switch (c)
+     {
+       case '\r' :
+       case '\n' :
+       case ' '  :
+       case '\t' : /* skip initial whitespace => skip to next */
+         if (token_started)
+         {
+           /* possibly a name, keyword, wathever */
+           tok->token.kind = tok_any;
+           tok->token.len  = cur-tok->token.start-1;
+           goto Exit;
+         }
+         /* otherwise, skip everything */
+         break;
+
+
+       case '%' : /* this is a comment - skip everything */
+         for (;;)
+         {
+           T1_Int  left = limit - cur;
+
+           while (left > 0)
+           {
+             c = (char)base[cur++];
+             if ( c == '\r' || c == '\n' )
+               goto Next;
+             left--;
+           }
+           if ( grow( tokenizer ) ) goto Exit;
+           base  = tok->base;
+           limit = tok->limit;
+         }
+
+
+       case '(' : /* a Postscript string */
+         kind  = tok_string;
+         ender = ')';
+
+       L1:
+         if (!token_started)
+         {
+           token_started    = 1;
+           tok->token.start = cur-1;
+         }
+
+         {
+           T1_Int  nest_level = 1;
+
+           starter = c;
+           for (;;)
+           {
+             T1_Int  left = limit-cur;
+             while (left > 0)
+             {
+               c = (char)base[cur++];
+
+               if ( c == starter )
+                 nest_level++;
+
+               else if ( c == ender )
+               {
+                 nest_level--;
+                 if (nest_level <= 0)
+                 {
+                   tok->token.kind = kind;
+                   tok->token.len  = cur - tok->token.start;
+                   goto Exit;
+                 }
+               }
+               left--;
+             }
+
+             if ( grow( tok ) ) goto Exit;
+             base  = tok->base;
+             limit = tok->limit;
+           }
+         }
+
+
+     case '[' : /* a Postscript array */
+       if (token_started)
+         goto Any_Token;
+
+       kind  = tok_array;
+       ender = ']';
+       goto L1;
+       break;
+
+
+     case '{' : /* a Postscript program */
+       if (token_started)
+         goto Any_Token;
+
+       kind  = tok_program;
+       ender = '}';
+       goto L1;
+       break;
+
+
+     case '<' : /* a Postscript hex byte array ?? */
+       if (token_started)
+         goto Any_Token;
+
+       kind  = tok_hexarray;
+       ender = '>';
+       goto L1;
+       break;
+
+
+     case '0':  /* any number */
+     case '1':
+     case '2':
+     case '3':
+     case '4':
+     case '5':
+     case '6':
+     case '7':
+     case '8':
+     case '9':
+       if (token_started)
+         goto Next;
+
+       tok->token.kind = tok_number;
+       token_started    = 1;
+       tok->token.start = cur-1;
+     L2:
+       for (;;)
+       {
+         T1_Int  left = limit-cur;
+         while (left > 0)
+         {
+           c = (char)base[cur++];
+
+           switch (c)
+           {
+             case '[':
+             case '{':
+             case '(':
+             case '<':
+             case '/':
+               goto Any_Token;           
+
+             case  ' ':
+             case '\r':
+             case '\t':
+             case '\n':
+               tok->token.len = cur - tok->token.start - 1;
+               goto Exit;
+
+             default:
+               ;
+           }
+           left--;
+         }
+         if (grow( tok )) goto Exit;
+         base  = tok->base;
+         limit = tok->limit;
+       }
+
+
+     case '.':   /* maybe a number */
+     case '-':
+     case '+':
+       if (token_started)
+         goto Next;
+         
+       token_started    = 1;
+       tok->token.start = cur-1;
+       for (;;)
+       {
+         T1_Int  left = limit-cur;
+         if ( left > 0 )
+         {
+           /* test for any following digit, interpreted as number */
+           c = (char)base[cur];
+           tok->token.kind = ( c >= '0' && c <= '9' ? tok_number : tok_any );
+           goto L2;
+         }
+         if (grow( tok )) goto Exit;
+         base  = tok->base;
+         limit = tok->limit;
+       }
+
+     case '/':  /* maybe an immediate name */
+       if (!token_started)
+       {
+         token_started    = 1;
+         tok->token.start = cur-1;
+
+         for (;;)
+         {
+           T1_Int  left = limit-cur;
+           if ( left > 0 )
+           {
+             /* test for single '/', interpreted as garbage */
+             c = (char)base[cur];
+             tok->token.kind = ( c == ' '  || c == '\t' ||
+                                 c == '\r' || c == '\n' ?
+                                 tok_any : tok_immediate );
+             goto L2;
+           }
+           if (grow( tok )) goto Exit;
+           base  = tok->base;
+           limit = tok->limit;
+         }
+       }
+       else
+       {
+   Any_Token:        /* possibly a name or wathever */
+         cur--;
+         tok->token.len = cur - tok->token.start;
+         goto Exit;
+       }
+
+     default:
+       if (!token_started)
+       {
+         token_started    = 1;
+         tok->token.start = cur-1;
+       }
+     }
+
+ Next:
+   ;
+   }
+
+ Exit:
+   tok->cursor = cur;
+
+   if (!tok->error)
+   {
+     /* now, tries to match keywords and immediate names */
+     T1_Int  index;
+
+     switch ( tok->token.kind )
+     {
+       case tok_immediate :  /* immediate name */
+         index = Find_Name( (char*)(tok->base + tok->token.start+1),
+                            tok->token.len-1,
+                            t1_immediates,
+                            imm_max - imm_first_ );
+         tok->token.kind2 = ( index >= 0 ? imm_first_ + index : 0 );
+         break;
+
+
+       case tok_any : /* test for keyword */
+         index = Find_Name( (char*)(tok->base + tok->token.start),
+                	    tok->token.len,
+                            t1_keywords,
+                            key_max - key_first_ );
+         if ( index >= 0 )
+         {
+           tok->token.kind  = tok_keyword;
+           tok->token.kind2 = key_first_ + index;
+         }
+         else
+           tok->token.kind2 = 0;
+         break;
+
+       default:
+         tok->token.kind2 = 0;
+     }
+   }
+   return tokenizer->error;
+ }
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> Read_CharStrings                                          */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     Read a charstrings from the current input stream. These are       */
+ /*     binary bytes that encode each individual glyph outline.           */
+ /*                                                                       */
+ /*     The caller is responsible for skipping the "lenIV" bytes at       */
+ /*     the start of the record..                                         */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     tokenizer :: target tokenizer object                              */
+ /*     num_chars :: number of binary bytes to read                       */
+ /*                                                                       */
+ /*  <Output>                                                             */
+ /*     buffer    :: target array of bytes. These are eexec-decrypted..   */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+ /*  <Note>                                                               */
+ /*     One should use the function Read_CharStrings to read the binary   */
+ /*     charstrings from the private dict..                               */
+ /*                                                                       */
+ LOCAL_FUNC
+ T1_Error  Read_CharStrings( T1_Tokenizer  tokenizer,
+                             T1_Int        num_chars,
+                             T1_Byte*      buffer )
+ {
+   for (;;)
+   {
+     T1_Int  left = tokenizer->limit - tokenizer->cursor;
+
+     if ( left >= num_chars )
+     {
+       MEM_Copy( buffer, tokenizer->base + tokenizer->cursor, num_chars );
+       t1_decrypt( buffer, num_chars, 4330 );
+       tokenizer->cursor += num_chars;
+       return T1_Err_Ok;
+     }
+
+     if ( grow(tokenizer) ) return tokenizer->error;
+   }
+ }
+
diff --git a/src/type1/t1tokens.h b/src/type1/t1tokens.h
new file mode 100644
index 0000000..d83148b
--- /dev/null
+++ b/src/type1/t1tokens.h
@@ -0,0 +1,352 @@
+/*******************************************************************
+ *
+ *  t1tokens.h
+ *
+ *  Type 1 tokenizer
+ *
+ *  Copyright 1996 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 tokenizer is in charge of loading and reading a Type1 font
+ *  file (either in PFB or PFA format), and extract successive tokens
+ *  and keywords from its two streams (i.e. the font program, and the
+ *  private dictionary).
+ *
+ *  Eexec decryption is performed automatically when entering the
+ *  private dictionary, or when retrieving char strings..
+ *
+ ******************************************************************/
+
+#ifndef T1TOKENS_H
+#define T1TOKENS_H
+
+#include <t1objs.h>
+
+/* enum value of first keyword */
+#define key_first_     100
+
+/* enum value of first immediate name */
+#define imm_first_     200
+
+  typedef  enum T1_TokenType_
+  {
+    tok_error = 0,
+
+    tok_eof,             /* end of file              */
+
+    /* simple token types */
+
+    tok_keyword,         /* keyword                      */
+    tok_number,          /* number (integer or real)     */
+    tok_string,          /* postscript string            */
+    tok_program,         /* postscript program           */
+    tok_immediate,       /* any immediate name           */
+    tok_array,           /* matrix, array, etc..         */
+    tok_hexarray,        /* array of hexadecimal nibbles */
+    tok_any,             /* anything else                */
+
+    /* Postscript keywords - placed in lexicographical order */
+
+    key_RD_alternate = key_first_,      /* "-|" = alternate form of RD */
+	key_ExpertEncoding,
+    key_ND,
+    key_NP,
+    key_RD,
+	key_StandardEncoding,
+    key_array,
+    key_begin,
+    key_closefile,
+    key_currentdict,
+    key_currentfile,
+    key_def,
+    key_dict,
+    key_dup,
+    key_eexec,
+    key_end,
+    key_execonly,
+    key_false,
+    key_for,
+    key_index,
+    key_noaccess,
+    key_put,
+    key_readonly,
+    key_true,
+    key_userdict,
+    key_NP_alternate,                   /* "|" = alternate form of NP  */
+    key_ND_alternate,                   /* "|-" = alternate form of ND */
+
+    key_max,   /* always keep this value there */
+
+    /* Postscript immediate names - other names will be ignored, except */
+    /* in charstrings..                                                 */
+
+    imm_RD_alternate = imm_first_,      /* "-|" = alternate form of RD */
+    imm_notdef,                         /* "/.notdef" immediate        */
+    imm_BlueFuzz,
+    imm_BlueScale,
+    imm_BlueShift,
+    imm_BlueValues,
+    imm_CharStrings,
+    imm_Encoding,
+    imm_FamilyBlues,
+    imm_FamilyName,
+    imm_FamilyOtherBlues,
+    imm_FID,
+    imm_FontBBox,
+    imm_FontID,
+    imm_FontInfo,
+    imm_FontMatrix,
+    imm_FontName,
+    imm_FontType,
+    imm_ForceBold,
+    imm_FullName,
+    imm_ItalicAngle,
+    imm_LanguageGroup,
+    imm_Metrics,
+    imm_MinFeature,
+    imm_ND,
+    imm_NP,
+    imm_Notice,
+    imm_OtherBlues,
+    imm_OtherSubrs,
+    imm_PaintType,
+    imm_Private,
+    imm_RD,
+    imm_RndStemUp,
+    imm_StdHW,
+    imm_StdVW,
+    imm_StemSnapH,
+    imm_StemSnapV,
+    imm_StrokeWidth,
+    imm_Subrs,
+    imm_UnderlinePosition,
+    imm_UnderlineThickness,
+    imm_UniqueID,
+    imm_Weight,
+
+    imm_isFixedPitch,
+    imm_lenIV,
+    imm_password,
+    imm_version,
+
+    imm_NP_alternate,                   /* "|"  = alternate form of NP  */
+    imm_ND_alternate,                   /* "|-" = alternate form of ND  */
+
+    imm_max   /* always keep this value here */
+
+  } T1_TokenType;
+
+
+  /* these arrays are visible for debugging purposes.. */
+  extern const  char*  t1_keywords[];
+  extern const  char*  t1_immediates[];
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Struct> T1_Token                                                    */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     A structure used to describe a token in the current input         */
+ /*     stream. Note that the Type1 driver doesn't try to interpret       */
+ /*     tokens until it really needs to..                                 */
+ /*                                                                       */
+ /*  <Fields>                                                             */
+ /*     kind  :: token type. Describes the token to the loader            */
+ /*     kind2 :: detailed token type.                                     */
+ /*                                                                       */
+ /*     start ::  index of first character of token in input stream       */
+ /*                                                                       */
+ /*     len   ::  length of token in characters.                          */
+ /*                                                                       */
+  typedef struct T1_Token_
+  {
+    T1_TokenType   kind;     /* simple type                    */
+    T1_TokenType   kind2;    /* detailed type                  */
+    T1_Int         start;    /* index of first token character */
+    T1_Int         len;      /* length of token in chars       */
+
+  } T1_Token;
+
+
+
+
+  typedef  struct  T1_TokenParser_
+  {
+    FT_Memory   memory;
+    FT_Stream   stream;
+
+    T1_Bool     in_pfb;      /* true if PFB file, PFA otherwise */
+    T1_Bool     in_private;  /* true if in private dictionary   */
+
+    T1_Byte*    base;        /* base address of current read buffer */
+    T1_Long     cursor;      /* current position in read buffer     */
+    T1_Long     limit;       /* limit of current read buffer        */
+    T1_Long     max;         /* maximum size of read buffer         */
+
+    T1_Error    error;       /* last error                          */
+    T1_Token    token;       /* last token read                     */
+
+  } T1_TokenParser;
+
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Type> T1_Tokenizer                                                  */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     A handle to an object used to extract tokens from the input.      */
+ /*     The object is able to perform PFA/PFB recognition, eexec          */
+ /*     decryption of the private dictionary, as well as eexec decryption */
+ /*     of the charstrings..                                              */
+ /*                                                                       */
+  typedef  T1_TokenParser*    T1_Tokenizer;
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> New_Tokenizer                                             */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     Creates a new tokenizer from a given input stream. This function  */
+ /*     automatically recognizes "pfa" or "pfb" files. The function       */
+ /*     "Read_Token" can then be used to extract successive tokens from   */
+ /*     the stream..                                                      */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     stream  :: input stream                                           */
+ /*                                                                       */
+ /*  <Output>                                                             */
+ /*     tokenizer :: handle to new tokenizer object..                     */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+ /*  <Note>                                                               */
+ /*     This function copies the stream handle within the object. Callers */
+ /*     should not discard "stream". This is done by the Done_Tokenizer   */
+ /*     function..                                                        */
+ /*                                                                       */
+ LOCAL_DEF
+ T1_Error  New_Tokenizer( FT_Stream      stream,
+                          T1_Tokenizer*  tokenizer );
+
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> Done_Tokenizer                                            */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     Closes a given tokenizer. This function will also close the       */
+ /*     stream embedded in the object..                                   */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     tokenizer :: target tokenizer object                              */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+ LOCAL_DEF
+ T1_Error  Done_Tokenizer( T1_Tokenizer  tokenizer );
+
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> Open_PrivateDict                                          */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     This function must be called to set the tokenizer to the private  */
+ /*     section of the Type1 file. It recognizes automatically the        */
+ /*     the kind of eexec encryption used (ascii or binary)..             */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     tokenizer :: target tokenizer object                              */
+ /*     lenIV     :: value of the "lenIV" variable..                      */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+ LOCAL_DEF
+ T1_Error  Open_PrivateDict( T1_Tokenizer  tokenizer );
+
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> Read_Token                                                */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     Read a new token from the current input stream. This function     */
+ /*     extracts a token from the font program until "Open_PrivateDict"   */
+ /*     has been called. After this, it returns tokens from the           */
+ /*     (eexec-encrypted) private dictionnary..                           */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     tokenizer :: target tokenizer object                              */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+ /*  <Note>                                                               */
+ /*     One should use the function Read_CharStrings to read the binary   */
+ /*     charstrings from the private dict..                               */
+ /*                                                                       */
+ LOCAL_DEF
+ T1_Error  Read_Token( T1_Tokenizer  tokenizer );
+
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> Read_CharStrings                                          */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     Read a charstrings from the current input stream. These are       */
+ /*     binary bytes that encode each individual glyph outline.           */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     tokenizer :: target tokenizer object                              */
+ /*     num_chars :: number of binary bytes to read                       */
+ /*                                                                       */
+ /*  <Output>                                                             */
+ /*     buffer    :: target array of bytes. These are eexec-decrypted..   */
+ /*                                                                       */
+ /*  <Return>                                                             */
+ /*     Type1 error code. 0 means success..                               */
+ /*                                                                       */
+ /*  <Note>                                                               */
+ /*     One should use the function Read_CharStrings to read the binary   */
+ /*     charstrings from the private dict..                               */
+ /*                                                                       */
+ LOCAL_DEF
+ T1_Error  Read_CharStrings( T1_Tokenizer  tokenizer,
+                             T1_Int        num_chars,
+                             T1_Byte*      buffer );
+
+
+ /*************************************************************************/
+ /*                                                                       */
+ /*  <Function> t1_decrypt                                                */
+ /*                                                                       */
+ /*  <Description>                                                        */
+ /*     Performs the Type 1 charstring decryption process..               */
+ /*                                                                       */
+ /*  <Input>                                                              */
+ /*     buffer  :: base address of data to decrypt                        */
+ /*     length  :: number of bytes to decrypt from base address           */
+ /*     seed    :: ecnryption seed (4330 for charstrings).                */
+ /*                                                                       */
+  LOCAL_DEF
+  void  t1_decrypt( T1_Byte*   buffer,
+                    T1_Int     length,
+                    T1_UShort  seed );
+
+#endif /* T1TOKENS_H */
diff --git a/src/type1/type1.c b/src/type1/type1.c
new file mode 100644
index 0000000..f7058d0
--- /dev/null
+++ b/src/type1/type1.c
@@ -0,0 +1,50 @@
+/***************************************************************************/
+/*                                                                         */
+/*  type1.c                                                                */
+/*                                                                         */
+/*  FreeType Type 1 driver component                                       */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/*                                                                         */
+/*  This file is used to compile the FreeType Type 1  font driver.         */
+/*  It relies on all components included in the "base" layer (see          */
+/*  the file "ftbase.c"). Source code is located in "freetype/ttlib"       */
+/*  and contains :                                                         */
+/*                                                                         */
+/*     - a driver interface                                                */
+/*     - an object manager                                                 */
+/*     - a table loader                                                    */
+/*     - a glyph loader                                                    */
+/*     - a glyph hinter                                                    */
+/*                                                                         */
+/***************************************************************************/
+
+
+
+#if 0
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+#include <t1driver.c>   /* driver interface  */
+#include <t1objs.c>     /* object manager    */
+#include <t1load.c>     /* table loader      */
+#include <t1hint.c>     /* hinter            */
+#include <t1gload.c>    /* glyph loader      */
+#endif
+
+#include <t1driver.c>
+#include <t1objs.c>
+#include <t1load.c>     /* table loader      */
+#include <t1gload.c>
+
+#include <t1tokens.c>
+#include <t1parse.c>
+#include <t1encode.c>
+#include <t1hinter.c>
+