shithub: freetype+ttf2subf

Download patch

ref: f0df85ba2a573c6c5c602667e9f91ef3b00c1d20
parent: 9ca2af38384a3fc3a26cc7eae96c59ad08aca2b2
author: David Turner <[email protected]>
date: Wed Jun 21 20:17:42 EDT 2000

- MAJOR INTERNAL REDESIGN:

    A lot of internal modifications have been performed lately on the
    source in order to provide the following enhancements:

      - more generic module support:

        The FT_Module type is now defined to represent a handle to a given
        module. The file <freetype/ftmodule.h> contains the FT_Module_Class
        definition, as well as the module-loading public API

        The FT_Driver type is still defined, and still represents a pointer
        to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
        FT_Get_Driver by FT_Get_Module, etc..


      - support for generic glyph image types:

        The FT_Renderer type is a pointer to a module used to perform various
        operations on glyph image.

        Each renderer is capable of handling images in a single format
        (e.g. ft_glyph_format_outline). Its functions are used to:

           - transform an glyph image
           - render a glyph image into a bitmap
           - return the control box (dimensions) of a given glyph image


        The scan converters "ftraster.c" and "ftgrays.c" have been moved
        to the new directory "src/renderer", and are used to provide two
        default renderer modules.

        One corresponds to the "standard" scan-converter, the other to the
        "smooth" one.

        The current renderer can be set through the new function
        FT_Set_Renderer.

        The old raster-related function FT_Set_Raster, FT_Get_Raster and
        FT_Set_Raster_Mode have now disappeared, in favor of the new:

           FT_Get_Renderer
           FT_Set_Renderer

        see the file <freetype/ftrender.h> for more details..

        These changes were necessary to properly support different scalable
        formats in the future, like bi-color glyphs, etc..


      - glyph loader object:

        A new internal object, called a 'glyph loader' has been introduced
        in the base layer. It is used by all scalable format font drivers
        to load glyphs and composites.

        This object has been created to reduce the code size of each driver,
        as each one of them basically re-implemented its functionality.

        See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
        more information..



      - FT_GlyphSlot had new fields:

        In order to support extended features (see below), the FT_GlyphSlot
        structure has a few new fields:

           linearHoriAdvance:  this field gives the linearly scaled (i.e.
                               scaled but unhinted) advance width for the glyph,
                               expressed as a 16.16 fixed pixel value. This
                               is useful to perform WYSIWYG text.

           linearVertAdvance:  this field gives the linearly scaled advance
                               height for the glyph (relevant in vertical glyph
                               layouts only). This is useful to perform
                               WYSIWYG text.

        Note that the two above field replace the removed "metrics2" field
        in the glyph slot.

           advance:   this field is a vector that gives the transformed
                      advance for the glyph. By default, it corresponds
                      to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
                      was specified when calling FT_Load_Glyph or FT_Load_Char

           bitmap_left: this field gives the distance in integer pixels from
                        the current pen position to the left-most pixel of
                        a glyph image WHEN IT IS A BITMAP. It is only valid
                        when the "format" field is set to
                        "ft_glyph_format_bitmap", for example, after calling
                        the new function FT_Render_Glyph.

           bitmap_top:  this field gives the distance in integer pixels from
                        the current pen position (located on the baseline) to
                        the top-most pixel of the glyph image WHEN IT IS A
                        BITMAP. Positive values correspond to upwards Y.

           loader:  this is a new private field for the glyph slot. Client
                    applications should not touch it..


      - support for transforms and direct rendering in FT_Load_Glyph:

        Most of the functionality found in <freetype/ftglyph.h> has been
        moved to the core library. Hence, the following:

          - a transform can be specified for a face through FT_Set_Transform.
            this transform is applied by FT_Load_Glyph to scalable glyph images
            (i.e. NOT TO BITMAPS) before the function returns, unless the
            bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..


          - once a glyph image has been loaded, it can be directly converted to
            a bitmap by using the new FT_Render_Glyph function. Note that this
            function takes the glyph image from the glyph slot, and converts
            it to a bitmap whose properties are returned in "face.glyph.bitmap",
            "face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
            native image might be lost after the conversion.


          - when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
            and FT_Load_Char functions will call FT_Render_Glyph automatically
            when needed.

git/fs: mount .git/fs: mount/attach disallowed
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,135 @@
 LATEST CHANGES
 
+  - MAJOR INTERNAL REDESIGN:
+  
+    A lot of internal modifications have been performed lately on the
+    source in order to provide the following enhancements:
+    
+      - more generic module support:
+      
+        The FT_Module type is now defined to represent a handle to a given
+        module. The file <freetype/ftmodule.h> contains the FT_Module_Class
+        definition, as well as the module-loading public API
+
+        The FT_Driver type is still defined, and still represents a pointer
+        to a font driver. Note that FT_Add_Driver is replaced by FT_Add_Module,
+        FT_Get_Driver by FT_Get_Module, etc..
+
+
+      - support for generic glyph image types:
+
+        The FT_Renderer type is a pointer to a module used to perform various
+        operations on glyph image.
+        
+        Each renderer is capable of handling images in a single format
+        (e.g. ft_glyph_format_outline). Its functions are used to:
+        
+           - transform an glyph image
+           - render a glyph image into a bitmap
+           - return the control box (dimensions) of a given glyph image
+
+
+        The scan converters "ftraster.c" and "ftgrays.c" have been moved
+        to the new directory "src/renderer", and are used to provide two
+        default renderer modules.
+        
+        One corresponds to the "standard" scan-converter, the other to the
+        "smooth" one.
+        
+        The current renderer can be set through the new function
+        FT_Set_Renderer.
+        
+        The old raster-related function FT_Set_Raster, FT_Get_Raster and
+        FT_Set_Raster_Mode have now disappeared, in favor of the new:
+        
+           FT_Get_Renderer
+           FT_Set_Renderer
+
+        see the file <freetype/ftrender.h> for more details..
+
+        These changes were necessary to properly support different scalable
+        formats in the future, like bi-color glyphs, etc..
+
+
+      - glyph loader object:
+
+        A new internal object, called a 'glyph loader' has been introduced
+        in the base layer. It is used by all scalable format font drivers
+        to load glyphs and composites.
+        
+        This object has been created to reduce the code size of each driver,
+        as each one of them basically re-implemented its functionality.
+
+        See <freetype/internal/ftobjs.h> and the FT_GlyphLoader type for
+        more information..
+
+
+
+      - FT_GlyphSlot had new fields:
+
+        In order to support extended features (see below), the FT_GlyphSlot
+        structure has a few new fields:
+        
+           linearHoriAdvance:  this field gives the linearly scaled (i.e.
+                               scaled but unhinted) advance width for the glyph,
+                               expressed as a 16.16 fixed pixel value. This
+                               is useful to perform WYSIWYG text.
+                               
+           linearVertAdvance:  this field gives the linearly scaled advance
+                               height for the glyph (relevant in vertical glyph
+                               layouts only). This is useful to perform
+                               WYSIWYG text.                               
+
+        Note that the two above field replace the removed "metrics2" field
+        in the glyph slot.
+        
+           advance:   this field is a vector that gives the transformed
+                      advance for the glyph. By default, it corresponds
+                      to the advance width, unless FT_LOAD_VERTICAL_LAYOUT
+                      was specified when calling FT_Load_Glyph or FT_Load_Char
+
+           bitmap_left: this field gives the distance in integer pixels from
+                        the current pen position to the left-most pixel of
+                        a glyph image WHEN IT IS A BITMAP. It is only valid
+                        when the "format" field is set to
+                        "ft_glyph_format_bitmap", for example, after calling
+                        the new function FT_Render_Glyph.
+                        
+           bitmap_top:  this field gives the distance in integer pixels from
+                        the current pen position (located on the baseline) to
+                        the top-most pixel of the glyph image WHEN IT IS A
+                        BITMAP. Positive values correspond to upwards Y.
+
+           loader:  this is a new private field for the glyph slot. Client
+                    applications should not touch it..
+
+
+      - support for transforms and direct rendering in FT_Load_Glyph:
+
+        Most of the functionality found in <freetype/ftglyph.h> has been
+        moved to the core library. Hence, the following:
+        
+          - a transform can be specified for a face through FT_Set_Transform.
+            this transform is applied by FT_Load_Glyph to scalable glyph images
+            (i.e. NOT TO BITMAPS) before the function returns, unless the
+            bit flag FT_LOAD_IGNORE_TRANSFORM was set in the load flags..
+
+
+          - once a glyph image has been loaded, it can be directly converted to
+            a bitmap by using the new FT_Render_Glyph function. Note that this
+            function takes the glyph image from the glyph slot, and converts
+            it to a bitmap whose properties are returned in "face.glyph.bitmap",
+            "face.glyph.bitmap_left" and "face.glyph.bitmap_top". The original
+            native image might be lost after the conversion.
+
+
+          - when using the new bit flag FT_LOAD_RENDER, the FT_Load_Glyph
+            and FT_Load_Char functions will call FT_Render_Glyph automatically
+            when needed.
+
+
+
+
   - reformated all modules source code in order to get rid of the basic
     data types redifinitions (i.e. "TT_Int" instead of "FT_Int", "T1_Fixed"
     instead of "FT_Fixed"). Hence the format-specific prefixes like "TT_",
--- a/config/modules.mk
+++ b/config/modules.mk
@@ -40,7 +40,7 @@
 #
 clean_module_list:
 	@-$(DELETE) $(subst $(SEP),$(HOSTSEP),$(FT_MODULE_LIST))
-	@-echo Regenerating the font drivers list in $(FT_MODULE_LIST)...
+	@-echo Regenerating the modules list in $(FT_MODULE_LIST)...
 
 make_module_list: clean_module_list
 	@echo done.
@@ -60,10 +60,10 @@
 # $(OPEN_DRIVER) & $(CLOSE_DRIVER) are used to specify a given font driver
 # in the `module.mk' rules file.
 #
-OPEN_DRIVER  := $(OPEN_MODULE)FT_DRIVER(
+OPEN_DRIVER  := $(OPEN_MODULE)FT_USE_MODULE(
 CLOSE_DRIVER := )$(CLOSE_MODULE)
 
-ECHO_DRIVER      := @echo "* driver: #
+ECHO_DRIVER      := @echo "* module: #
 ECHO_DRIVER_DESC := (
 ECHO_DRIVER_DONE := )"
 
--- a/demos/src/ftmulti.c
+++ b/demos/src/ftmulti.c
@@ -13,8 +13,7 @@
 /****************************************************************************/
 
 #include <freetype/freetype.h>
-#include <freetype/ftraster.h>
-#include <freetype/ftgrays.h>
+#include <freetype/ftrender.h>
 #include <freetype/ftmm.h>
 
 #include "common.h"
@@ -76,7 +75,8 @@
   int  use_grays   = 1;
 
   /* the standard raster's interface */
-  FT_Raster_Funcs  std_raster;
+  FT_Renderer   std_renderer;
+  FT_Renderer   smooth_renderer;
 
   FT_Multi_Master  multimaster;
   FT_Long          design_pos[T1_MAX_MM_AXIS];
@@ -460,10 +460,10 @@
   static
   void  reset_raster( void )
   {
-    if ( antialias && use_grays )
-      FT_Set_Raster( library, &ft_grays_raster );
+    if ( antialias && use_grays && smooth_renderer )
+      FT_Set_Renderer( library, smooth_renderer, 0, 0 );
     else
-      FT_Set_Raster( library, &std_raster );
+      FT_Set_Renderer( library, std_renderer, 0, 0 );
   }
 
 
@@ -715,8 +715,11 @@
       PanicZ( "Could not initialize FreeType library" );
 
     /* retrieve the standard raster's interface */
-    (void)FT_Get_Raster( library, ft_glyph_format_outline, &std_raster );
-    reset_raster();
+    std_renderer = (FT_Renderer)FT_Get_Module( library, "standard renderer" );
+    if (!std_renderer)
+      PanicZ( "Could not retrieve standard renderer" );
+
+    smooth_renderer = (FT_Renderer)FT_Get_Module( library, "smooth renderer" );
 
   NewFile:
     ptsize      = orig_ptsize;
--- a/demos/src/ftstring.c
+++ b/demos/src/ftstring.c
@@ -11,6 +11,7 @@
 /****************************************************************************/
 
 #include <freetype/freetype.h>
+#include <freetype/ftrender.h>
 #include <freetype/ftglyph.h>
 #include "common.h"
 
@@ -64,7 +65,8 @@
   static int  use_grays   = 1;
 
   /* the standard raster's interface */
-  static FT_Raster_Funcs  std_raster;
+  FT_Renderer   std_renderer;
+  FT_Renderer   smooth_renderer;
 
   static FT_Matrix      trans_matrix;
   static int            transform = 0;
@@ -470,14 +472,10 @@
 
   static void  reset_raster( void )
   {
-    FT_Error  error;
-
-    error = 1;
-    if ( use_grays && antialias )
-      error = FT_Set_Raster( library, &ft_grays_raster );
-
-    if (error)
-      (void)FT_Set_Raster( library, &std_raster );
+    if ( antialias && use_grays && smooth_renderer )
+      FT_Set_Renderer( library, smooth_renderer, 0, 0 );
+    else
+      FT_Set_Renderer( library, std_renderer, 0, 0 );
   }
 
 
@@ -673,7 +671,11 @@
     if (error) PanicZ( "Could not initialise FreeType library" );
 
     /* retrieve the standard raster's interface */
-    (void)FT_Get_Raster( library, ft_glyph_format_outline, &std_raster );
+    std_renderer = (FT_Renderer)FT_Get_Module( library, "standard renderer" );
+    if (!std_renderer)
+      PanicZ( "Could not retrieve standard renderer" );
+
+    smooth_renderer = (FT_Renderer)FT_Get_Module( library, "smooth renderer" );
 
   NewFile:
     ptsize      = orig_ptsize;
--- a/demos/src/fttimer.c
+++ b/demos/src/fttimer.c
@@ -20,6 +20,7 @@
 /****************************************************************************/
 
 #include <freetype/freetype.h>
+#include <freetype/ftrender.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -331,8 +332,12 @@
     /* set-up smooth anti-aliaser */
     if (use_grays)
     {
-      error = FT_Set_Raster( library, &ft_grays_raster );
-      if (error) Panic( "Could not initialize smooth anti-aliasing renderer" );
+      FT_Renderer  smooth;
+      
+      smooth = (FT_Renderer)FT_Get_Module( library, "smooth renderer" );
+      if (!smooth) Panic( "Could not initialize smooth anti-aliasing renderer" );
+      
+      FT_Set_Renderer( library, smooth, 0, 0 );
     }
 
     /* Load face */
--- a/demos/src/ftview.c
+++ b/demos/src/ftview.c
@@ -17,8 +17,7 @@
 
 
 #include <freetype/freetype.h>
-#include <freetype/ftraster.h>
-#include <freetype/ftgrays.h>
+#include <freetype/ftrender.h>
 
   /* the following header shouldn't be used in normal programs */
 #include <freetype/internal/ftdebug.h>
@@ -84,8 +83,10 @@
   int  trace_level = 0;
 
   /* the standard raster's interface */
-  FT_Raster_Funcs  std_raster;
+  FT_Renderer   std_renderer;
+  FT_Renderer   smooth_renderer;
 
+
 #define RASTER_BUFF_SIZE   32768
   char  raster_buff[RASTER_BUFF_SIZE];
 
@@ -458,10 +459,10 @@
   static
   void  reset_raster( void )
   {
-    if ( antialias && use_grays )
-      FT_Set_Raster( library, &ft_grays_raster );
+    if ( antialias && use_grays && smooth_renderer )
+      FT_Set_Renderer( library, smooth_renderer, 0, 0 );
     else
-      FT_Set_Raster( library, &std_raster );
+      FT_Set_Renderer( library, std_renderer, 0, 0 );
   }
 
 
@@ -672,8 +673,12 @@
       PanicZ( "Could not initialize FreeType library" );
 
     /* retrieve the standard raster's interface */
-    (void)FT_Get_Raster( library, ft_glyph_format_outline, &std_raster );
+    std_renderer = (FT_Renderer)FT_Get_Module( library, "standard renderer" );
+    if (!std_renderer)
+      PanicZ( "Could not retrieve standard renderer" );
 
+    smooth_renderer = (FT_Renderer)FT_Get_Module( library, "smooth renderer" );
+      
   NewFile:
     ptsize      = orig_ptsize;
     hinted      = 1;
--- a/demos/src/memtest.c
+++ b/demos/src/memtest.c
@@ -224,7 +224,7 @@
 
     /* the new library has no drivers in it, add the default ones */
     /* (implemented in ftinit.c)..                                */
-    FT_Default_Drivers(library);
+    FT_Add_Default_Modules(library);
 
 
     /* Now check all files */
--- a/demos/src/ttdebug.c
+++ b/demos/src/ttdebug.c
@@ -1203,7 +1203,7 @@
     if (error) Panic( "could not initialise FreeType library" );
 
     memory = library->memory;
-    driver = FT_Get_Driver( library, "truetype" );
+    driver = (FT_Driver)FT_Get_Module( library, "truetype" );
     if (!driver) Panic( "could not find the TrueType driver in FreeType 2\n" );
 
     FT_Set_Debug_Hook( library,
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -1,7 +1,9 @@
-FT_DRIVER(cff_driver_interface)
-FT_DRIVER(t1cid_driver_interface)
-FT_DRIVER(psnames_driver_interface)
-FT_DRIVER(sfnt_driver_interface)
-FT_DRIVER(tt_driver_interface)
-FT_DRIVER(t1_driver_interface)
-FT_DRIVER(t1z_driver_interface)
+FT_USE_MODULE(cff_driver_class)
+FT_USE_MODULE(t1cid_driver_class)
+FT_USE_MODULE(psnames_module_class)
+FT_USE_MODULE(ft_standard_renderer_class)
+FT_USE_MODULE(ft_smooth_renderer_class)
+FT_USE_MODULE(sfnt_module_class)
+FT_USE_MODULE(tt_driver_class)
+FT_USE_MODULE(t1_driver_class)
+FT_USE_MODULE(t1z_driver_class)
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -251,16 +251,12 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /*    FT_MAX_DRIVERS                                                     */
+  /*    FT_MAX_MODULES                                                     */
   /*                                                                       */
-  /*    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 ;-)                   */
+  /*    The maximum number ofmodules that can be registered in a single    */
+  /*    FreeType library object. 16 seems to be a good choice for now :-)  */
   /*                                                                       */
-  /*    If you don't intend to register new drivers at runtime, you        */
-  /*    certainly do not need to change this value..                       */
-  /*                                                                       */
-#define FT_MAX_DRIVERS  8
+#define FT_MAX_MODULES  16
 
 
   /*************************************************************************/
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -212,6 +212,19 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Type>                                                                */
+  /*    FT_Module                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a given FreeType module object. Each module can be     */
+  /*    a font driver, a renderer, or anything else that provides services */
+  /*    to the formers..                                                   */
+  /*                                                                       */
+  typedef struct FT_ModuleRec_*  FT_Module;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
   /*    FT_Driver                                                          */
   /*                                                                       */
   /* <Description>                                                         */
@@ -225,9 +238,25 @@
   typedef struct FT_DriverRec_*  FT_Driver;
 
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Type>                                                                */
+  /*    FT_Renderer                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A handle to a given FreeType renderer. A renderer is in charge     */
+  /*    of converting a glyph image to a bitmap, when necessary. Each      */
+  /*    supports a given glyph image format, and one or more target        */
+  /*    surface depths..                                                   */
+  /*                                                                       */
+  typedef struct FT_RendererRec_*  FT_Renderer;
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
   /*    FT_Face                                                            */
   /*                                                                       */
   /* <Description>                                                         */
@@ -607,7 +636,7 @@
 
     /************************************************************/
     /* The following fields should be considered private and    */
-    /* rarely, if ever, used by client applications..           */
+    /* rarely, if ever, used driectly by client applications..  */
 
     FT_Driver        driver;
     FT_Memory        memory;
@@ -750,6 +779,19 @@
 #define FT_FACE_FLAG_MULTIPLE_MASTERS  0x100
 
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_FACE_FLAG_EXTERNAL_STREAM                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This bit field is used internally by FreeType to indicate that     */
+  /*    a face's stream was provided by the client application and should  */
+  /*    not be destroyed by FT_Done_Face                                   */
+  /*                                                                       */
+#define FT_FACE_FLAG_EXTERNAL_STREAM   0x4000
+
+
 #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)
@@ -921,6 +963,25 @@
 #define FT_SUBGLYPH_FLAG_USE_MY_METRICS        0x200
 
 
+ /**********************************************************************
+  *
+  *  <Struct>
+  *     FT_Glyph_Loader
+  *
+  *  <Description>
+  *     The glyph loader is an internal object used to load several
+  *     glyphs together (for example, in the case of composites)
+  *
+  *  <Note>
+  *     the glyph loader implementation is not part of the high-level
+  *     API, hence the forward structure declaration;
+  *
+  *
+  *********************************************************************/
+  
+  typedef struct FT_GlyphLoader_    FT_GlyphLoader;
+
+  
   /*************************************************************************/
   /*                                                                       */
   /*                  FreeType Glyph Slot base class                       */
@@ -941,36 +1002,105 @@
   /*                rare, the glyph slots are listed through a direct,     */
   /*                single-linked list using its `next' field.             */
   /*                                                                       */
+  /*    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  :: 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 is used to return alternate glyph metrics   */
-  /*                for scalable formats. Only four fields in it are       */
-  /*                valid: horiBearingX, horiAdvance, vertBearingY and     */
-  /*                vertAdvance. All other fields should be ignored.       */
-  /*                By default, it contains the glyph metrics expressed    */
-  /*                in font units. However, when FT_Load_Glyph() is called */
-  /*                with FT_LOAD_LINEAR set, the metrics are expressed     */
-  /*                in 16.16 unhinted pixel values.. This can be useful    */
-  /*                to perform WYSIWYG glyph layout..                      */
+  /*                Note that even when the glyph image is transformed,    */
+  /*                the metrics aren't..                                   */
   /*                                                                       */
-  /*    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.                                           */
+  /*    linearHoriAdvance :: For scalable formats only, this field holds   */
+  /*                         the linearly scaled horizontal advance width  */
+  /*                         for the glyph (i.e. the scaled and unhinted   */
+  /*                         value of the hori advance). This can be       */
+  /*                         important to perform correct WYSIWYG layout   */
   /*                                                                       */
-  /*    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().                           */
+  /*                         Note that this value is expressed by default  */
+  /*                         in 16.16 pixels. However, when the glyph is   */
+  /*                         loaded with the FT_LOAD_UNSCALED_LINEAR flag, */
+  /*                         this field contains simply the value of the   */
+  /*                         advance in original font units.               */
   /*                                                                       */
-  /*    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().                           */
+  /*    linearVertAdvance :: For scalable formats only, this field holds   */
+  /*                         the linearly scaled vertical advance height   */
+  /*                         for the glyph. See linearHoriAdvance for      */
+  /*                         comments.                                     */
   /*                                                                       */
+  /*    advance  :: this is the transformed advance width for the glyph    */
+  /*                                                                       */
+  /*    format   :: this field indicates the format of the image           */
+  /*                contained in the glyph slot. Typically                 */
+  /*                ft_glyph_format_bitmap, ft_glyph_format_outline        */
+  /*                & ft_glyph_format_composite, but others are possible   */
+  /*                                                                       */
+  /*    bitmap   :: this field is used as a bitmap descriptor when the     */
+  /*                slot format is ft_glyph_format_bitmap. Note that       */
+  /*                the address and content of the bitmap buffer can       */
+  /*                change between calls of FT_Load_Glyph and a few        */
+  /*                other functions.                                       */
+  /*                                                                       */
+  /*    bitmap_left  :: this is the bitmap's left bearing expressed in     */
+  /*                    integer pixels. Of course, this is only valid      */
+  /*                    when the format is ft_glyph_format_bitmap          */
+  /*                                                                       */
+  /*    bitmap_top   :: this is the bitmap's top bearing expressed in      */
+  /*                    integer pixels. Remember that this is the          */
+  /*                    distance from the baseline to the top-most         */
+  /*                    glyph scanline, upwards y coordinates being        */
+  /*                    *positive*                                         */
+  /*                                                                       */
+  /*    outline  :: The outline descriptor for the current glyph image     */
+  /*                when it's format is ft_glyph_bitmap_outline.           */
+  /*                                                                       */
+  /*    num_subglyphs :: the number of subglyphs in a composite glyph.     */
+  /*                     this format is only valid for the composite       */
+  /*                     glyph format, that should normally only be        */
+  /*                     loaded with the FT_LOAD_NO_RECURSE flag..         */
+  /*                                                                       */
+  /*    subglyphs     :: an array of subglyph descriptors for composite    */
+  /*                     glyphs. There are 'num_subglyphs' elements in     */
+  /*                     in there..                                        */
+  /*                                                                       */
+  /*    control_data  :: certain font drivers can also return the control  */
+  /*                     data for a given glyph image (e.g. TrueType       */
+  /*                     bytecode, Type 1 charstrings, etc..). This field  */
+  /*                     is a pointer to such data..                       */
+  /*                                                                       */
+  /*    control_len   :: this is the length in bytes of the control data   */
+  /*                                                                       */
+  /*    other         :: really wicked format can use this pointer to      */
+  /*                     present their own glyph image to client apps.     */
+  /*                     Note that the app will need to know about the     */
+  /*                     image format,                                     */
+  /*                                                                       */
+  /*    loader        :: this is a private object for the glyph slot. Do   */
+  /*                     not touch this..                                  */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    When FT_Load_Glyph is called with default flags (FT_LOAD_DEFAULT), */
+  /*    the glyph image is loaded in the glyph slot in its native format   */
+  /*    (e.g. a vectorial outline for TrueType and Type 1 formats)         */
+  /*                                                                       */
+  /*    This image can later be converted into a bitmap by calling         */
+  /*    FT_Render_Glyph. This function finds the current renderer for the  */
+  /*    native image's format then invokes it.                             */
+  /*                                                                       */
+  /*    The renderer is in charge of transforming the native image through */
+  /*    the slot's face transformation fields, then convert it into a      */
+  /*    bitmap that is returned in "slot->bitmap".                         */
+  /*                                                                       */
+  /*    Note that "slot->bitmap_left" and "slot->bitmap_top" are also      */
+  /*    used to specify the position of the bitmap relative to the current */
+  /*    pen position (e.g. coordinates [0,0] on the baseline). Of course,  */
+  /*    "slot->format" is also changed to "ft_glyph_format_bitmap"..       */
+  /*                                                                       */
+  /*                                                                       */
 
   enum
   {
@@ -977,21 +1107,29 @@
     ft_glyph_own_bitmap = 1
   };
 
+
+
   typedef struct  FT_GlyphSlotRec_
   {
     FT_Face           face;
     FT_GlyphSlot      next;
     FT_UInt           flags;
+    FT_Generic        generic;
 
     FT_Glyph_Metrics  metrics;
-    FT_Glyph_Metrics  metrics2;
+    FT_Fixed          linearHoriAdvance;
+    FT_Fixed          linearVertAdvance;
+    FT_Vector         advance;
 
     FT_Glyph_Format   format;
+    
     FT_Bitmap         bitmap;
+    FT_Int            bitmap_left;
+    FT_Int            bitmap_top;
+    
     FT_Outline        outline;
 
-    FT_Int            num_subglyphs;
-    FT_Int            max_subglyphs;
+    FT_UInt           num_subglyphs;
     FT_SubGlyph*      subglyphs;
 
     void*             control_data;
@@ -999,6 +1137,9 @@
 
     void*             other;
 
+    /* private fields */
+    FT_GlyphLoader*   loader;
+
   } FT_GlyphSlotRec;
 
 
@@ -1149,7 +1290,7 @@
     FT_Long        memory_size;
     FT_String*     pathname;
     FT_Stream      stream;
-    FT_Driver      driver;
+    FT_Module      driver;
     FT_Int         num_params;
     FT_Parameter*  params;
 
@@ -1438,6 +1579,15 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    If the glyph image is not a bitmap, and if the bit flag            */
+  /*    FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be         */
+  /*    transformed with the information passed to a previous call to      */
+  /*    FT_Set_Transform.                                                  */
+  /*                                                                       */
+  /*    Note that this also transforms the "face.glyph.advance" field,     */
+  /*    but **NOT** the values in "face.glyph.metrics"..                   */
+  /*                                                                       */
   FT_EXPORT_DEF(FT_Error)   FT_Load_Glyph( FT_Face  face,
                                            FT_UInt  glyph_index,
                                            FT_Int   load_flags );
@@ -1472,6 +1622,14 @@
   /*    is not defined in the charmap, this function will return an        */
   /*    error..                                                            */
   /*                                                                       */
+  /*    If the glyph image is not a bitmap, and if the bit flag            */
+  /*    FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be         */
+  /*    transformed with the information passed to a previous call to      */
+  /*    FT_Set_Transform.                                                  */
+  /*                                                                       */
+  /*    Note that this also transforms the "face.glyph.advance" field,     */
+  /*    but **NOT** the values in "face.glyph.metrics"..                   */
+  /*                                                                       */
   FT_EXPORT_DEF(FT_Error)   FT_Load_Char( FT_Face   face,
                                           FT_ULong  char_code,
                                           FT_Int    load_flags );
@@ -1507,15 +1665,17 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Constant>                                                            */
-  /*    FT_LOAD_NO_OUTLINE                                                 */
+  /*    FT_LOAD_RENDER                                                     */
   /*                                                                       */
   /* <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.    */
+  /*    the function should load the glyph and immediately convert it      */
+  /*    into a bitmap, when necessary, by calling FT_Render_Glyph.         */
   /*                                                                       */
-#define FT_LOAD_NO_OUTLINE  4
+  /*    Note that by default, FT_Load_Glyph loads the glyph image in its   */
+  /*    native format..                                                    */
+  /*                                                                       */
+#define FT_LOAD_RENDER     4
 
 
   /*************************************************************************/
@@ -1526,8 +1686,9 @@
   /* <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.    */
+  /*    glyph.  This is useful when you do not want to load the embedded   */
+  /*    bitmaps of scalable formats, as the native glyph image will be     */
+  /*    loaded, and can then be renderer through FT_Render_Glyph           */
   /*                                                                       */
 #define FT_LOAD_NO_BITMAP  8
 
@@ -1535,16 +1696,19 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Constant>                                                            */
-  /*    FT_LOAD_LINEAR                                                     */
+  /*    FT_LOAD_VERTICAL_LAYOUT                                            */
   /*                                                                       */
   /* <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.        */
+  /*    the glyph image should be prepared for vertical layout. This       */
+  /*    basically means that "face.glyph.advance" will correspond to the   */
+  /*    vertical advance height (instead of the default horizontal         */
+  /*    advance width), and that the glyph image will translated to        */
+  /*    match the vertical bearings positions..                            */
   /*                                                                       */
-#define FT_LOAD_LINEAR  16
+#define FT_LOAD_VERTICAL_LAYOUT  16
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Constant>                                                            */
@@ -1557,6 +1721,7 @@
   /*                                                                       */
 #define FT_LOAD_FORCE_AUTOHINT  32
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Constant>                                                            */
@@ -1571,6 +1736,7 @@
   /*                                                                       */
 #define FT_LOAD_CROP_BITMAP  64
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Constant>                                                            */
@@ -1601,6 +1767,7 @@
   /*                                                                       */
 #define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 512
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Constant>                                                            */
@@ -1621,9 +1788,52 @@
   /*                                                                       */
 #define FT_LOAD_NO_RECURSE 1024
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Constant>                                                            */
+  /*    FT_LOAD_IGNORE_TRANSFORM                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the glyph loader should not try to transform the loaded glyph      */
+  /*    image.                                                             */
+  /*                                                                       */
+#define FT_LOAD_IGNORE_TRANSFORM 2048
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_ANTI_ALIAS                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Only used with FT_LOAD_RENDER set, indicates that the returned     */
+  /*    glyph image should be anti-aliased. This basically tells the       */
+  /*    glyph loader to use 'ft_render_mode_antialias' when calling        */
+  /*    FT_Render_Glyph.                                                   */
+  /*                                                                       */
+  /*                                                                       */
+#define FT_LOAD_LINEAR_ANTI_ALIAS  4096
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_LOAD_LINEAR_DESIGN                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Load_Glyph() to indicate that   */
+  /*    the function should return the linearly scaled metrics expressed   */
+  /*    in original font units, instead of the default 16.16 pixel values. */
+  /*                                                                       */
+#define FT_LOAD_LINEAR_DESIGN 8192
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
   /*    FT_LOAD_DEFAULT                                                    */
   /*                                                                       */
   /* <Description>                                                         */
@@ -1638,6 +1848,69 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Set_Transform                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function used to set the transformation that is applied to glyph */
+  /*    images just before they're converted to bitmaps in a glyph slot    */
+  /*    when FT_Render_Glyph is called..                                   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    face   :: A handle to the source face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    matrix :: A pointer to the transformation's 2x2 matrix.  Use 0 for */
+  /*              the identity matrix.                                     */
+  /*    delta  :: A pointer to the translation vector.  Use 0 for the null */
+  /*              vector.                                                  */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The transformation is only applied to scalable image formats.      */
+  /*                                                                       */
+  FT_EXPORT_DEF( void )  FT_Set_Transform( FT_Face     face,
+                                           FT_Matrix*  matrix,
+                                           FT_Vector*  delta );
+
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Render_Glyph
+  *
+  *  <Description>
+  *     Converts a given glyph image to a bitmap. It does so by inspecting
+  *     the glyph image format, find the relevant renderer, and invoke it
+  *
+  *  <Input>
+  *     slot        :: handle to the glyph slot containing the image to
+  *                    convert
+  *
+  *     render_mode :: a set of bit flags indicating which kind of bitmap
+  *                    to render. For now, only 'ft_render_mode_anti_alias'
+  *                    is supported by the available renderers, but others
+  *                    could appear later (e.g. LCD or TV optimised)
+  *
+  *  <Return>
+  *     Error code. 0 means success.
+  *
+  *  <Note>
+  *     in case of success, the renderer will be used to convert glyph
+  *     images in the renderer's known format into bitmaps.
+  *
+  *     This doesn't change the current renderer for other formats..
+  *
+  *     The slot's native image should be considered lost after the
+  *     conversion..
+  *
+  *************************************************************************/
+  
+  FT_EXPORT_DEF(FT_Error)  FT_Render_Glyph( FT_GlyphSlot  slot,
+                                            FT_UInt       render_mode );
+
+                                            
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Get_Kerning                                                     */
   /*                                                                       */
   /* <Description>                                                         */
@@ -1829,6 +2102,27 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Vector_Transform                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Transforms a single vector through a 2x2 matrix.                   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    vector :: The target vector to transform                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    matrix :: A pointer to the source 2x2 matrix.                      */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  FT_EXPORT_DEF(void)  FT_Vector_Transform( FT_Vector*  vector,
+                                            FT_Matrix*  matrix );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Outline_Get_Bitmap                                              */
   /*                                                                       */
   /* <Description>                                                         */
@@ -1893,6 +2187,7 @@
                                               FT_Outline*       outline,
                                               FT_Raster_Params* params );
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -2045,6 +2340,7 @@
                                              FT_Pos       yOffset );
 
 
+#if 0
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -2146,8 +2442,8 @@
                                                FT_Glyph_Format format,
                                                unsigned long   mode,
                                                void*           args );
+#endif
 
-
  /***************************************************************************/
  /***************************************************************************/
  /***************************************************************************/
@@ -2231,25 +2527,6 @@
   FT_EXPORT_DEF(void)  FT_Outline_Reverse( FT_Outline*  outline );
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_Vector_Transform                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Transforms a single vector through a 2x2 matrix.                   */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    vector :: The target vector to transform                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    matrix :: A pointer to the source 2x2 matrix.                      */
-  /*                                                                       */
-  /* <MT-Note>                                                             */
-  /*    Yes.                                                               */
-  /*                                                                       */
-  FT_EXPORT_DEF(void)  FT_Vector_Transform( FT_Vector*  vector,
-                                            FT_Matrix*  matrix );
 
 
   /*************************************************************************/
--- a/include/freetype/fterrors.h
+++ b/include/freetype/fterrors.h
@@ -64,6 +64,8 @@
   FT_ERRORDEF( FT_Err_Invalid_CharMap_Handle,  0x0035, "invalid charmap handle" )
   FT_ERRORDEF( FT_Err_Invalid_Outline,         0x0036, "invalid outline" )
   FT_ERRORDEF( FT_Err_Invalid_Dimensions,      0x0037, "invalid dimensions" )
+  FT_ERRORDEF( FT_Err_Invalid_Version,         0x0038, "invalid FreeType version" )
+  FT_ERRORDEF( FT_Err_Lower_Module_Version,    0x0039, "module version is too low" )
 
   FT_ERRORDEF( FT_Err_Unavailable_Outline,     0x0040, "unavailable outline" )
   FT_ERRORDEF( FT_Err_Unavailable_Bitmap,      0x0041, "unavailable bitmap" )
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -5,6 +5,9 @@
 /*  This file defines the glyph image formats recognized by FreeType, as   */
 /*  well as the default raster interface.                                  */
 /*                                                                         */
+/*  Note: a "raster" is simply a scan-line converter, used to render       */
+/*        FT_Outlines into FT_Bitmaps                                      */
+/*                                                                         */
 /*  Copyright 1996-2000 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
 /*                                                                         */
@@ -187,6 +190,10 @@
    *                    for paletted pixel modes.
    *
    * <Note>
+   *   For now, the only pixel mode supported by FreeType are mono and grays.
+   *   However, drivers might be added in the future to support more "colorful"
+   *   options..
+   *
    *   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
@@ -195,7 +202,6 @@
    *   Note that no font was found presenting such embedded bitmaps, so this
    *   is currently completely unhandled by the library.
    *
-   *
    *************************************************************************/
 
   typedef struct FT_Bitmap_
@@ -220,8 +226,7 @@
   /*                                                                       */
   /* <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.                                                   */
+  /*    converter.                                                         */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    n_contours :: The number of contours in the outline.               */
@@ -268,6 +273,7 @@
 
   } FT_Outline;
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Enum>                                                                */
@@ -286,7 +292,7 @@
   /*   ft_outline_even_odd_fill ::                                         */
   /*       by default, outlines are filled using the non-zero winding      */
   /*       rule. When set to 1, the outline will be filled using the       */
-  /*       even-odd fill rule.. (XXX: unimplemented)                       */
+  /*       even-odd fill rule.. (only works with the smooth raster)        */
   /*                                                                       */
   /*   ft_outline_reverse_fill ::                                          */
   /*       By default, outside contours of an outline are oriented in      */
@@ -460,6 +466,23 @@
   /*    conic_to :: The second-order Bezier arc emitter.                   */
   /*    cubic_to :: The third-order Bezier arc emitter.                    */
   /*                                                                       */
+  /*    shift    :: the shift that is applied to coordinates before        */
+  /*                they're sent to the emmiter                            */
+  /*                                                                       */
+  /*    delta    :: the delta that is applied to coordinates before        */
+  /*                they're sent to the emitter, but after the shift       */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The point coordinates sent to the emitters are the transformed     */
+  /*    version of the original coordinates (this is important for high    */
+  /*    accuracy during scan-conversion). The transform is simply:         */
+  /*                                                                       */
+  /*     x' = (x << shift) - delta                                         */
+  /*     y' = (x << shift) - delta                                         */
+  /*                                                                       */
+  /*    Set the value of 'shift' and 'delta' to 0 to get the original      */
+  /*    point coordinates..                                                */
+  /*                                                                       */
   typedef struct  FT_Outline_Funcs_
   {
     FT_Outline_MoveTo_Func   move_to;
@@ -479,13 +502,12 @@
   /*    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.  */
+  /*    This macro converts four letter tags into unsigned longs..         */
   /*                                                                       */
 #define FT_IMAGE_TAG( _x1, _x2, _x3, _x4 ) \
-          (((unsigned long)_x1 << 24) |        \
-           ((unsigned long)_x2 << 16) |        \
-           ((unsigned long)_x3 << 8)  |        \
+          (((unsigned long)_x1 << 24) |    \
+           ((unsigned long)_x2 << 16) |    \
+           ((unsigned long)_x3 << 8)  |    \
             (unsigned long)_x4)
 
 
@@ -495,7 +517,7 @@
   *    FT_Glyph_Format
   *
   * <Description>
-  *    An enumeration type used to describethe format of a given glyph
+  *    An enumeration type used to describe the 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.
@@ -541,13 +563,13 @@
 
  /**************************************************************************
   *
+  *  A raster is a scan converter, in charge of rendering an outline into a
+  *  a bitmap. This section contains the public API for rasters.
   *
+  *  Note that in FreeType 2, all rasters are now encapsulated within
+  *  specific modules called "renderers". See <freetype/internal/ftrender.h>
+  *  for more details on renderers..
   *
-  *
-  *
-  *
-  *
-  *
   **************************************************************************/
 
   /*************************************************************************/
@@ -934,5 +956,4 @@
   } FT_Raster_Funcs;
 
 #endif /* FTIMAGE_H */
-
 
--- a/include/freetype/internal/ftdriver.h
+++ b/include/freetype/internal/ftdriver.h
@@ -2,7 +2,7 @@
 /*                                                                         */
 /*  ftdriver.h                                                             */
 /*                                                                         */
-/*  FreeType driver interface (specification).                             */
+/*  FreeType font driver interface (specification).                        */
 /*                                                                         */
 /*  Copyright 1996-2000 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
@@ -18,174 +18,9 @@
 #ifndef FTDRIVER_H
 #define FTDRIVER_H
 
-#include <freetype/freetype.h>
+#include <freetype/ftmodule.h>
+#include <freetype/config/ftconfig.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.                                                            */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    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_doneDriver                                                */
-  /*                                                                       */
-  /* <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.                                                            */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    driver :: A handle to target driver object.                        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  typedef FT_Error  (*FTDriver_doneDriver)( FT_Driver  driver );
-
-
-  typedef void  (*FTDriver_Interface)( void );
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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).                          */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    driver    :: A handle to a driver object.                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    interface :: A string designing the interface.  Examples are       */
-  /*                 `sfnt', `post_names', `charmaps', etc.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    A typeless pointer to the extension's interface (normally a table  */
-  /*    of function pointers).  Returns NULL if the requested extension    */
-  /*    isn't available (i.e., wasn't compiled in the driver at build      */
-  /*    time).                                                             */
-  /*                                                                       */
-  typedef FTDriver_Interface  (*FTDriver_getInterface)
-                                ( FT_Driver         driver,
-                                  const FT_String*  interface );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_FormatInterface                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A driver interface field whose value is a driver-specific          */
-  /*    interface method table.  This table contains entry points to       */
-  /*    various functions that are strictly related to the driver's        */
-  /*    format.                                                            */
-  /*                                                                       */
-  typedef void*  FT_FormatInterface;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
-  /*    FT_Attach_Reader                                                   */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This function is associated to the `attach_file' driver-specific   */
-  /*    interface.  It is used to read additional data for a given face    */
-  /*    from another input stream/file.  For example, it is used to        */
-  /*    attach a Type 1 AFM file to a given Type 1 face.                   */
-  /*                                                                       */
-  typedef FT_Error  (*FT_Attach_Reader)( FT_Face  face, FT_Stream  stream );
-
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /****                           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.                                     */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    stream         :: The input stream.                                */
-  /*    face           :: A handle to the new target face.                 */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    typeface_index :: The face index in the font resource.  Used to    */
-  /*                      access individual faces in collections.          */
-  /*                                                                       */
-  /*    num_params     :: number of optional generic parameters            */
-  /*    parameters     :: table of generic parameters                      */
-  /*                                                                       */
-  /* <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.                                         */
-  /*                                                                       */
-  /*    The generic parameters are a way to pass additional data to a      */
-  /*    given font driver when creating a new face object. In most cases   */
-  /*    they will be simply ignored..                                      */
-  /*                                                                       */
-  /*    FTDriver_doneFace() will be called subsequently, whatever the      */
-  /*    result was.                                                        */
-  /*                                                                       */
   typedef FT_Error  (*FTDriver_initFace)( FT_Stream      stream,
                                           FT_Face        face,
                                           FT_Int         typeface_index,
@@ -193,124 +28,21 @@
                                           FT_Parameter*  parameters );
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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.                                                     */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    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     :: A pointer to 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 by format-specific interfaces.             */
-  /*                                                                       */
-  typedef FT_Error  (*FTDriver_getKerning)( FT_Face      face,
-                                            FT_UInt      left_glyph,
-                                            FT_UInt      right_glyph,
-                                            FT_Vector*   kerning );
+  typedef FT_Error  (*FTDriver_initSize)( FT_Size  size );
 
 
+  typedef void  (*FTDriver_doneSize)( FT_Size  size );
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /****                            S I Z E S                            ****/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
 
+  typedef FT_Error  (*FTDriver_initGlyphSlot)( FT_GlyphSlot  slot );
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
-  /*    FTDriver_initSize                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A driver method used to initialize a new size object.  The object  */
-  /*    must be created by the caller.                                     */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    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 );
 
+  typedef void  (*FTDriver_doneGlyphSlot)( FT_GlyphSlot  slot );
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
-  /*    FTDriver_setCharSizes                                              */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A driver method used to reset a size's character sizes (horizontal */
-  /*    and vertical) expressed in fractional points.                      */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size            :: A handle to the target size object.             */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    char_width      :: The character width expressed in 26.6           */
-  /*                       fractional points.                              */
-  /*    char_height     :: The character height expressed in 26.6          */
-  /*                       fractional points.                              */
-  /*    horz_resolution :: The horizontal resolution.                      */
-  /*    vert_resolution :: The vertical resolution.                        */
-  /*                                                                       */
-  /* <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,
@@ -317,127 +49,10 @@
                                               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.                         */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size         :: A handle to the target size object.                */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    pixel_width  :: The character width expressed in 26.6 fractional   */
-  /*                    pixels.                                            */
-  /*    pixel_height :: The character height expressed in 26.6 fractional  */
-  /*                    pixels.                                            */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This function should work with all kinds of `size' objects, either */
-  /*    fixed or scalable ones.                                            */
-  /*                                                                       */
   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.                                                            */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
-  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.                                                     */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    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.                                 */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    slot :: A handle to the new glyph slot object.                     */
-  /*                                                                       */
-  typedef void  (*FTDriver_doneGlyphSlot)( FT_GlyphSlot  slot );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
-  /*    FTDriver_loadGlyph                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A driver method used to load a glyph within a given glyph slot.    */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    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.                              */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    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).                  */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
   typedef FT_Error  (*FTDriver_loadGlyph)( FT_GlyphSlot  slot,
                                            FT_Size       size,
                                            FT_UInt       glyph_index,
@@ -444,149 +59,116 @@
                                            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 );
 
+  typedef FT_Error  (*FTDriver_getKerning)( FT_Face      face,
+                                            FT_UInt      left_glyph,
+                                            FT_UInt      right_glyph,
+                                            FT_Vector*   kerning );
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /****                       I N T E R F A C E                         ****/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
+  typedef FT_Error  (*FTDriver_attachFile)( FT_Face  face, FT_Stream  stream );
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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       :: The 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_interface        :: 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.     */
-  /*                                                                       */
-  /*    get_char_index       :: Returns the glyph index for a given        */
-  /*                            charmap.                                   */
-  /*                                                                       */
-  typedef struct  FT_DriverInterface_
+
+  typedef FT_Error  (*FTDriver_getAdvances)( FT_Face     face,
+                                             FT_UInt     first,
+                                             FT_UInt     count,
+                                             FT_Bool     vertical,
+                                             FT_UShort*  advances );
+
+
+ /*************************************************************************
+  *
+  *  <Struct>
+  *     FT_Driver_Class
+  *
+  *  <Description>
+  *     The font driver class. This structure mostly contains pointers to
+  *     driver methods.
+  *
+  *  <Fields>
+  *     face_object_size :: size of a face object in bytes
+  *     size_object_size :: size of a size object in bytes
+  *     slot_object_size :: size of a glyph object in bytes
+  *
+  *     init_face    :: format-specific face constructor
+  *     done_face    :: format-specific face destructor
+  *
+  *     init_size    :: format-specific size constructor
+  *     done_size    :: format-specific size destructor
+  *
+  *     init_slot    :: format-specific slot constructor
+  *     done_slot    :: format-specific slot destructor
+  *
+  *     set_char_sizes  ::  handle to a function used to set the new character
+  *                         size in points + resolution. can be set to 0 to
+  *                         indicate default behaviour
+  *
+  *     set_pixel_sizes ::  handme to function used to set the new character
+  *                         size in pixels. can be set to 0 to indicate
+  *                         default behaviour
+  *
+  *     load_glyph      ::  load a given glyph image in a slot. This field
+  *                         is mandatory !
+  *
+  *     get_char_index  ::  return the glyph index of a given character
+  *                         for a given charmap. This field is mandatory !
+  *
+  *     get_kerning     ::  return the unscaled kerning for a given pair
+  *                         of glyphs. can be set to 0 if the format doesn't
+  *                         support kerning.
+  *
+  *     attach_file     ::  reads additional data for a face from another
+  *                         file/stream. For example, this can be used
+  *                         to add data from AFM or PFM files on a Type 1
+  *                         face, or a CIDMap on a CID-keyed face..
+  *
+  *     get_advances    ::  a function used to return the advances of 'count'
+  *                         glyphs, starting at 'index'. the "vertical" flags
+  *                         must be set when vertical advances are queried.
+  *                         the advances buffer is caller-allocated
+  *
+  *     get_bboxes      ::  a function used to return the bounding box of
+  *                         'count' glyphs, starting at 'index'. the bbox
+  *                         buffer is caller-allocated
+  *
+  *  <Note>
+  *     Most function pointers, with the exception of "load_glyph" and
+  *     "get_char_index" can be set to 0 to indicate a the default behaviour
+  *     
+  *
+  *************************************************************************/
+  
+  typedef struct  FT_Driver_Class_
   {
-    FT_Int                       driver_object_size;
+    FT_Module_Class              root;
+    
     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_initGlyphSlot       init_slot;
+    FTDriver_doneGlyphSlot       done_slot;
+
     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;
+    FTDriver_getKerning          get_kerning;
+    FTDriver_attachFile          attach_file;
+
+    FTDriver_getAdvances         get_advances;
+
+  } FT_Driver_Class;
 
 
 #endif /* FTDRIVER_H */
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -26,6 +26,7 @@
 #define FTOBJS_H
 
 #include <freetype/internal/ftmemory.h>
+#include <freetype/ftrender.h>
 #include <freetype/internal/ftdriver.h>
 
   /*************************************************************************/
@@ -67,12 +68,103 @@
 #endif
 
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                         M O D U L E S                           ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
 
+ /************************************************************************
+  *
+  *  <Struct>
+  *     FT_ModuleRec
+  *
+  *  <Description>
+  *     A module object instance.
+  *
+  *  <Fields>
+  *     clazz   ::  pointer to module's class
+  *     library ::  handle to parent library object
+  *     memory  ::  handle to memory manager
+  *     generic ::  generic structure for user-level extensibility (?)
+  *
+  ************************************************************************/
+  
+  typedef struct FT_ModuleRec_
+  {
+    FT_Module_Class*  clazz;
+    FT_Library        library;
+    FT_Memory         memory;
+    FT_Generic        generic;
+    
+  } FT_ModuleRec;
+
+  /* typecast an object to a FT_Module */
+  #define  FT_MODULE(x)          ((FT_Module)(x))
+  #define  FT_MODULE_CLASS(x)    FT_MODULE(x)->clazz
+  #define  FT_MODULE_LIBRARY(x)  FT_MODULE(x)->library
+  #define  FT_MODULE_MEMORY(x)   FT_MODULE(x)->memory
+
+  #define  FT_MODULE_IS_DRIVER(x)  (FT_MODULE_CLASS(x)->module_flags & \
+                                        ft_module_font_driver )
+
+  #define  FT_MODULE_IS_DRIVER(x)  (FT_MODULE_CLASS(x)->module_flags & \
+                                        ft_module_font_driver )
+
+  #define  FT_MODULE_IS_RENDERER(x)  (FT_MODULE_CLASS(x)->module_flags & \
+                                        ft_module_renderer )
+
+  #define  FT_DRIVER_IS_SCALABLE(x)  (FT_MODULE_CLASS(x)->module_flags & \
+                                        ft_module_driver_scalable )
+
+  #define  FT_DRIVER_USES_OUTLINES(x)  !(FT_MODULE_CLASS(x)->module_flags & \
+                                         ft_module_driver_no_outlines )
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****               FACE, SIZE & GLYPH SLOT OBJECTS                   ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /* a few macros used to perform easy typecasts with minimal brain damage */
+
+  #define  FT_FACE(x)  ((FT_Face)x)
+  #define  FT_SIZE(x)  ((FT_Size)x)
+  #define  FT_SLOT(x)  ((FT_GlyphSlot)x)
+  
+  #define  FT_FACE_DRIVER(x)   FT_FACE(x)->driver
+  #define  FT_FACE_LIBRARY(x)  FT_FACE_DRIVER(x)->root.library
+  #define  FT_FACE_MEMORY(x)   FT_FACE(x)->memory
+
+  #define  FT_SIZE_FACE(x)  FT_SIZE(x)->face
+  #define  FT_SLOT_FACE(x)  FT_SLOT(x)->face
+
+  #define  FT_FACE_SLOT(x)  FT_FACE(x)->glyph
+  #define  FT_FACE_SIZE(x)  FT_FACE(x)->size
+
+
+  /* this must be kept exported - this will be used later in our own */
+  /* high-level caching font manager called SemTex (way after the    */
+  /* 2.0 release though..                                            */
   FT_EXPORT_DEF(FT_Error)  FT_New_Size( FT_Face   face,
                                         FT_Size*  size );
 
   FT_EXPORT_DEF(FT_Error)  FT_Done_Size( FT_Size  size );
 
+
   FT_EXPORT_DEF(FT_Error)  FT_New_GlyphSlot( FT_Face        face,
                                              FT_GlyphSlot*  aslot );
 
@@ -80,13 +172,76 @@
 
 
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                   G L Y P H   L O A D E R                       ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
 
+  typedef struct FT_GlyphLoad_
+  {
+    FT_Outline    outline;       /* outline                          */
+    FT_UInt       num_subglyphs; /* number of subglyphs              */
+    FT_SubGlyph*  subglyphs;     /* subglyphs                        */
+    FT_Vector*    extra_points;  /* extra points table..             */
+  
+  } FT_GlyphLoad;
+
+
+  struct FT_GlyphLoader_
+  {
+    FT_Memory     memory;
+    FT_UInt       max_points;
+    FT_UInt       max_contours;
+    FT_UInt       max_subglyphs;
+    FT_Bool       use_extra;
+
+    FT_GlyphLoad  base;
+    FT_GlyphLoad  current;
+
+    void*         other;            /* for possible future extension ? */
+    
+  };
+
+
+  BASE_DEF(FT_Error)  FT_GlyphLoader_New( FT_Memory         memory,
+                                          FT_GlyphLoader*  *aloader );
+                                          
+  BASE_DEF(FT_Error)  FT_GlyphLoader_Create_Extra( FT_GlyphLoader*  loader );                                        
+  
+  BASE_DEF(void)      FT_GlyphLoader_Done( FT_GlyphLoader*  loader );
+  
+  BASE_DEF(void)      FT_GlyphLoader_Reset( FT_GlyphLoader*  loader );
+  
+  BASE_DEF(void)      FT_GlyphLoader_Rewind( FT_GlyphLoader*  loader );
+  
+  BASE_DEF(FT_Error)  FT_GlyphLoader_Check_Points( FT_GlyphLoader* loader,
+                                                   FT_UInt         n_points,
+                                                   FT_UInt         n_contours );
+                               
+  BASE_DEF(FT_Error)  FT_GlyphLoader_Check_Subglyphs( FT_GlyphLoader*  loader,
+                                                      FT_UInt          n_subs );
+
+  BASE_DEF(void)      FT_GlyphLoader_Prepare( FT_GlyphLoader*  loader );
+
+  
+  BASE_DEF(void)      FT_GlyphLoader_Add( FT_GlyphLoader*  loader );
+
+  BASE_DEF(FT_Error)  FT_GlyphLoader_Copy_Points( FT_GlyphLoader*  target,
+                                                  FT_GlyphLoader*  source );
+
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
   /****                                                                 ****/
   /****                                                                 ****/
-  /****                         D R I V E R S                           ****/
+  /****                        R E N D E R E R S                        ****/
   /****                                                                 ****/
   /****                                                                 ****/
   /*************************************************************************/
@@ -93,7 +248,39 @@
   /*************************************************************************/
   /*************************************************************************/
 
+  #define FT_RENDERER(x)  ((FT_Renderer)(x))
+
+  typedef struct FT_RendererRec_
+  {
+    FT_ModuleRec           root;
+    FT_Renderer_Class*     clazz;
+    FT_Glyph_Format        glyph_format;
+
+    FT_Raster              raster;
+    FT_Raster_Render_Func  raster_render;
+    FTRenderer_render      render;
+  
+  } FT_RendererRec;
+
   /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                    F O N T   D R I V E R S                      ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /* typecast a module into a driver easily */
+  #define FT_DRIVER(x)  ((FT_Driver)(x))
+
+  /* typecast a module as a driver, and get its driver class */
+  #define FT_DRIVER_CLASS(x)  FT_DRIVER(x)->clazz
+
+  /*************************************************************************/
   /*                                                                       */
   /* <Struct>                                                              */
   /*    FT_DriverRec                                                       */
@@ -103,29 +290,12 @@
   /*    managing and loading font files of a given format.                 */
   /*                                                                       */
   /*  <Fields>                                                             */
-  /*     library     :: A handle to the driver's parent library.           */
+  /*     root        :: contains the fields of the root module class       */
   /*                                                                       */
-  /*     memory      :: A handle to the driver's memory object.  This is a */
-  /*                    duplicate of `library->memory'.                    */
+  /*     clazz       :: a pointer to the font driver's class. Note that    */
+  /*                    this is NOT root.clazz. 'class' wasn't used        */
+  /*                    as it's a reserved word in C++                     */
   /*                                                                       */
-  /*     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      */
@@ -132,23 +302,19 @@
   /*                    registry, when they are supported through the      */
   /*                    config macro FT_CONFIG_OPTION_EXTENSIONS           */
   /*                                                                       */
+  /*     glyph_loader :: glyph loader for all faces managed by this driver */
+  /*                     this object isn't defined for unscalable formats  */
+  /*                                                                       */
   typedef struct  FT_DriverRec_
   {
-    FT_Library          library;
-    FT_Memory           memory;
+    FT_ModuleRec      root;
+    FT_Driver_Class*  clazz;
+    
+    FT_ListRec        faces_list;
+    void*             extensions;
+    
+    FT_GlyphLoader*   glyph_loader;
 
-    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;
 
 
@@ -157,19 +323,6 @@
   /*************************************************************************/
   /****                                                                 ****/
   /****                                                                 ****/
-  /****                      G L Y P H   Z O N E S                      ****/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                                                                 ****/
   /****                       L I B R A R I E S                         ****/
   /****                                                                 ****/
   /****                                                                 ****/
@@ -197,31 +350,45 @@
   /*    generic        :: Client data variable.  Used to extend the        */
   /*                      Library class by higher levels and clients.      */
   /*                                                                       */
-  /*    num_drivers    :: The number of drivers currently registered       */
+  /*    num_modules    :: The number of modules currently registered       */
   /*                      within this library.  This is set to 0 for new   */
-  /*                      libraries.  New drivers are added through the    */
-  /*                      FT_Add_Driver() API function.                    */
+  /*                      libraries.  New modules are added through the    */
+  /*                      FT_Add_Module() API function.                    */
   /*                                                                       */
-  /*    drivers        :: A table used to store handles to the currently   */
-  /*                      registered font drivers.  Note that each driver  */
+  /*    modules        :: A table used to store handles to the currently   */
+  /*                      registered modules. Note that each font driver   */
   /*                      contains a list of its opened faces.             */
   /*                                                                       */
+  /*    renderers      :: the list of renderers currently registered       */
+  /*                      within the library.                              */
+  /*                                                                       */
+  /*    cur_renderer   :: current outline renderer. This is a short cut    */
+  /*                      used to avoid parsing the list on each call to   */
+  /*                      FT_Outline_Render. It is a handle to the current */
+  /*                      renderer for the ft_glyph_format_outline format. */
+  /*                                                                       */
   /*    raster_pool    :: The raster object's render pool.  This can       */
   /*                      ideally be changed dynamically at run-time.      */
   /*                                                                       */
+  /*    raster_pool_size :: size of the render pool in bytes               */
+  /*                                                                       */
+  /*                                                                       */
+  /*                                                                       */
+  /*                                                                       */
   typedef  void  (*FT_DebugHook_Func)( void* arg );
 
+
   typedef struct  FT_LibraryRec_
   {
-    FT_Memory           memory;         /* library's memory object          */
+    FT_Memory           memory;         /* library's memory manager */
 
     FT_Generic          generic;
 
-    FT_Int              num_drivers;
-    FT_Driver           drivers[ FT_MAX_DRIVERS ];  /* driver objects  */
+    FT_Int              num_modules;
+    FT_Module           modules[ FT_MAX_MODULES ];  /* module objects  */
 
-    FT_Raster_Funcs     raster_funcs[ FT_MAX_GLYPH_FORMATS ];
-    FT_Raster           rasters     [ FT_MAX_GLYPH_FORMATS ];
+    FT_ListRec          renderers;     /* list of renderers        */
+    FT_Renderer         cur_renderer;  /* current outline renderer */
 
     void*               raster_pool;      /* scan-line conversion render pool */
     long                raster_pool_size; /* size of render pool in bytes     */
@@ -239,21 +406,13 @@
 
 
 
-  FT_EXPORT_DEF(void)  FT_Set_Debug_Hook( FT_Library         library,
-                                          FT_UInt            hook_index,
-                                          FT_DebugHook_Func  debug_hook );
+  FT_EXPORT_DEF(void)      FT_Set_Debug_Hook( FT_Library         library,
+                                              FT_UInt            hook_index,
+                                              FT_DebugHook_Func  debug_hook );
 
 
-  FT_EXPORT_DEF(FT_Error)  FT_Add_Driver( FT_Library                 library,
-                                          const FT_DriverInterface*  driver_interface );
 
 
-  FT_EXPORT_DEF(FT_Error)  FT_Remove_Driver( FT_Driver  driver );
-
-
-  FT_EXPORT_DEF(FT_Driver) FT_Get_Driver( FT_Library  library,
-                                          char*       driver_name );
-
 #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
 
   FT_EXPORT_DEF(FT_Error)   FT_New_Stream( const char*  filepathname,
@@ -264,6 +423,7 @@
   FT_EXPORT_DEF(FT_Memory)  FT_New_Memory( void );
 
 #endif
+
 
 /* Define default raster's interface. The default raster is located in `src/base/ftraster.c' */
 /*                                                                                           */
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -110,8 +110,8 @@
 
 
   typedef
-  FTDriver_Interface  (*SFNT_Get_Interface_Func)( FT_Driver    driver,
-                                                  const char*  interface );
+  FT_Module_Interface  (*SFNT_Get_Interface_Func)( FT_Module    module,
+                                                   const char*  interface );
 
 
   /*************************************************************************/
--- a/src/base/ftextend.c
+++ b/src/base/ftextend.c
@@ -70,7 +70,7 @@
     FT_Extension_Registry*  registry;
 
 
-    memory = driver->library->memory;
+    memory = driver->root.library->memory;
     if ( ALLOC( registry, sizeof ( *registry ) ) )
       return error;
 
@@ -101,7 +101,7 @@
   LOCAL_FUNC
   FT_Error  FT_Done_Extensions( FT_Driver  driver )
   {
-    FT_Memory  memory = driver->memory;
+    FT_Memory  memory = driver->root.memory;
 
 
     FREE( driver->extensions );
@@ -126,7 +126,7 @@
   /*                                                                       */
   FT_EXPORT_FUNC( FT_Error )  FT_Register_Extension(
                                 FT_Driver            driver,
-                                FT_Extension_Class*  class )
+                                FT_Extension_Class*  clazz )
   {
     FT_Extension_Registry*  registry;
 
@@ -134,7 +134,7 @@
     if ( !driver )
       return FT_Err_Invalid_Driver_Handle;
 
-    if ( !class )
+    if ( !clazz )
       return FT_Err_Invalid_Argument;
 
     registry = (FT_Extension_Registry*)driver->extensions;
@@ -143,11 +143,10 @@
       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 = *class;
+      *cur = *clazz;
 
       cur->offset  = registry->cur_offset;
 
@@ -260,7 +259,7 @@
           cur->finalize( ext, face );
       }
 
-      memory = face->driver->memory;
+      memory = face->driver->root.memory;
       FREE( face->extensions );
     }
 
@@ -302,7 +301,7 @@
     if ( !registry )
       return FT_Err_Ok;
 
-    memory = face->driver->memory;
+    memory = face->driver->root.memory;
     if ( ALLOC( face->extensions, registry->cur_offset ) )
       return error;
 
--- a/src/base/ftglyph.c
+++ b/src/base/ftglyph.c
@@ -209,11 +209,9 @@
 
         /* transform the outline -- note that the original metrics are NOT */
         /* transformed by this, only the outline points themselves...      */
-        FT_Outline_Transform( &face->glyph->outline,
-                              &face->transform_matrix );
         FT_Outline_Translate( &face->glyph->outline,
-                              face->transform_delta.x + origin_x,
-                              face->transform_delta.y + origin_y );
+                               origin_x,
+                               origin_y );
 
         /* compute the size in pixels of the outline */
         FT_Outline_Get_CBox( &face->glyph->outline, &cbox );
@@ -257,7 +255,7 @@
         FT_Outline_Translate( &face->glyph->outline,
                               -cbox.xMin,
                               -cbox.yMin );
-        error = FT_Outline_Get_Bitmap( face->driver->library,
+        error = FT_Outline_Get_Bitmap( face->driver->root.library,
                                        &face->glyph->outline,
                                        &bitglyph->bitmap );
         if ( error )
@@ -327,8 +325,8 @@
 
     *vecglyph = 0;
 
-    /* check that NO_OUTLINE and NO_RECURSE are not set */
-    if ( load_flags & ( FT_LOAD_NO_OUTLINE | FT_LOAD_NO_RECURSE ) )
+    /* check that RENDER and NO_RECURSE are not set */
+    if ( load_flags & ( FT_LOAD_RENDER | FT_LOAD_NO_RECURSE ) )
     {
       error = FT_Err_Invalid_Argument;
       goto Exit;
@@ -348,16 +346,6 @@
       goto Exit;
     }
 
-    /* transform the outline -- note that the original metrics are NOT */
-    /* transformed by this, only the outline points themselves...      */
-    if ( face->transform_flags )
-    {
-      FT_Outline_Transform( &face->glyph->outline, &face->transform_matrix );
-      FT_Outline_Translate( &face->glyph->outline,
-                            face->transform_delta.x,
-                            face->transform_delta.y );
-    }
-
     /* now, create a new outline glyph and copy everything */
     memory = face->memory;
     if ( ALLOC( glyph, sizeof ( *glyph ) ) )
@@ -366,7 +354,7 @@
     ft_prepare_glyph( (FT_Glyph)glyph, face, 0 );
     glyph->metrics.glyph_type = ft_glyph_type_outline;
 
-    error = FT_Outline_New( face->driver->library,
+    error = FT_Outline_New( face->driver->root.library,
                             face->glyph->outline.n_points,
                             face->glyph->outline.n_contours,
                             &glyph->outline );
@@ -383,72 +371,6 @@
   Fail:
     FREE( glyph );
     goto Exit;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_Set_Transform                                                   */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A function used to set the transformation that is applied to glyph */
-  /*    images just after they are loaded in the face's glyph slot, and    */
-  /*    before they are returned by either FT_Get_Glyph_Bitmap() or        */
-  /*    FT_Get_Glyph_Outline().                                            */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    face   :: A handle to the source face object.                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    matrix :: A pointer to the transformation's 2x2 matrix.  Use 0 for */
-  /*              the identity matrix.                                     */
-  /*    delta  :: A pointer to the translation vector.  Use 0 for the null */
-  /*              vector.                                                  */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The transformation is only applied to glyph outlines if they are   */
-  /*    found in a font face.  It is unable to transform embedded glyph    */
-  /*    bitmaps.                                                           */
-  /*                                                                       */
-  FT_EXPORT_FUNC( void )  FT_Set_Transform( FT_Face     face,
-                                            FT_Matrix*  matrix,
-                                            FT_Vector*  delta )
-  {
-    if ( !face )
-      return;
-
-    face->transform_flags = 0;
-
-    if ( !matrix )
-    {
-      face->transform_matrix.xx = 0x10000L;
-      face->transform_matrix.xy = 0L;
-      face->transform_matrix.yx = 0L;
-      face->transform_matrix.yy = 0x10000L;
-      matrix = &face->transform_matrix;
-    }
-    else
-      face->transform_matrix = *matrix;
-
-    /* set transform_flags bit flag 0 if `matrix' isn't the identity */
-    if ( ( matrix->xy | matrix->yx ) ||
-         matrix->xx != 0x10000L      ||
-         matrix->yy != 0x10000L      )
-      face->transform_flags |= 1;
-
-    if ( !delta )
-    {
-      face->transform_delta.x = 0;
-      face->transform_delta.y = 0;
-      delta = &face->transform_delta;
-    }
-    else
-      face->transform_delta = *delta;
-
-    /* set transform_flags bit flag 1 if `delta' isn't the null vector */
-    if ( delta->x | delta->y )
-      face->transform_flags |= 2;
   }
 
 
--- a/src/base/ftgrays.c
+++ /dev/null
@@ -1,1952 +1,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftgrays.c                                                              */
-/*                                                                         */
-/*    A new `perfect' anti-aliasing renderer (body).                       */
-/*                                                                         */
-/*  Copyright 2000 by                                                      */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*  This file can be compiled without the rest of the FreeType engine,   */
-  /*  by defining the _STANDALONE_ macro when compiling it.  You also need */
-  /*  to put the files `ftgrays.h' and `ftimage.h' into the current        */
-  /*  compilation directory.  Typically, you could do something like       */
-  /*                                                                       */
-  /*  - copy `src/base/ftgrays.c' to your current directory                */
-  /*                                                                       */
-  /*  - copy `include/freetype/ftimage.h' and                              */
-  /*    `include/freetype/ftgrays.h' to the same directory                 */
-  /*                                                                       */
-  /*  - compile `ftgrays' with the _STANDALONE_ macro defined, as in       */
-  /*                                                                       */
-  /*      cc -c -D_STANDALONE_ ftgrays.c                                   */
-  /*                                                                       */
-  /*  The renderer can be initialized with a call to                       */
-  /*  `ft_grays_raster.grays_raster_new'; an anti-aliased bitmap can be    */
-  /*  generated with a call to `ft_grays_raster.grays_raster_render'.      */
-  /*                                                                       */
-  /*  See the comments and documentation in the file `ftimage.h' for       */
-  /*  more details on how the raster works.                                */
-  /*                                                                       */
-  /*************************************************************************/
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*  This is a new anti-aliasing scan-converter for FreeType 2.  The      */
-  /*  algorithm used here is _very_ different from the one in the standard */
-  /*  `ftraster' module.  Actually, `ftgrays' computes the _exact_         */
-  /*  coverage of the outline on each pixel cell.                          */
-  /*                                                                       */
-  /*  It is based on ideas that I initially found in Raph Levien's         */
-  /*  excellent LibArt graphics library (see http://www.levien.com/libart  */
-  /*  for more information, though the web pages do not tell anything      */
-  /*  about the renderer; you'll have to dive into the source code to      */
-  /*  understand how it works).                                            */
-  /*                                                                       */
-  /*  Note, however, that this is a _very_ different implementation        */
-  /*  compared Raph's.  Coverage information is stored in a very different */
-  /*  way, and I don't use sorted vector paths.  Also, it doesn't use      */
-  /*  floating point values.                                               */
-  /*                                                                       */
-  /*  This renderer has the following advantages:                          */
-  /*                                                                       */
-  /*  - It doesn't need an intermediate bitmap.  Instead, one can supply   */
-  /*    a callback function that will be called by the renderer to draw    */
-  /*    gray spans on any target surface.  You can thus do direct          */
-  /*    composition on any kind of bitmap, provided that you give the      */
-  /*    renderer the right callback.                                       */
-  /*                                                                       */
-  /*  - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on  */
-  /*    each pixel cell                                                    */
-  /*                                                                       */
-  /*  - It performs a single pass on the outline (the `standard' FT2       */
-  /*    renderer makes two passes).                                        */
-  /*                                                                       */
-  /*  - It can easily be modified to render to _any_ number of gray levels */
-  /*    cheaply.                                                           */
-  /*                                                                       */
-  /*  - For small (< 20) pixel sizes, it is faster than the standard       */
-  /*    renderer.                                                          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#include <string.h>             /* for memcpy() */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
-  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
-  /* messages during execution.                                            */
-  /*                                                                       */
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_aaraster
-
-
-#define ErrRaster_Invalid_Outline  -1
-
-
-#ifdef _STANDALONE_
-
-
-#include "ftimage.h"
-#include "ftgrays.h"
-
-  /* This macro is used to indicate that a function parameter is unused. */
-  /* Its purpose is simply to reduce compiler warnings.  Note also that  */
-  /* simply defining it as `(void)x' doesn't avoid warnings with certain */
-  /* ANSI compilers (e.g. LCC).                                          */
-#define UNUSED( x )  (x) = (x)
-
-  /* Disable the tracing mechanism for simplicity -- developers can      */
-  /* activate it easily by redefining these two macros.                  */
-#ifndef FT_ERROR
-#define FT_ERROR( x )  do ; while ( 0 )     /* nothing */
-#endif
-
-#ifndef FT_TRACE
-#define FT_TRACE( x )  do ; while ( 0 )     /* nothing */
-#endif
-
-
-#else /* _STANDALONE_ */
-
-
-#include <freetype/ftgrays.h>
-#include <freetype/internal/ftobjs.h>  /* for UNUSED()                  */
-#include <freetype/internal/ftdebug.h> /* for FT_TRACE() and FT_ERROR() */
-#include <freetype/freetype.h>         /* for FT_Outline_Decompose()    */
-
-
-#endif /* _STANDALONE_ */
-
-
-  /* define this to dump debugging information */
-#define xxxDEBUG_GRAYS
-
-  /* as usual, for the speed hungry :-) */
-
-#ifndef FT_STATIC_RASTER
-
-
-#define RAS_ARG   PRaster  raster
-#define RAS_ARG_  PRaster  raster,
-
-#define RAS_VAR   raster
-#define RAS_VAR_  raster,
-
-#define ras       (*raster)
-
-
-#else /* FT_STATIC_RASTER */
-
-
-#define RAS_ARG   /* empty */
-#define RAS_ARG_  /* empty */
-#define RAS_VAR   /* empty */
-#define RAS_VAR_  /* empty */
-
-  static TRaster  ras;
-
-
-#endif /* FT_STATIC_RASTER */
-
-
-  /* must be at least 6 bits! */
-#define PIXEL_BITS  8
-
-#define ONE_PIXEL       ( 1L << PIXEL_BITS )
-#define PIXEL_MASK      ( -1L << PIXEL_BITS )
-#define TRUNC( x )      ( (x) >> PIXEL_BITS )
-#define SUBPIXELS( x )  ( (x) << PIXEL_BITS )
-#define FLOOR( x )      ( (x) & -ONE_PIXEL )
-#define CEILING( x )    ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
-#define ROUND( x )      ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
-
-#if PIXEL_BITS >= 6
-#define UPSCALE( x )    ( (x) << ( PIXEL_BITS - 6 ) )
-#define DOWNSCALE( x )  ( (x) >> ( PIXEL_BITS - 6 ) )
-#else
-#define UPSCALE( x )    ( (x) >> ( 6 - PIXEL_BITS ) )
-#define DOWNSCALE( x )  ( (x) << ( 6 - PIXEL_BITS ) )
-#endif
-
-  /* Define this if you want to use a more compact storage scheme.  This   */
-  /* increases the number of cells available in the render pool but slows  */
-  /* down the rendering a bit.  It is useful if you have a really tiny     */
-  /* render pool.                                                          */
-#define xxxGRAYS_COMPACT
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*   TYPE DEFINITIONS                                                    */
-  /*                                                                       */
-  typedef int   TScan;   /* integer scanline/pixel coordinate */
-  typedef long  TPos;    /* sub-pixel coordinate              */
-
-  /* maximal number of gray spans in a call to the span callback */
-#define FT_MAX_GRAY_SPANS  32
-
-
-#ifdef GRAYS_COMPACT
-
-  typedef struct  TCell_
-  {
-    short  x     : 14;
-    short  y     : 14;
-    int    cover : PIXEL_BITS + 2;
-    int    area  : PIXEL_BITS * 2 + 2;
-
-  } TCell, *PCell;
-
-#else /* GRAYS_COMPACT */
-
-  typedef struct  TCell_
-  {
-    TScan  x;
-    TScan  y;
-    int    cover;
-    int    area;
-
-  } TCell, *PCell;
-
-#endif /* GRAYS_COMPACT */
-
-
-  typedef struct TRaster_
-  {
-    PCell  cells;
-    int    max_cells;
-    int    num_cells;
-
-    TScan  min_ex, max_ex;
-    TScan  min_ey, max_ey;
-
-    int    area;
-    int    cover;
-    int    invalid;
-
-    TScan  ex, ey;
-    TScan  cx, cy;
-    TPos   x,  y;
-
-    TScan  last_ey;
-
-    FT_Vector   bez_stack[32 * 3];
-    int         lev_stack[32];
-
-    FT_Outline  outline;
-    FT_Bitmap   target;
-
-    FT_Span     gray_spans[FT_MAX_GRAY_SPANS];
-    int         num_gray_spans;
-
-    FT_Raster_Span_Func  render_span;
-    void*                render_span_data;
-    int                  span_y;
-
-    int    band_size;
-    int    band_shoot;
-    int    conic_level;
-    int    cubic_level;
-
-    void*  memory;
-
-  } TRaster, *PRaster;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Initialize the cells table.                                           */
-  /*                                                                       */
-  static
-  void  init_cells( RAS_ARG_ void*  buffer,
-                    long            byte_size )
-  {
-    ras.cells     = (PCell)buffer;
-    ras.max_cells = byte_size / sizeof ( TCell );
-    ras.num_cells = 0;
-    ras.area      = 0;
-    ras.cover     = 0;
-    ras.invalid   = 1;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compute the outline bounding box.                                     */
-  /*                                                                       */
-  static
-  void  compute_cbox( RAS_ARG_ FT_Outline*  outline )
-  {
-    FT_Vector*  vec   = outline->points;
-    FT_Vector*  limit = vec + outline->n_points;
-
-
-    if ( outline->n_points <= 0 )
-    {
-      ras.min_ex = ras.max_ex = 0;
-      ras.min_ey = ras.max_ey = 0;
-      return;
-    }
-
-    ras.min_ex = ras.max_ex = vec->x;
-    ras.min_ey = ras.max_ey = vec->y;
-
-    vec++;
-
-    for ( ; vec < limit; vec++ )
-    {
-      TPos  x = vec->x;
-      TPos  y = vec->y;
-
-
-      if ( x < ras.min_ex ) ras.min_ex = x;
-      if ( x > ras.max_ex ) ras.max_ex = x;
-      if ( y < ras.min_ey ) ras.min_ey = y;
-      if ( y > ras.max_ey ) ras.max_ey = y;
-    }
-
-    /* truncate the bounding box to integer pixels */
-    ras.min_ex = ras.min_ex >> 6;
-    ras.min_ey = ras.min_ey >> 6;
-    ras.max_ex = ( ras.max_ex + 63 ) >> 6;
-    ras.max_ey = ( ras.max_ey + 63 ) >> 6;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Record the current cell in the table.                                 */
-  /*                                                                       */
-  static
-  int  record_cell( RAS_ARG )
-  {
-    PCell  cell;
-
-
-    if ( !ras.invalid && ( ras.area | ras.cover ) )
-    {
-      if ( ras.num_cells >= ras.max_cells )
-        return 1;
-
-      cell        = ras.cells + ras.num_cells++;
-      cell->x     = ras.ex - ras.min_ex;
-      cell->y     = ras.ey - ras.min_ey;
-      cell->area  = ras.area;
-      cell->cover = ras.cover;
-    }
-
-    return 0;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Set the current cell to a new position.                               */
-  /*                                                                       */
-  static
-  int  set_cell( RAS_ARG_ TScan  ex,
-                          TScan  ey )
-  {
-    int  invalid, record, clean;
-
-
-    /* Move the cell pointer to a new position.  We set the `invalid'      */
-    /* flag to indicate that the cell isn't part of those we're interested */
-    /* in during the render phase.  This means that:                       */
-    /*                                                                     */
-    /* . the new vertical position must be within min_ey..max_ey - 1.      */
-    /* . the new horizontal position must be strictly less than max_ex     */
-    /*                                                                     */
-    /* Note that if a cell is to the left of the clipping region, it is    */
-    /* actually set to the (min_ex-1) horizontal position.                 */
-
-    record  = 0;
-    clean   = 1;
-
-    invalid = ( ey < ras.min_ey || ey >= ras.max_ey || ex >= ras.max_ex );
-    if ( !invalid )
-    {
-      /* All cells that are on the left of the clipping region go to the */
-      /* min_ex - 1 horizontal position.                                 */
-      if ( ex < ras.min_ex )
-        ex = ras.min_ex - 1;
-
-      /* if our position is new, then record the previous cell */
-      if ( ex != ras.ex || ey != ras.ey )
-        record = 1;
-      else
-        clean = ras.invalid;  /* do not clean if we didn't move from */
-                              /* a valid cell                        */
-    }
-
-    /* record the previous cell if needed (i.e., if we changed the cell */
-    /* position, of changed the `invalid' flag)                         */
-    if ( ( ras.invalid != invalid || record ) && record_cell( RAS_VAR ) )
-      return 1;
-
-    if ( clean )
-    {
-      ras.area  = 0;
-      ras.cover = 0;
-    }
-
-    ras.invalid = invalid;
-    ras.ex      = ex;
-    ras.ey      = ey;
-    return 0;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Start a new contour at a given cell.                                  */
-  /*                                                                       */
-  static
-  void  start_cell( RAS_ARG_  TScan  ex,
-                              TScan  ey )
-  {
-    if ( ex < ras.min_ex )
-      ex = ras.min_ex - 1;
-
-    ras.area    = 0;
-    ras.cover   = 0;
-    ras.ex      = ex;
-    ras.ey      = ey;
-    ras.last_ey = SUBPIXELS( ey );
-    ras.invalid = 0;
-
-    (void)set_cell( RAS_VAR_ ex, ey );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Render a scanline as one or more cells.                               */
-  /*                                                                       */
-  static
-  int  render_scanline( RAS_ARG_  TScan  ey,
-                                  TPos   x1,
-                                  TScan  y1,
-                                  TPos   x2,
-                                  TScan  y2 )
-  {
-    TScan  ex1, ex2, fx1, fx2, delta;
-    long   p, first, dx;
-    int    incr, lift, mod, rem;
-
-
-    dx = x2 - x1;
-
-    ex1 = TRUNC( x1 ); /* if (ex1 >= ras.max_ex) ex1 = ras.max_ex-1; */
-    ex2 = TRUNC( x2 ); /* if (ex2 >= ras.max_ex) ex2 = ras.max_ex-1; */
-    fx1 = x1 - SUBPIXELS( ex1 );
-    fx2 = x2 - SUBPIXELS( ex2 );
-
-    /* trivial case.  Happens often */
-    if ( y1 == y2 )
-      return set_cell( RAS_VAR_ ex2, ey );
-
-    /* everything is located in a single cell.  That is easy! */
-    /*                                                        */
-    if ( ex1 == ex2 )
-    {
-      delta      = y2 - y1;
-      ras.area  += ( fx1 + fx2 ) * delta;
-      ras.cover += delta;
-      return 0;
-    }
-
-    /* ok, we'll have to render a run of adjacent cells on the same */
-    /* scanline...                                                  */
-    /*                                                              */
-    p     = ( ONE_PIXEL - fx1 ) * ( y2 - y1 );
-    first = ONE_PIXEL;
-    incr  = 1;
-
-    if ( dx < 0 )
-    {
-      p     = fx1 * ( y2 - y1 );
-      first = 0;
-      incr  = -1;
-      dx    = -dx;
-    }
-
-    delta = p / dx;
-    mod   = p % dx;
-    if ( mod < 0 )
-    {
-      delta--;
-      mod += dx;
-    }
-
-    ras.area  += ( fx1 + first ) * delta;
-    ras.cover += delta;
-
-    ex1 += incr;
-    if ( set_cell( RAS_VAR_ ex1, ey ) )
-      goto Error;
-    y1  += delta;
-
-    if ( ex1 != ex2 )
-    {
-      p     = ONE_PIXEL * ( y2 - y1 );
-      lift  = p / dx;
-      rem   = p % dx;
-      if ( rem < 0 )
-      {
-        lift--;
-        rem += dx;
-      }
-
-      mod -= dx;
-
-      while ( ex1 != ex2 )
-      {
-        delta = lift;
-        mod  += rem;
-        if ( mod >= 0 )
-        {
-          mod -= dx;
-          delta++;
-        }
-
-        ras.area  += ONE_PIXEL * delta;
-        ras.cover += delta;
-        y1        += delta;
-        ex1       += incr;
-        if ( set_cell( RAS_VAR_ ex1, ey ) )
-          goto Error;
-      }
-    }
-
-    delta      = y2 - y1;
-    ras.area  += ( fx2 + ONE_PIXEL - first ) * delta;
-    ras.cover += delta;
-
-    return 0;
-
-  Error:
-    return 1;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Render a given line as a series of scanlines.                         */
-  /*                                                                       */
-  static
-  int  render_line( RAS_ARG_ TPos  to_x,
-                             TPos  to_y )
-  {
-    TScan  ey1, ey2, fy1, fy2;
-    TPos   dx, dy, x, x2;
-    int    p, rem, mod, lift, delta, first, incr;
-
-
-    ey1 = TRUNC( ras.last_ey );
-    ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
-    fy1 = ras.y - ras.last_ey;
-    fy2 = to_y - SUBPIXELS( ey2 );
-
-    dx = to_x - ras.x;
-    dy = to_y - ras.y;
-
-    /* we should do something about the trivial case where dx == 0, */
-    /* as it happens very often!       XXXXX                        */
-
-    /* perform vertical clipping */
-    {
-      TScan  min, max;
-
-
-      min = ey1;
-      max = ey2;
-      if ( ey1 > ey2 )
-      {
-        min = ey2;
-        max = ey1;
-      }
-      if ( min >= ras.max_ey || max < ras.min_ey )
-        goto End;
-    }
-
-    /* everything is on a single scanline */
-    if ( ey1 == ey2 )
-    {
-      if ( render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ) )
-        goto Error;
-      goto End;
-    }
-
-    /* ok, we'll have to render several scanlines */
-    p     = ( ONE_PIXEL - fy1 ) * dx;
-    first = ONE_PIXEL;
-    incr  = 1;
-
-    if ( dy < 0 )
-    {
-      p     = fy1 * dx;
-      first = 0;
-      incr  = -1;
-      dy    = -dy;
-    }
-
-    delta = p / dy;
-    mod   = p % dy;
-    if ( mod < 0 )
-    {
-      delta--;
-      mod += dy;
-    }
-
-    x = ras.x + delta;
-    if ( render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first ) )
-      goto Error;
-
-    ey1 += incr;
-    if ( set_cell( RAS_VAR_ TRUNC( x ), ey1 ) )
-      goto Error;
-
-    if ( ey1 != ey2 )
-    {
-      p     = ONE_PIXEL * dx;
-      lift  = p / dy;
-      rem   = p % dy;
-      if ( rem < 0 )
-      {
-        lift--;
-        rem += dy;
-      }
-      mod -= dy;
-
-      while ( ey1 != ey2 )
-      {
-        delta = lift;
-        mod  += rem;
-        if ( mod >= 0 )
-        {
-          mod -= dy;
-          delta++;
-        }
-
-        x2 = x + delta;
-        if ( render_scanline( RAS_VAR_ ey1,
-                              x, ONE_PIXEL - first, x2, first ) )
-          goto Error;
-        x = x2;
-        ey1 += incr;
-        if ( set_cell( RAS_VAR_ TRUNC( x ), ey1 ) )
-          goto Error;
-      }
-    }
-
-    if ( render_scanline( RAS_VAR_ ey1,
-                          x, ONE_PIXEL - first, to_x, fy2 ) )
-      goto Error;
-
-  End:
-    ras.x       = to_x;
-    ras.y       = to_y;
-    ras.last_ey = SUBPIXELS( ey2 );
-
-    return 0;
-
-  Error:
-    return 1;
-  }
-
-
-  static
-  void  split_conic( FT_Vector*  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;
-  }
-
-
-  static
-  int  render_conic( RAS_ARG_ FT_Vector*  control,
-                              FT_Vector*  to )
-  {
-    TPos        dx, dy;
-    int         top, level;
-    int*        levels;
-    FT_Vector*  arc;
-
-
-    dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 );
-    if ( dx < 0 )
-      dx = -dx;
-    dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 );
-    if ( dy < 0 )
-      dy = -dy;
-    if ( dx < dy )
-      dx = dy;
-
-    level = 1;
-    dx = dx / ras.conic_level;
-    while ( dx > 0 )
-    {
-      dx >>= 1;
-      level++;
-    }
-
-    /* a shortcut to speed things up */
-    if ( level <= 1 )
-    {
-      /* we compute the mid-point directly in order to avoid */
-      /* calling split_conic()                               */
-      TPos   to_x, to_y, mid_x, mid_y;
-
-
-      to_x  = UPSCALE( to->x );
-      to_y  = UPSCALE( to->y );
-      mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4;
-      mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4;
-
-      return render_line( RAS_VAR_ mid_x, mid_y ) ||
-             render_line( RAS_VAR_ to_x, to_y );
-    }
-
-    arc       = ras.bez_stack;
-    levels    = ras.lev_stack;
-    top       = 0;
-    levels[0] = level;
-
-    arc[0].x = UPSCALE( to->x );
-    arc[0].y = UPSCALE( to->y );
-    arc[1].x = UPSCALE( control->x );
-    arc[1].y = UPSCALE( control->y );
-    arc[2].x = ras.x;
-    arc[2].y = ras.y;
-
-    while ( top >= 0 )
-    {
-      level = levels[top];
-      if ( level > 1 )
-      {
-        /* check that the arc crosses the current band */
-        TPos  min, max, y;
-
-
-        min = max = arc[0].y;
-
-        y = arc[1].y;
-        if ( y < min ) min = y;
-        if ( y > max ) max = y;
-
-        y = arc[2].y;
-        if ( y < min ) min = y;
-        if ( y > max ) max = y;
-
-        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
-          goto Draw;
-
-        split_conic( arc );
-        arc += 2;
-        top++;
-        levels[top] = levels[top - 1] = level - 1;
-        continue;
-      }
-
-    Draw:
-      {
-        TPos  to_x, to_y, mid_x, mid_y;
-
-
-        to_x  = arc[0].x;
-        to_y  = arc[0].y;
-        mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4;
-        mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4;
-
-        if ( render_line( RAS_VAR_ mid_x, mid_y ) ||
-             render_line( RAS_VAR_ to_x, to_y )   )
-          return 1;
-
-        top--;
-        arc -= 2;
-      }
-    }
-    return 0;
-  }
-
-
-  static
-  void  split_cubic( FT_Vector*  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;
-  }
-
-
-  static
-  int  render_cubic( RAS_ARG_ FT_Vector*  control1,
-                              FT_Vector*  control2,
-                              FT_Vector*  to )
-  {
-    TPos        dx, dy, da, db;
-    int         top, level;
-    int*        levels;
-    FT_Vector*  arc;
-
-
-    dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 );
-    if ( dx < 0 )
-      dx = -dx;
-    dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 );
-    if ( dy < 0 )
-      dy = -dy;
-    if ( dx < dy )
-      dx = dy;
-    da = dx;
-
-    dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x );
-    if ( dx < 0 )
-      dx = -dx;
-    dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y );
-    if ( dy < 0 )
-      dy = -dy;
-    if ( dx < dy )
-      dx = dy;
-    db = dx;
-
-    level = 1;
-    da    = da / ras.cubic_level;
-    db    = db / ras.conic_level;
-    while ( da > 0 || db > 0 )
-    {
-      da >>= 1;
-      db >>= 2;
-      level++;
-    }
-
-    if ( level <= 1 )
-    {
-      TPos   to_x, to_y, mid_x, mid_y;
-
-
-      to_x  = UPSCALE( to->x );
-      to_y  = UPSCALE( to->y );
-      mid_x = ( ras.x + to_x +
-                3 * UPSCALE( control1->x + control2->x ) ) / 8;
-      mid_y = ( ras.y + to_y +
-                3 * UPSCALE( control1->y + control2->y ) ) / 8;
-
-      return render_line( RAS_VAR_ mid_x, mid_y ) ||
-             render_line( RAS_VAR_ to_x, to_y );
-    }
-
-    arc      = ras.bez_stack;
-    arc[0].x = UPSCALE( to->x );
-    arc[0].y = UPSCALE( to->y );
-    arc[1].x = UPSCALE( control2->x );
-    arc[1].y = UPSCALE( control2->y );
-    arc[2].x = UPSCALE( control1->x );
-    arc[2].y = UPSCALE( control1->y );
-    arc[3].x = ras.x;
-    arc[3].y = ras.y;
-
-    levels    = ras.lev_stack;
-    top       = 0;
-    levels[0] = level;
-
-    while ( top >= 0 )
-    {
-      level = levels[top];
-      if ( level > 1 )
-      {
-        /* check that the arc crosses the current band */
-        TPos  min, max, y;
-
-
-        min = max = arc[0].y;
-        y = arc[1].y;
-        if ( y < min ) min = y;
-        if ( y > max ) max = y;
-        y = arc[2].y;
-        if ( y < min ) min = y;
-        if ( y > max ) max = y;
-        y = arc[3].y;
-        if ( y < min ) min = y;
-        if ( y > max ) max = y;
-        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
-          goto Draw;
-        split_cubic( arc );
-        arc += 3;
-        top ++;
-        levels[top] = levels[top - 1] = level - 1;
-        continue;
-      }
-
-    Draw:
-      {
-        TPos   to_x, to_y, mid_x, mid_y;
-
-
-        to_x  = arc[0].x;
-        to_y  = arc[0].y;
-        mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8;
-        mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8;
-
-        if ( render_line( RAS_VAR_ mid_x, mid_y ) ||
-             render_line( RAS_VAR_ to_x, to_y )   )
-          return 1;
-        top --;
-        arc -= 3;
-      }
-    }
-    return 0;
-  }
-
-
-  /* a macro comparing two cell pointers.  Returns true if a <= b. */
-#if 1
-#define PACK( a )          ( ( (long)(a)->y << 16 ) + (a)->x )
-#define LESS_THAN( a, b )  ( PACK( a ) < PACK( b ) )
-#else /* 1 */
-#define LESS_THAN( a, b )  ( (a)->y < (b)->y || \
-                             ( (a)->y == (b)->y && (a)->x < (b)->x ) )
-#endif /* 1 */
-
-#define SWAP_CELLS( a, b, temp )  do             \
-                                  {              \
-                                    temp = *(a); \
-                                    *(a) = *(b); \
-                                    *(b) = temp; \
-                                  } while ( 0 )
-#define DEBUG_SORT
-#define QUICK_SORT
-
-#ifdef SHELL_SORT
-
-  /* A simple shell sort algorithm that works directly on our */
-  /* cells table..                                            */
-  static
-  void  shell_sort ( PCell  cells,
-                     int    count )
-  {
-    PCell  i, j, limit = cells + count;
-    TCell  temp;
-    int    gap;
-
-
-    /* compute initial gap */
-    for ( gap = 0; ++gap < count; gap *= 3 )
-      ;
-
-    while ( gap /= 3 )
-    {
-      for ( i = cells + gap; i < limit; i++ )
-      {
-        for ( j = i - gap; ; j -= gap )
-        {
-          PCell  k = j + gap;
-
-
-          if ( LESS_THAN( j, k ) )
-            break;
-
-          SWAP_CELLS( j, k, temp );
-
-          if ( j < cells + gap )
-            break;
-        }
-      }
-    }
-  }
-
-#endif /* SHELL_SORT */
-
-
-#ifdef QUICK_SORT
-
-  /* This is a non-recursive quicksort that directly process our cells     */
-  /* array.  It should be faster than calling the stdlib qsort(), and we   */
-  /* can even tailor our insertion threshold...                            */
-
-#define QSORT_THRESHOLD  9  /* below this size, a sub-array will be sorted */
-                            /* through a normal insertion sort..           */
-
-  static
-  void  quick_sort( PCell  cells,
-                    int    count )
-  {
-    PCell   stack[40];  /* should be enough ;-) */
-    PCell*  top;        /* top of stack */
-    PCell   base, limit;
-    TCell   temp;
-
-
-    limit = cells + count;
-    base  = cells;
-    top   = stack;
-
-    for (;;)
-    {
-      int    len = limit - base;
-      PCell  i, j, pivot;
-
-
-      if ( len > QSORT_THRESHOLD )
-      {
-        /* we use base + len/2 as the pivot */
-        pivot = base + len / 2;
-        SWAP_CELLS( base, pivot, temp );
-
-        i = base + 1;
-        j = limit - 1;
-
-        /* now ensure that *i <= *base <= *j */
-        if ( LESS_THAN( j, i ) )
-          SWAP_CELLS( i, j, temp );
-
-        if ( LESS_THAN( base, i ) )
-          SWAP_CELLS( base, i, temp );
-
-        if ( LESS_THAN( j, base ) )
-          SWAP_CELLS( base, j, temp );
-
-        for (;;)
-        {
-          do i++; while ( LESS_THAN( i, base ) );
-          do j--; while ( LESS_THAN( base, j ) );
-
-          if ( i > j )
-            break;
-
-          SWAP_CELLS( i, j, temp );
-        }
-
-        SWAP_CELLS( base, j, temp );
-
-        /* now, push the largest sub-array */
-        if ( j - base > limit - i )
-        {
-          top[0] = base;
-          top[1] = j;
-          base   = i;
-        }
-        else
-        {
-          top[0] = i;
-          top[1] = limit;
-          limit  = j;
-        }
-        top += 2;
-      }
-      else
-      {
-        /* the sub-array is small, perform insertion sort */
-        j = base;
-        i = j + 1;
-
-        for ( ; i < limit; j = i, i++ )
-        {
-          for ( ; LESS_THAN( j + 1, j ); j-- )
-          {
-            SWAP_CELLS( j + 1, j, temp );
-            if ( j == base )
-              break;
-          }
-        }
-        if ( top > stack )
-        {
-          top  -= 2;
-          base  = top[0];
-          limit = top[1];
-        }
-        else
-          break;
-      }
-    }
-  }
-
-#endif /* QUICK_SORT */
-
-
-#ifdef DEBUG_GRAYS
-#ifdef DEBUG_SORT
-
-  static
-  int  check_sort( PCell  cells,
-                   int    count )
-  {
-    PCell  p, q;
-
-
-    for ( p = cells + count - 2; p >= cells; p-- )
-    {
-      q = p + 1;
-      if ( !LESS_THAN( p, q ) )
-        return 0;
-    }
-    return 1;
-  }
-
-#endif /* DEBUG_SORT */
-#endif /* DEBUG_GRAYS */
-
-
-  static
-  int  Move_To( FT_Vector*  to,
-                FT_Raster   raster )
-  {
-    TPos  x, y;
-
-
-    /* record current cell, if any */
-    record_cell( (PRaster)raster );
-
-    /* start to a new position */
-    x = UPSCALE( to->x );
-    y = UPSCALE( to->y );
-    start_cell( (PRaster)raster, TRUNC( x ), TRUNC( y ) );
-    ((PRaster)raster)->x = x;
-    ((PRaster)raster)->y = y;
-    return 0;
-  }
-
-
-  static
-  int  Line_To( FT_Vector*  to,
-                FT_Raster   raster )
-  {
-    return render_line( (PRaster)raster,
-                        UPSCALE( to->x ), UPSCALE( to->y ) );
-  }
-
-
-  static
-  int  Conic_To( FT_Vector*  control,
-                 FT_Vector*  to,
-                 FT_Raster   raster )
-  {
-    return render_conic( (PRaster)raster, control, to );
-  }
-
-
-  static
-  int  Cubic_To( FT_Vector*  control1,
-                 FT_Vector*  control2,
-                 FT_Vector*  to,
-                 FT_Raster   raster )
-  {
-    return render_cubic( (PRaster)raster, control1, control2, to );
-  }
-
-
-  static
-  void  grays_render_span( int       y,
-                           int       count,
-                           FT_Span*  spans,
-                           PRaster   raster )
-  {
-    unsigned char*  p;
-    FT_Bitmap*      map = &raster->target;
-
-
-    /* first of all, compute the scanline offset */
-    p = (unsigned char*)map->buffer - y * map->pitch;
-    if ( map->pitch >= 0 )
-      p += ( map->rows - 1 ) * map->pitch;
-
-    for ( ; count > 0; count--, spans++ )
-    {
-      if ( spans->coverage )
-#if 1
-        memset( p + spans->x, (unsigned char)spans->coverage, spans->len );
-#else /* 1 */
-      {
-        q     = p + spans->x;
-        limit = q + spans->len;
-        for ( ; q < limit; q++ )
-          q[0] = (unsigned char)spans->coverage;
-      }
-#endif /* 1 */
-    }
-  }
-
-
-#ifdef DEBUG_GRAYS
-
-#include <stdio.h>
-
-  static
-  void  dump_cells( RAS_ARG )
-  {
-    PCell  cell, limit;
-    int    y = -1;
-
-
-    cell  = ras.cells;
-    limit = cell + ras.num_cells;
-
-    for ( ; cell < limit; cell++ )
-    {
-      if ( cell->y != y )
-      {
-        fprintf( stderr, "\n%2d: ", cell->y );
-        y = cell->y;
-      }
-      fprintf( stderr, "[%d %d %d]",
-               cell->x, cell->area, cell->cover );
-    }
-    fprintf(stderr, "\n" );
-  }
-
-#endif /* DEBUG_GRAYS */
-
-
-  static
-  void  grays_hline( RAS_ARG_ TScan  x,
-                              TScan  y,
-                              TPos   area,
-                              int    acount )
-  {
-    FT_Span*   span;
-    int        count;
-    int        coverage;
-
-
-    /* compute the coverage line's coverage, depending on the    */
-    /* outline fill rule                                         */
-    /*                                                           */
-    /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */
-    /*                                                           */
-    coverage = area >> ( PIXEL_BITS * 2 + 1 - 8);  /* use range 0..256 */
-
-    if ( ras.outline.flags & ft_outline_even_odd_fill )
-    {
-      if ( coverage < 0 )
-        coverage = -coverage;
-
-      while ( coverage >= 512 )
-        coverage -= 512;
-
-      if ( coverage > 256 )
-        coverage = 512 - coverage;
-      else if ( coverage == 256 )
-        coverage = 255;
-    }
-    else
-    {
-      /* normal non-zero winding rule */
-      if ( coverage < 0 )
-        coverage = -coverage;
-
-      if ( coverage >= 256 )
-        coverage = 255;
-    }
-
-    y += ras.min_ey;
-    x += ras.min_ex;
-
-    if ( coverage )
-    {
-      /* see if we can add this span to the current list */
-      count = ras.num_gray_spans;
-      span  = ras.gray_spans + count - 1;
-      if ( count > 0                          &&
-           ras.span_y == y                    &&
-           (int)span->x + span->len == (int)x &&
-           span->coverage == coverage )
-      {
-        span->len += acount;
-        return;
-      }
-
-      if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS )
-      {
-        if ( ras.render_span )
-          ras.render_span( ras.span_y, count, ras.gray_spans,
-                           ras.render_span_data );
-        /* ras.render_span( span->y, ras.gray_spans, count ); */
-
-#ifdef DEBUG_GRAYS
-
-        if ( ras.span_y >= 0 )
-        {
-          int  n;
-
-
-          fprintf( stderr, "y=%3d ", ras.span_y );
-          span = ras.gray_spans;
-          for ( n = 0; n < count; n++, span++ )
-            fprintf( stderr, "[%d..%d]:%02x ",
-                     span->x, span->x + span->len - 1, span->coverage );
-          fprintf( stderr, "\n" );
-        }
-
-#endif /* DEBUG_GRAYS */
-
-        ras.num_gray_spans = 0;
-        ras.span_y         = y;
-
-        count = 0;
-        span  = ras.gray_spans;
-      }
-      else
-        span++;
-
-      /* add a gray span to the current list */
-      span->x        = (short)x;
-      span->len      = (unsigned short)acount;
-      span->coverage = (unsigned char)coverage;
-      ras.num_gray_spans++;
-    }
-  }
-
-
-  static
-  void  grays_sweep( RAS_ARG_ FT_Bitmap*  target )
-  {
-    TScan  x, y, cover, area;
-    PCell  start, cur, limit;
-
-    UNUSED( target );
-
-
-    cur   = ras.cells;
-    limit = cur + ras.num_cells;
-
-    cover              = 0;
-    ras.span_y         = -1;
-    ras.num_gray_spans = 0;
-
-    for (;;)
-    {
-      start  = cur;
-      y      = start->y;
-      x      = start->x;
-
-      area   = start->area;
-      cover += start->cover;
-
-      /* accumulate all start cells */
-      for (;;)
-      {
-        ++cur;
-        if ( cur >= limit || cur->y != start->y || cur->x != start->x )
-          break;
-
-        area  += cur->area;
-        cover += cur->cover;
-      }
-
-      /* if the start cell has a non-null area, we must draw an */
-      /* individual gray pixel there                            */
-      if ( area && x >= 0 )
-      {
-        grays_hline( RAS_VAR_ x, y, cover * ( ONE_PIXEL * 2 ) - area, 1 );
-        x++;
-      }
-
-      if ( x < 0 )
-        x = 0;
-
-      if ( cur < limit && start->y == cur->y )
-      {
-        /* draw a gray span between the start cell and the current one */
-        if ( cur->x > x )
-          grays_hline( RAS_VAR_ x, y,
-                       cover * ( ONE_PIXEL * 2 ), cur->x - x );
-      }
-      else
-      {
-        /* draw a gray span until the end of the clipping region */
-        if ( cover && x < ras.max_ex - ras.min_ex )
-          grays_hline( RAS_VAR_ x, y,
-                       cover * ( ONE_PIXEL * 2 ),
-                       ras.max_ex - x - ras.min_ex );
-        cover = 0;
-      }
-
-      if ( cur >= limit )
-        break;
-    }
-
-    if ( ras.render_span && ras.num_gray_spans > 0 )
-      ras.render_span( ras.span_y, ras.num_gray_spans,
-                       ras.gray_spans, ras.render_span_data );
-
-#ifdef DEBUG_GRAYS
-
-    {
-      int       n;
-      FT_Span*  span;
-
-
-      fprintf( stderr, "y=%3d ", ras.span_y );
-      span = ras.gray_spans;
-      for ( n = 0; n < ras.num_gray_spans; n++, span++ )
-        fprintf( stderr, "[%d..%d]:%02x ",
-                 span->x, span->x + span->len - 1, span->coverage );
-      fprintf( stderr, "\n" );
-    }
-
-#endif /* DEBUG_GRAYS */
-
-  }
-
-
-#ifdef _STANDALONE_
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*  The following function should only compile in stand_alone mode,      */
-  /*  i.e., when building this component without the rest of FreeType.     */
-  /*                                                                       */
-  /*************************************************************************/
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_Outline_Decompose                                               */
-  /*                                                                       */
-  /* <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.                                       */
-  /*                                                                       */
-  static
-  int  FT_Outline_Decompose( FT_Outline*        outline,
-                             FT_Outline_Funcs*  interface,
-                             void*              user )
-  {
-#undef SCALED
-#define SCALED( x )  ( ( (x) << shift ) - delta )
-
-    FT_Vector   v_last;
-    FT_Vector   v_control;
-    FT_Vector   v_start;
-
-    FT_Vector*  point;
-    FT_Vector*  limit;
-    char*       tags;
-
-    int     n;         /* index of contour in outline     */
-    int     first;     /* index of first point in contour */
-    int     error;
-    char    tag;       /* current point's state           */
-
-    int     shift = interface->shift;
-    FT_Pos  delta = interface->delta;
-
-
-    first = 0;
-
-    for ( n = 0; n < outline->n_contours; n++ )
-    {
-      int  last;  /* index of last point in contour */
-
-
-      last  = outline->contours[n];
-      limit = outline->points + last;
-
-      v_start = outline->points[first];
-      v_last  = outline->points[last];
-
-      v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y );
-      v_last.x  = SCALED( v_last.x );  v_last.y  = SCALED( v_last.y );
-
-      v_control = v_start;
-
-      point = outline->points + first;
-      tags  = outline->tags  + first;
-      tag   = FT_CURVE_TAG( tags[0] );
-
-      /* A contour cannot start with a cubic control point! */
-      if ( tag == FT_Curve_Tag_Cubic )
-        goto 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->tags[last] ) == FT_Curve_Tag_On )
-        {
-          /* start at last point if it is on the curve */
-          v_start = v_last;
-          limit--;
-        }
-        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;
-        }
-        point--;
-        tags--;
-      }
-
-      error = interface->move_to( &v_start, user );
-      if ( error )
-        goto Exit;
-
-      while ( point < limit )
-      {
-        point++;
-        tags++;
-
-        tag = FT_CURVE_TAG( tags[0] );
-        switch ( tag )
-        {
-        case FT_Curve_Tag_On:  /* emit a single line_to */
-          {
-            FT_Vector  vec;
-
-
-            vec.x = SCALED( point->x );
-            vec.y = SCALED( point->y );
-
-            error = interface->line_to( &vec, user );
-            if ( error )
-              goto Exit;
-            continue;
-          }
-
-        case FT_Curve_Tag_Conic:  /* consume conic arcs */
-          {
-            v_control.x = SCALED( point->x );
-            v_control.y = SCALED( point->y );
-
-          Do_Conic:
-            if ( point < limit )
-            {
-              FT_Vector  vec;
-              FT_Vector  v_middle;
-
-
-              point++;
-              tags++;
-              tag = FT_CURVE_TAG( tags[0] );
-
-              vec.x = SCALED( point->x );
-              vec.y = SCALED( point->y );
-
-              if ( tag == FT_Curve_Tag_On )
-              {
-                error = interface->conic_to( &v_control, &vec, user );
-                if ( error )
-                  goto Exit;
-                continue;
-              }
-
-              if ( tag != FT_Curve_Tag_Conic )
-                goto Invalid_Outline;
-
-              v_middle.x = ( v_control.x + vec.x ) / 2;
-              v_middle.y = ( v_control.y + vec.y ) / 2;
-
-              error = interface->conic_to( &v_control, &v_middle, user );
-              if ( error )
-                goto Exit;
-
-              v_control = vec;
-              goto Do_Conic;
-            }
-
-            error = interface->conic_to( &v_control, &v_start, user );
-            goto Close;
-          }
-
-        default:  /* FT_Curve_Tag_Cubic */
-          {
-            FT_Vector  vec1, vec2;
-
-
-            if ( point + 1 > limit                             ||
-                 FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic )
-              goto Invalid_Outline;
-
-            point += 2;
-            tags  += 2;
-
-            vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y );
-            vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y );
-
-            if ( point <= limit )
-            {
-              FT_Vector  vec;
-
-
-              vec.x = SCALED( point->x );
-              vec.y = SCALED( point->y );
-
-              error = interface->cubic_to( &vec1, &vec2, &vec, user );
-              if ( error )
-                goto Exit;
-              continue;
-            }
-
-            error = interface->cubic_to( &vec1, &vec2, &v_start, user );
-            goto Close;
-          }
-        }
-      }
-
-      /* close the contour with a line segment */
-      error = interface->line_to( &v_start, user );
-
-   Close:
-      if ( error )
-        goto Exit;
-
-      first = last + 1;
-    }
-
-    return 0;
-
-  Exit:
-    return error;
-
-  Invalid_Outline:
-    return ErrRaster_Invalid_Outline;
-  }
-
-#endif /* _STANDALONE_ */
-
-
-  typedef struct  TBand_
-  {
-    FT_Pos  min, max;
-
-  } TBand;
-
-
-  static
-  int  grays_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,
-      0,
-      0
-    };
-
-    TBand    bands[40], *band;
-    int      n, num_bands;
-    TPos     min, max, max_y;
-
-
-    /* Set up state in the raster object */
-    compute_cbox( RAS_VAR_ outline );
-
-    /* clip to target bitmap, exit if nothing to do */
-    if ( ras.max_ex <= 0 || ras.min_ex >= ras.target.width ||
-         ras.max_ey <= 0 || ras.min_ey >= ras.target.rows  )
-      return 0;
-
-    if ( ras.min_ex < 0 ) ras.min_ex = 0;
-    if ( ras.min_ey < 0 ) ras.min_ey = 0;
-
-    if ( ras.max_ex > ras.target.width ) ras.max_ex = ras.target.width;
-    if ( ras.max_ey > ras.target.rows )  ras.max_ey = ras.target.rows;
-
-    /* simple heuristic used to speed-up the bezier decomposition     */
-    /* see the code in render_conic and render_cubic for more details */
-    ras.conic_level = 32;
-    ras.cubic_level = 16;
-
-    {
-      int level = 0;
-
-
-      if ( ras.max_ex > 24 || ras.max_ey > 24 )
-        level++;
-      if ( ras.max_ex > 120 || ras.max_ey > 120 )
-        level += 2;
-
-      ras.conic_level <<= level;
-      ras.cubic_level <<= level;
-    }
-
-    /* setup vertical bands */
-    num_bands = ( ras.max_ey - ras.min_ey ) / ras.band_size;
-    if ( num_bands == 0 )  num_bands = 1;
-    if ( num_bands >= 39 ) num_bands = 39;
-
-    ras.band_shoot = 0;
-
-    min   = ras.min_ey;
-    max_y = ras.max_ey;
-
-    for ( n = 0; n < num_bands; n++, min = max )
-    {
-      max = min + ras.band_size;
-      if ( n == num_bands - 1 || max > max_y )
-        max = max_y;
-
-      bands[0].min = min;
-      bands[0].max = max;
-      band         = bands;
-
-      while ( band >= bands )
-      {
-        FT_Pos  bottom, top, middle;
-        int     error;
-
-
-        ras.num_cells = 0;
-        ras.invalid   = 1;
-        ras.min_ey    = band->min;
-        ras.max_ey    = band->max;
-
-        error = FT_Outline_Decompose( outline, &interface, &ras ) ||
-                record_cell( RAS_VAR );
-
-        if ( !error )
-        {
-#ifdef SHELL_SORT
-          shell_sort( ras.cells, ras.num_cells );
-#else
-          quick_sort( ras.cells, ras.num_cells );
-#endif
-
-#ifdef DEBUG_GRAYS
-          check_sort( ras.cells, ras.num_cells );
-          dump_cells( RAS_VAR );
-#endif
-
-          grays_sweep( RAS_VAR_  &ras.target );
-          band--;
-          continue;
-        }
-
-        /* render pool overflow, we will reduce the render band by half */
-        bottom = band->min;
-        top    = band->max;
-        middle = bottom + ( ( top - bottom ) >> 1 );
-
-        /* waoow! This is too complex for a single scanline, something */
-        /* must be really rotten here!                                 */
-        if ( middle == bottom )
-        {
-#ifdef DEBUG_GRAYS
-          fprintf( stderr, "Rotten glyph!\n" );
-#endif
-          return 1;
-        }
-
-        if ( bottom-top >= ras.band_size )
-          ras.band_shoot++;
-
-        band[1].min = bottom;
-        band[1].max = middle;
-        band[0].min = middle;
-        band[0].max = top;
-        band++;
-      }
-    }
-
-    if ( ras.band_shoot > 8 && ras.band_size > 16 )
-      ras.band_size = ras.band_size / 2;
-
-    return 0;
-  }
-
-
-  extern
-  int  grays_raster_render( PRaster            raster,
-                            FT_Raster_Params*  params )
-  {
-    FT_Outline*  outline = (FT_Outline*)params->source;
-    FT_Bitmap*   target_map = params->target;
-
-
-    if ( !raster || !raster->cells || !raster->max_cells )
-      return -1;
-
-    /* return immediately if the outline is empty */
-    if ( outline->n_points == 0 || outline->n_contours <= 0 )
-      return 0;
-
-    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 -1;
-
-    /* XXXX: this version does not support monochrome rendering yet! */
-    if ( !(params->flags & ft_raster_flag_aa) )
-      return -1;
-
-    ras.outline   = *outline;
-    ras.target    = *target_map;
-    ras.num_cells = 0;
-    ras.invalid   = 1;
-
-    ras.render_span      = (FT_Raster_Span_Func)grays_render_span;
-    ras.render_span_data = &ras;
-
-    if ( params->flags & ft_raster_flag_direct )
-    {
-      ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
-      ras.render_span_data = params->user;
-    }
-
-    return grays_convert_glyph( (PRaster)raster, outline );
-  }
-
-
-  /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/
-  /****                         a static object.                  *****/
-
-#ifdef _STANDALONE_
-
-  static
-  int  grays_raster_new( void*       memory,
-                         FT_Raster*  araster )
-  {
-    static TRaster  the_raster;
-
-    UNUSED( memory );
-
-
-    *araster = (FT_Raster)&the_raster;
-    memset( &the_raster, 0, sizeof ( the_raster ) );
-
-    return 0;
-  }
-
-
-  static
-  void  grays_raster_done( FT_Raster  raster )
-  {
-    /* nothing */
-    UNUSED( raster );
-  }
-
-#else /* _STANDALONE_ */
-
-  static
-  int  grays_raster_new( FT_Memory   memory,
-                         FT_Raster*  araster )
-  {
-    FT_Error  error;
-    PRaster   raster;
-
-
-    *araster = 0;
-    if ( !ALLOC( raster, sizeof ( TRaster ) ) )
-    {
-      raster->memory = memory;
-      *araster = (FT_Raster)raster;
-    }
-
-    return error;
-  }
-
-
-  static
-  void grays_raster_done( FT_Raster  raster )
-  {
-    FT_Memory  memory = (FT_Memory)((PRaster)raster)->memory;
-
-
-    FREE( raster );
-  }
-
-#endif /* _STANDALONE_ */
-
-
-  static
-  void  grays_raster_reset( FT_Raster    raster,
-                            const char*  pool_base,
-                            long         pool_size )
-  {
-    PRaster  rast = (PRaster)raster;
-
-
-    if ( raster && pool_base && pool_size >= 4096 )
-      init_cells( rast, (char*)pool_base, pool_size );
-
-    rast->band_size  = ( pool_size / sizeof ( TCell ) ) / 8;
-  }
-
-
-  FT_Raster_Funcs  ft_grays_raster =
-  {
-    ft_glyph_format_outline,
-
-    (FT_Raster_New_Func)     grays_raster_new,
-    (FT_Raster_Reset_Func)   grays_raster_reset,
-    (FT_Raster_Set_Mode_Func)0,
-    (FT_Raster_Render_Func)  grays_raster_render,
-    (FT_Raster_Done_Func)    grays_raster_done
-  };
-
-
-/* END */
--- a/src/base/ftinit.c
+++ b/src/base/ftinit.c
@@ -20,8 +20,8 @@
   /*  The purpose of this file is to implement the following two           */
   /*  functions:                                                           */
   /*                                                                       */
-  /*  FT_Default_Drivers():                                                */
-  /*     This function is used to add the set of default drivers to a      */
+  /*  FT_Add_Default_Modules():                                            */
+  /*     This function is used to add the set of default modules to a      */
   /*     fresh new library object.  The set is taken from the header file  */
   /*     `freetype/config/ftmodule.h'.  See the document `FreeType 2.0     */
   /*     Build System' for more information.                               */
@@ -40,7 +40,7 @@
 #include <freetype/config/ftconfig.h>
 #include <freetype/internal/ftobjs.h>
 #include <freetype/internal/ftdebug.h>
-#include <freetype/internal/ftdriver.h>
+#include <freetype/ftmodule.h>
 
 
   /*************************************************************************/
@@ -52,16 +52,16 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_init
 
-#undef  FT_DRIVER
-#define FT_DRIVER( x )  extern FT_DriverInterface  x;
+#undef  FT_USE_MODULE
+#define FT_USE_MODULE( x )  extern const FT_Module_Class*  x;
 
 #include <freetype/config/ftmodule.h>
 
-#undef  FT_DRIVER
-#define FT_DRIVER( x )  &x,
+#undef  FT_USE_MODULE
+#define FT_USE_MODULE( x )  (const FT_Module_Class*)&x,
 
 static
-const FT_DriverInterface*  ft_default_drivers[] =
+const FT_Module_Class*  ft_default_modules[] =
   {
 #include <freetype/config/ftmodule.h>
     0
@@ -71,7 +71,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_Default_Drivers                                                 */
+  /*    FT_Add_Default_Modules                                             */
   /*                                                                       */
   /* <Description>                                                         */
   /*    Adds the set of default drivers to a given library object.         */
@@ -79,23 +79,22 @@
   /* <InOut>                                                               */
   /*    library :: A handle to a new library object.                       */
   /*                                                                       */
-  FT_EXPORT_FUNC( void )  FT_Default_Drivers( FT_Library  library )
+  FT_EXPORT_FUNC( void )  FT_Add_Default_Modules( FT_Library  library )
   {
-    FT_Error                    error;
-    const FT_DriverInterface**  cur;
+    FT_Error                 error;
+    const FT_Module_Class**  cur;
 
+    /* test for valid library delayed to FT_Add_Module() */
 
-    /* test for valid library delayed to FT_Add_Driver() */
-
-    cur = ft_default_drivers;
+    cur = ft_default_modules;
     while ( *cur )
     {
-      error = FT_Add_Driver( library, *cur );
+      error = FT_Add_Module( library, *cur );
       /* notify errors, but don't stop */
       if ( error )
       {
-        FT_ERROR(( "FT_Default_Drivers: Cannot install `%s', error = %x\n",
-                   (*cur)->driver_name, error ));
+        FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = %x\n",
+                   (*cur)->module_name, error ));
       }
       cur++;
     }
@@ -115,7 +114,7 @@
   /*    library :: A handle to a new library object.                       */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    FreeTyoe error code.  0 means success.                             */
   /*                                                                       */
   FT_EXPORT_FUNC( FT_Error )  FT_Init_FreeType( FT_Library*  library )
   {
@@ -139,7 +138,7 @@
 
     error = FT_New_Library( memory, library );
     if ( !error )
-      FT_Default_Drivers( *library );
+      FT_Add_Default_Modules( *library );
 
     return error;
   }
--- a/src/base/ftmm.c
+++ b/src/base/ftmm.c
@@ -47,8 +47,8 @@
       FT_Get_MM_Func  func;
 
 
-      func = (FT_Get_MM_Func)driver->interface.get_interface(
-                                       driver, "get_mm" );
+      func = (FT_Get_MM_Func)driver->root.clazz->get_interface(
+                                       FT_MODULE(driver), "get_mm" );
       if ( func )
         error = func( face, master );
     }
@@ -76,8 +76,8 @@
       FT_Set_MM_Design_Func  func;
 
 
-      func = (FT_Set_MM_Design_Func)driver->interface.get_interface(
-                                             driver, "set_mm_design" );
+      func = (FT_Set_MM_Design_Func)driver->root.clazz->get_interface(
+                                           FT_MODULE(driver), "set_mm_design" );
       if ( func )
         error = func( face, num_coords, coords );
     }
@@ -105,8 +105,8 @@
       FT_Set_MM_Blend_Func  func;
 
 
-      func = (FT_Set_MM_Blend_Func)driver->interface.get_interface(
-                                             driver, "set_mm_blend" );
+      func = (FT_Set_MM_Blend_Func)driver->root.clazz->get_interface(
+                                           FT_MODULE(driver), "set_mm_blend" );
       if ( func )
         error = func( face, num_coords, coords );
     }
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -199,7 +199,19 @@
     }
   }
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                           S T R E A M                           ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -298,12 +310,15 @@
   }
 
 
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_objs
+
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
   /****                                                                 ****/
   /****                                                                 ****/
-  /****               O B J E C T   M A N A G E M E N T                 ****/
+  /****                     G L Y P H   L O A D E R                     ****/
   /****                                                                 ****/
   /****                                                                 ****/
   /*************************************************************************/
@@ -310,425 +325,421 @@
   /*************************************************************************/
   /*************************************************************************/
 
+  /**************************************************************************
+   *
+   *  The glyph loader is a simple object which is used to load a set of
+   *  glyphs easily. It is critical for the correct loading of composites.
+   *
+   *  Ideally, one can see it as a stack of abstract "glyph" objects.
+   *
+   *  loader.base      is really the bottom of the stack. It describes a
+   *                   single glyph image made of the juxtaposition of several
+   *                   glyphs (those 'in the stack')
+   *
+   *  loader.current   describes the top of the stack, on which a new
+   *                   glyph can be loaded.
+   *
+   *  Rewind   clears the stack
+   *  Prepare  means set up "loader.current" for addition of a new glyph image
+   *  Add      means add the 'current' glyph image to the 'base' one, and
+   *           prepare for another one..
+   *
+   *  the glyph loader is now a base object. Each driver used to re-implement
+   *  it in one way or the other, which wasted code and energy..
+   *
+   *************************************************************************/
 
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_objs
-
-
-  /* destructor for sizes list */
-  static
-  void  destroy_size( FT_Memory  memory,
-                      FT_Size    size,
-                      FT_Driver  driver )
+ /* create a new glyph loader */
+  BASE_FUNC(FT_Error)  FT_GlyphLoader_New( FT_Memory        memory,
+                                           FT_GlyphLoader* *aloader )
   {
-    /* finalize format-specific stuff */
-    driver->interface.done_size( size );
-    FREE( size );
+    FT_GlyphLoader*  loader;
+    FT_Error         error;
+
+    if (!ALLOC(loader, sizeof(*loader)))
+    {
+      loader->memory = memory;
+      *aloader       = loader;
+    }
+    return error;
   }
 
 
-  /* destructor for faces list */
-  static
-  void  destroy_face( FT_Memory  memory,
-                      FT_Face    face,
-                      FT_Driver  driver )
+ /* rewind the glyph loader - reset counters to 0 */
+  BASE_FUNC(void)      FT_GlyphLoader_Rewind( FT_GlyphLoader*  loader )
   {
-    /* Discard glyph slots for this face                                */
-    /* XXX: Beware!  FT_Done_GlyphSlot() changes the field `face->slot' */
-    while ( face->glyph )
-      FT_Done_GlyphSlot( face->glyph );
+    FT_GlyphLoad*  base    = &loader->base;
+    FT_GlyphLoad*  current = &loader->current;
 
-    /* Discard all sizes for this face */
-    FT_List_Finalize( &face->sizes_list,
-                     (FT_List_Destructor)destroy_size,
-                     memory,
-                     driver );
-    face->size = 0;
+    base->outline.n_points   = 0;
+    base->outline.n_contours = 0;
+    base->num_subglyphs      = 0;
 
-    /* finalize format-specific stuff */
-    driver->interface.done_face( face );
+    *current = *base;
+  }
 
-    /* Now discard client data */
-    if ( face->generic.finalizer )
-      face->generic.finalizer( face );
 
-    /* close the stream for this face */
-    ft_done_stream( &face->stream );
+ /* reset the glyph loader, frees all allocated tables and starts from zero */
+  BASE_FUNC(void)      FT_GlyphLoader_Reset( FT_GlyphLoader*  loader )
+  {
+    FT_Memory memory = loader->memory;
 
-    /* get rid of it */
-    FREE( face );
+    FREE( loader->base.outline.points );
+    FREE( loader->base.outline.tags );
+    FREE( loader->base.outline.contours );
+    FREE( loader->base.extra_points );
+    FREE( loader->base.subglyphs );
+
+    loader->max_points    = 0;
+    loader->max_contours  = 0;
+    loader->max_subglyphs = 0;
+
+    FT_GlyphLoader_Rewind( loader );
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Destroy_Driver                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Destroys a given driver object.  This also destroys all child      */
-  /*    faces.                                                             */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*     driver :: A handle to the target driver object.                   */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*     The driver _must_ be LOCKED!                                      */
-  /*                                                                       */
-  static
-  void  Destroy_Driver( FT_Driver  driver )
+ /* delete a glyph loader */
+  BASE_FUNC(void)     FT_GlyphLoader_Done( FT_GlyphLoader*  loader )
   {
-    FT_Memory  memory = driver->memory;
+    if (loader)
+    {
+      FT_Memory memory = loader->memory;
 
+      FT_GlyphLoader_Reset(loader);
+      FREE( loader );
+    }
+  }
 
-    /* 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 );
+ /* re-adjust the 'current' outline fields */
+  static void FT_GlyphLoader_Adjust_Points( FT_GlyphLoader*  loader )
+  {
+    FT_Outline*  base    = &loader->base.outline;
+    FT_Outline*  current = &loader->current.outline;
 
-    /* finalize client-data */
-    if ( driver->generic.finalizer )
-      driver->generic.finalizer( driver );
-
-    /* discard it */
-    FREE( driver );
+    current->points   = base->points   + base->n_points;
+    current->tags     = base->tags     + base->n_points;
+    current->contours = base->contours + base->n_contours;
+    
+    /* handle extra points table - if any */
+    if (loader->use_extra)
+      loader->current.extra_points = loader->base.extra_points + base->n_points;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*   FT_Get_Raster                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*   Returns the raster interface corresponding to a given glyph format  */
-  /*   tag.                                                                */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*   library      :: A handle to the source library object.              */
-  /*                                                                       */
-  /*   glyph_format :: The glyph format tag.                               */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*   raster_funcs :: If this field is not 0, the raster's interface      */
-  /*                   functions are returned.                             */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*   A pointer to the corresponding raster object.                       */
-  /*                                                                       */
-  FT_EXPORT_FUNC( FT_Raster )  FT_Get_Raster(
-                                 FT_Library        library,
-                                 FT_Glyph_Format   glyph_format,
-                                 FT_Raster_Funcs*  raster_funcs )
+
+  BASE_FUNC(FT_Error)  FT_GlyphLoader_Create_Extra( FT_GlyphLoader*  loader )
   {
-    FT_Int  n;
+    FT_Error   error;
+    FT_Memory  memory = loader->memory;
+    
+    if ( !ALLOC_ARRAY( loader->base.extra_points,
+                       loader->max_points, FT_Vector ) )
+    {
+      loader->use_extra = 1;
+      FT_GlyphLoader_Adjust_Points(loader);
+    }
+    return error;
+  }
 
 
-    if ( !library )
-      return 0;
 
-    for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ )
-    {
-      FT_Raster_Funcs*  funcs = &library->raster_funcs[n];
 
+ /* re-adjust the 'current' subglyphs field */
+  static void FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader*  loader )
+  {
+    FT_GlyphLoad* base    = &loader->base;
+    FT_GlyphLoad* current = &loader->current;
 
-      if ( funcs->glyph_format == glyph_format )
-      {
-        if ( raster_funcs )
-          *raster_funcs = *funcs;
-        return library->rasters[n];
-      }
-    }
-    return 0;
+    current->subglyphs = base->subglyphs + base->num_subglyphs;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_Set_Raster                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Registers a given raster to the library.                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    library      :: A handle to a target library object.               */
-  /*                                                                       */
-  /*    raster_funcs :: A pointer to the raster's interface functions.     */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This function will do the following:                               */
-  /*                                                                       */
-  /*    - A new raster object is created through `raster_func.raster_new'. */
-  /*      If this fails, the function returns.                             */
-  /*                                                                       */
-  /*    - If a raster is already registered for the glyph format           */
-  /*      specified in raster_funcs, it will be destroyed.                 */
-  /*                                                                       */
-  /*    - The new raster is registered for the glyph format.               */
-  /*                                                                       */
-  FT_EXPORT_FUNC( FT_Error )  FT_Set_Raster( FT_Library        library,
-                                             FT_Raster_Funcs*  raster_funcs )
+ /* ensure that we can add n_points and n_contours to our glyph. this */
+ /* function reallocates its outline tables if necessary. Note that   */
+ /* it DOESN'T change the number of points within the loader !!       */
+  BASE_FUNC(FT_Error) FT_GlyphLoader_Check_Points( FT_GlyphLoader* loader,
+                                                   FT_UInt         n_points,
+                                                   FT_UInt         n_contours )
   {
-    FT_Glyph_Format  glyph_format;
-    FT_Raster_Funcs* funcs;
-    FT_Raster        raster;
-    FT_Error         error;
-    FT_Int           n, index;
+    FT_Memory    memory  = loader->memory;
+    FT_Error     error   = FT_Err_Ok;
+    FT_Outline*  base    = &loader->base.outline;
+    FT_Outline*  current = &loader->current.outline;
+    FT_Bool      adjust  = 1;
 
+    FT_UInt  new_max;
 
-    if ( !library )
-      return FT_Err_Invalid_Library_Handle;
+    /* check points & tags */
+    new_max = base->n_points + current->n_points + n_points;
+    if (new_max > loader->max_points)
+    {
+      new_max = (new_max+7) & -8;
+      if ( REALLOC_ARRAY( base->points, base->n_points, new_max, FT_Vector ) ||
+           REALLOC_ARRAY( base->tags,   base->n_points, new_max, FT_Byte   ) )
+       goto Exit;
 
-    if ( !raster_funcs )
-      return FT_Err_Invalid_Argument;
+      if ( loader->use_extra &&
+           REALLOC_ARRAY( loader->base.extra_points, base->n_points, new_max,
+                          FT_Vector ) )
+       goto Exit;
 
-    glyph_format = raster_funcs->glyph_format;
+      adjust = 1;
+      loader->max_points = new_max;
+    }
 
-    if ( glyph_format == ft_glyph_format_none )
-      return FT_Err_Invalid_Argument;
+    /* check contours */
+    new_max = base->n_contours + current->n_contours +
+              n_contours;
+    if (new_max > loader->max_contours)
+    {
+      new_max = (new_max+3) & -4;
+      if (REALLOC_ARRAY( base->contours, base->n_contours, new_max, FT_Short ))
+        goto Exit;
 
-    /* create a new raster object */
-    error = raster_funcs->raster_new( library->memory, &raster );
-    if ( error )
-      goto Exit;
+      adjust = 1;
+      loader->max_contours = new_max;
+    }
 
-    raster_funcs->raster_reset( raster,
-                                library->raster_pool,
-                                library->raster_pool_size );
+    if (adjust)
+      FT_GlyphLoader_Adjust_Points( loader );
 
-    index = -1;
-    for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ )
-    {
-      FT_Raster_Funcs*  funcs = library->raster_funcs + n;
+  Exit:
+    return error;
+  }
 
 
-      /* record the first vacant entry in `index' */
-      if ( index < 0 && funcs->glyph_format == ft_glyph_format_none )
-        index = n;
+ /* ensure that we can add n_subglyphs to our glyph. this function    */
+ /* reallocates its subglyphs table if necessary. Note that it DOES   */
+ /* NOT change the number of subglyphs within the loader !!           */
+  BASE_FUNC(FT_Error)  FT_GlyphLoader_Check_Subglyphs( FT_GlyphLoader*  loader,
+                                                       FT_UInt          n_subs )
+  {
+    FT_Memory  memory = loader->memory;
+    FT_Error   error  = FT_Err_Ok;
+    FT_UInt    new_max;
 
-      /* compare this entry's glyph format with the one we need */
-      if ( funcs->glyph_format == glyph_format )
-      {
-        /* A raster already exists for this glyph format.  We will */
-        /* destroy it before updating its entry in the table.      */
-        funcs->raster_done( library->rasters[n] );
-        index = n;
-        break;
-      }
-    }
+    FT_GlyphLoad*  base    = &loader->base;
+    FT_GlyphLoad*  current = &loader->current;
 
-    if ( index < 0 )
+    new_max = base->num_subglyphs + current->num_subglyphs + n_subs;
+    if (new_max > loader->max_subglyphs)
     {
-      /* the table is full and has no vacant entries */
-      error = FT_Err_Too_Many_Glyph_Formats;
-      goto Fail;
-    }
+      new_max = (new_max+1) & -2;
+      if (REALLOC_ARRAY( base->subglyphs, base->num_subglyphs,
+                         new_max, FT_SubGlyph ))
+        goto Exit;
 
-    funcs  = library->raster_funcs + index;
-    *funcs = *raster_funcs;
-    library->rasters[index] = raster;
+      loader->max_subglyphs = new_max;
 
+      FT_GlyphLoader_Adjust_Subglyphs( loader );
+    }
+
   Exit:
     return error;
-
-  Fail:
-    raster_funcs->raster_done( raster );
-    goto Exit;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_Unset_Raster                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Removes a given raster from the library.                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    library      :: A handle to a target library object.               */
-  /*                                                                       */
-  /*    raster_funcs :: A pointer to the raster's interface functions.     */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_EXPORT_DEF( FT_Error )  FT_Unset_Raster(
-                               FT_Library        library,
-                               FT_Raster_Funcs*  raster_funcs )
+ /* prepare loader for the addition of a new glyph on top of the base one */
+  BASE_FUNC(void)      FT_GlyphLoader_Prepare( FT_GlyphLoader*  loader )
   {
-    FT_Glyph_Format  glyph_format;
-    FT_Error         error;
-    FT_Int           n;
+    FT_GlyphLoad*  current = &loader->current;
 
+    current->outline.n_points   = 0;
+    current->outline.n_contours = 0;
+    current->num_subglyphs      = 0;
 
-    if ( !library )
-      return FT_Err_Invalid_Library_Handle;
+    FT_GlyphLoader_Adjust_Points   ( loader );
+    FT_GlyphLoader_Adjust_Subglyphs( loader );
+  }
 
-    error = FT_Err_Invalid_Argument;
 
-    if ( !raster_funcs )
-      goto Exit;
+ /* add current glyph to the base image - and prepare for another */
+  BASE_FUNC(void)      FT_GlyphLoader_Add( FT_GlyphLoader*  loader )
+  {
+    FT_GlyphLoad*  base    = &loader->base;
+    FT_GlyphLoad*  current = &loader->current;
 
-    glyph_format = raster_funcs->glyph_format;
+    FT_UInt        n_curr_contours = current->outline.n_contours;
+    FT_UInt        n_base_points   = base->outline.n_points;
+    FT_UInt        n;
 
-    if ( glyph_format == ft_glyph_format_none )
-      goto Exit;
+    base->outline.n_points   += current->outline.n_points;
+    base->outline.n_contours += current->outline.n_contours;
+    base->num_subglyphs      += current->num_subglyphs;
 
-    for ( n = 0; n < FT_MAX_GLYPH_FORMATS; n++ )
-    {
-      FT_Raster_Funcs*  funcs = library->raster_funcs + n;
+    /* adjust contours count in newest outline */
+    for ( n = 0; n < n_curr_contours; n++ )
+      current->outline.contours[n] += n_base_points;
 
+    /* prepare for another new glyph image */
+    FT_GlyphLoader_Prepare( loader );
+  }
 
-      if ( funcs->glyph_format == glyph_format )
-      {
-        funcs->raster_done( library->rasters[n] );
-        library->rasters[n]                   = 0;
-        library->raster_funcs[n].glyph_format = ft_glyph_format_none;
-        error = FT_Err_Ok;
-        break;
-      }
+
+  BASE_FUNC(FT_Error)   FT_GlyphLoader_Copy_Points( FT_GlyphLoader*  target,
+                                                    FT_GlyphLoader*  source )
+  {
+    FT_Error  error;
+    FT_UInt   num_points   = source->base.outline.n_points;
+    FT_UInt   num_contours = source->base.outline.n_contours;
+    
+    error = FT_GlyphLoader_Check_Points( target, num_points, num_contours );
+    if (!error)
+    {
+      FT_Outline*  out = &target->base.outline;
+      FT_Outline*  in  = &source->base.outline;
+      
+      MEM_Copy( out->points,   in->points, num_points * sizeof(FT_Vector) );
+      MEM_Copy( out->tags,     in->tags,   num_points * sizeof(char) );
+      MEM_Copy( out->contours, in->contours, num_contours * sizeof(short) );
+      
+      /* do we need to copy the extra points ? */
+      if (target->use_extra && source->use_extra)
+        MEM_Copy( target->base.extra_points, source->base.extra_points,
+                  num_points * sizeof(FT_Vector) );
+                  
+      out->n_points   = num_points;
+      out->n_contours = num_contours;
+      
+      FT_GlyphLoader_Adjust_Points( target );
     }
+    return error;                                         
+  }                                           
 
-  Exit:
-    return error;
-  }
 
 
   /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_Set_Raster_Mode                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets a raster-specific mode.                                       */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    library :: A handle to a target library object.                    */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    format  :: The glyph format used to select the raster.             */
-  /*                                                                       */
-  /*    mode    :: The raster-specific mode descriptor.                    */
-  /*                                                                       */
-  /*    args    :: The mode arguments.                                     */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_EXPORT_FUNC( FT_Error )  FT_Set_Raster_Mode( FT_Library       library,
-                                                  FT_Glyph_Format  format,
-                                                  unsigned long    mode,
-                                                  void*            args )
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****               FACE, SIZE & GLYPH SLOT OBJECTS                   ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  static  FT_Error  ft_glyphslot_init( FT_GlyphSlot  slot )
   {
-    FT_Raster_Funcs  funcs;
-    FT_Raster        raster;
+    FT_Driver         driver = slot->face->driver;
+    FT_Driver_Class*  clazz  = driver->clazz;
+    FT_Memory         memory = driver->root.memory;
+    FT_Error          error  = FT_Err_Ok;
 
+    if (FT_DRIVER_USES_OUTLINES(driver))
+      error = FT_GlyphLoader_New( memory, &slot->loader );
 
-    if ( !library )
-      return FT_Err_Invalid_Library_Handle;
+    if (!error && clazz->init_slot)
+      error = clazz->init_slot( slot );
 
-    raster = FT_Get_Raster( library, format, &funcs );
-    if ( raster && args && funcs.raster_set_mode )
-      return funcs.raster_set_mode( raster, mode, args );
-    else
-      return FT_Err_Invalid_Argument;
+    return error;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_Set_Debug_Hook                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets a debug hook function for debugging the interpreter of a      */
-  /*    font format.                                                       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    library    :: A handle to the library object.                      */
-  /*                                                                       */
-  /*    hook_index :: The index of the debug hook.  You should use the     */
-  /*                  values defined in ftobjs.h, e.g.                     */
-  /*                  FT_DEBUG_HOOK_TRUETYPE                               */
-  /*                                                                       */
-  /*    debug_hook :: The function used to debug the interpreter.          */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    Currently, four debug hook slots are available, but only two (for  */
-  /*    the TrueType and the Type 1 interpreter) are defined.              */
-  /*                                                                       */
-  FT_EXPORT_FUNC( void )  FT_Set_Debug_Hook( FT_Library         library,
-                                             FT_UInt            hook_index,
-                                             FT_DebugHook_Func  debug_hook )
+  static  void      ft_glyphslot_clear( FT_GlyphSlot  slot )
   {
-    if ( library && debug_hook &&
-         hook_index <
-           ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )
-      library->debug_hooks[hook_index] = debug_hook;
+    /* clear all public fields in the glyph slot */
+    MEM_Set( &slot->metrics, 0, sizeof(slot->metrics) );
+    MEM_Set( &slot->outline, 0, sizeof(slot->outline) );
+    MEM_Set( &slot->bitmap,  0, sizeof(slot->bitmap)  );
+
+    slot->bitmap_left   = 0;
+    slot->bitmap_top    = 0;
+    slot->num_subglyphs = 0;
+    slot->subglyphs     = 0;
+    slot->control_data  = 0;
+    slot->control_len   = 0;
+    slot->other         = 0;
+    slot->format        = 0;
+
+    slot->linearHoriAdvance = 0;
+    slot->linearVertAdvance = 0;
   }
 
 
+  static  void      ft_glyphslot_done( FT_GlyphSlot  slot )
+  {
+    FT_Driver         driver = slot->face->driver;
+    FT_Driver_Class*  clazz  = driver->clazz;
+    FT_Memory         memory = driver->root.memory;
+
+    /* free bitmap buffer if needed */
+    if ( slot->flags & ft_glyph_own_bitmap )
+      FREE( slot->bitmap.buffer );
+
+    /* free glyph loader */
+    if (FT_DRIVER_USES_OUTLINES(driver))
+    {
+      FT_GlyphLoader_Done( slot->loader );
+      slot->loader = 0;
+    }
+
+    if (clazz->done_slot)
+      clazz->done_slot( slot );
+  }
+
+
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_New_Library                                                     */
+  /*    FT_New_GlyphSlot                                                   */
   /*                                                                       */
   /* <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.           */
+  /*    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>                                                               */
-  /*    memory   :: A handle to the original memory object.                */
+  /*    face  :: A handle to a parent face object.                         */
   /*                                                                       */
   /* <Output>                                                              */
-  /*    alibrary :: A pointer to handle of a new library object.           */
+  /*    aslot :: A handle to a new glyph slot object.                      */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_EXPORT_FUNC( FT_Error )  FT_New_Library( FT_Memory    memory,
-                                              FT_Library*  alibrary )
+
+  FT_EXPORT_FUNC( FT_Error )  FT_New_GlyphSlot( FT_Face        face,
+                                                FT_GlyphSlot*  aslot )
   {
-    FT_Library  library = 0;
-    FT_Error    error;
+    FT_Error           error;
+    FT_Driver          driver;
+    FT_Driver_Class*   clazz;
+    FT_Memory          memory;
+    FT_GlyphSlot       slot;
 
+    *aslot = 0;
 
-    if ( !memory )
+    if ( !face || !aslot || !face->driver )
       return FT_Err_Invalid_Argument;
 
-    /* first of all, allocate the library object */
-    if ( ALLOC( library, sizeof ( *library ) ) )
-      return error;
+    driver = face->driver;
+    clazz  = driver->clazz;
+    memory = driver->root.memory;
 
-    library->memory = memory;
+    FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
+    if ( !ALLOC( slot, clazz->slot_object_size ) )
+    {
+      slot->face = face;
 
-    /* allocate the render pool */
-    library->raster_pool_size = FT_RENDER_POOL_SIZE;
-    if ( ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
-      goto Fail;
+      error = ft_glyphslot_init( slot );
+      if (error)
+      {
+        ft_glyphslot_done( slot );
+        FREE( slot );
+        goto Exit;
+      }
 
-    /* now register the default raster for the `outline' glyph image */
-    /* format for now, ignore the error...                           */
-    error = FT_Set_Raster( library, &ft_default_raster );
+      *aslot = slot;
+    }
 
-    /* That's ok now */
-    *alibrary = library;
-
-    return FT_Err_Ok;
-
-  Fail:
-    FREE( library );
+  Exit:
+    FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
     return error;
   }
 
@@ -736,140 +747,108 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_Done_Library                                                    */
+  /*    FT_Done_GlyphSlot                                                  */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Discards a given library object.  This closes all drivers and      */
-  /*    discards all resource objects.                                     */
+  /*    Destroys a given glyph slot.  Remember however that all slots are  */
+  /*    automatically destroyed with its parent.  Using this function is   */
+  /*    not always mandatory.                                              */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    library :: A handle to the target library.                         */
+  /*    slot :: A handle to a target glyph slot.                           */
   /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_EXPORT_FUNC( FT_Error )  FT_Done_Library( FT_Library  library )
+  FT_EXPORT_FUNC( void )  FT_Done_GlyphSlot( FT_GlyphSlot  slot )
   {
-    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++ )
+    if ( slot )
     {
-      FT_Driver  driver = library->drivers[n];
+      FT_Driver         driver = slot->face->driver;
+      FT_Memory         memory = driver->root.memory;
+      FT_GlyphSlot*     parent;
+      FT_GlyphSlot      cur;
 
-
-      if ( driver )
+      /* Remove slot from its parent face's list */
+      parent = &slot->face->glyph;
+      cur    = *parent;
+      while ( cur )
       {
-        Destroy_Driver( driver );
-        library->drivers[n] = 0;
-      }
-    }
-
-    /* Destroy raster objects */
-    FREE( library->raster_pool );
-    library->raster_pool_size = 0;
-
-    {
-      FT_Raster_Funcs*  cur    = library->raster_funcs;
-      FT_Raster_Funcs*  limit  = cur + FT_MAX_GLYPH_FORMATS;
-      FT_Raster*        raster = library->rasters;
-
-      for ( ; cur < limit; cur++, raster++ )
-      {
-        if ( cur->glyph_format != ft_glyph_format_none )
+        if ( cur == slot )
         {
-          cur->raster_done( *raster );
-          *raster = 0;
-          cur->glyph_format = ft_glyph_format_none;
+          *parent = cur->next;
+          ft_glyphslot_done(slot);
+          FREE( slot );
+          break;
         }
+        cur = cur->next;
       }
     }
+  }
 
-    FREE( library );
 
-    return FT_Err_Ok;
-  }
 
+ /* forward declaration */
+  static  FT_Renderer  ft_lookup_glyph_renderer( FT_GlyphSlot  slot );
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_Add_Driver                                                      */
+  /*    FT_Set_Transform                                                   */
   /*                                                                       */
   /* <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.                */
+  /*    A function used to set the transformation that is applied to glyph */
+  /*    images just before they're converted to bitmaps in a glyph slot    */
+  /*    when FT_Render_Glyph is called..                                   */
   /*                                                                       */
   /* <InOut>                                                               */
-  /*    library          :: A handle to the target library object.         */
+  /*    face   :: A handle to the source face object.                      */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    driver_interface :: A pointer to a driver interface table.         */
+  /*    matrix :: A pointer to the transformation's 2x2 matrix.  Use 0 for */
+  /*              the identity matrix.                                     */
+  /*    delta  :: A pointer to the translation vector.  Use 0 for the null */
+  /*              vector.                                                  */
   /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
   /* <Note>                                                                */
-  /*    This function doesn't check whether the driver is already          */
-  /*    installed!                                                         */
+  /*    The transformation is only applied to scalable image formats.      */
   /*                                                                       */
-  FT_EXPORT_FUNC( FT_Error )  FT_Add_Driver(
-                                FT_Library                 library,
-                                const FT_DriverInterface*  driver_interface )
+  FT_EXPORT_FUNC( void )  FT_Set_Transform( FT_Face     face,
+                                            FT_Matrix*  matrix,
+                                            FT_Vector*  delta )
   {
-    FT_Error   error;
-    FT_Driver  driver;
-    FT_Memory  memory;
+    if ( !face )
+      return;
 
+    face->transform_flags = 0;
 
-    if ( !library )
-      return FT_Err_Invalid_Library_Handle;
-
-    if ( !driver_interface )
-      return FT_Err_Invalid_Argument;
-
-    memory = library->memory;
-    error  = FT_Err_Ok;
-
-    if ( library->num_drivers >= FT_MAX_DRIVERS )
-      error = FT_Err_Too_Many_Drivers;
-    else
+    if ( !matrix )
     {
-      if ( ALLOC( driver, driver_interface->driver_object_size ) )
-        goto Exit;
+      face->transform_matrix.xx = 0x10000L;
+      face->transform_matrix.xy = 0L;
+      face->transform_matrix.yx = 0L;
+      face->transform_matrix.yy = 0x10000L;
+      matrix = &face->transform_matrix;
+    }
+    else
+      face->transform_matrix = *matrix;
 
-      driver->library   = library;
-      driver->memory    = memory;
-      driver->interface = *driver_interface;
+    /* set transform_flags bit flag 0 if `matrix' isn't the identity */
+    if ( ( matrix->xy | matrix->yx ) ||
+         matrix->xx != 0x10000L      ||
+         matrix->yy != 0x10000L      )
+      face->transform_flags |= 1;
 
-      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 );
+    if ( !delta )
+    {
+      face->transform_delta.x = 0;
+      face->transform_delta.y = 0;
+      delta = &face->transform_delta;
     }
+    else
+      face->transform_delta = *delta;
 
-  Exit:
-    return error;
+    /* set transform_flags bit flag 1 if `delta' isn't the null vector */
+    if ( delta->x | delta->y )
+      face->transform_flags |= 2;
   }
 
 
@@ -876,63 +855,93 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_Remove_Driver                                                   */
+  /*    FT_Load_Glyph                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Unregisters a given driver.  This closes the driver, which in turn */
-  /*    destroys all faces, sizes, slots, etc. associated with it.         */
+  /*    A function used to load a single glyph within a given glyph slot,  */
+  /*    for a given size.                                                  */
   /*                                                                       */
-  /*    This function also DESTROYS the driver object.                     */
-  /*                                                                       */
   /* <Input>                                                               */
-  /*    driver :: A handle to target driver object.                        */
+  /*    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.                             */
   /*                                                                       */
-  FT_EXPORT_FUNC( FT_Error )  FT_Remove_Driver( FT_Driver  driver )
+  /* <Note>                                                                */
+  /*    If the glyph image is not a bitmap, and if the bit flag            */
+  /*    FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be         */
+  /*    transformed with the information passed to a previous call to      */
+  /*    FT_Set_Transform.                                                  */
+  /*                                                                       */
+  /*    Note that this also transforms the "face.glyph.advance" field,     */
+  /*    but **NOT** the values in "face.glyph.metrics"..                   */
+  /*                                                                       */
+
+  FT_EXPORT_FUNC( FT_Error )  FT_Load_Glyph( FT_Face  face,
+                                             FT_UInt  glyph_index,
+                                             FT_Int   load_flags )
   {
-    FT_Library  library;
-    FT_Memory   memory;
-    FT_Driver   *cur, *last;
-    FT_Error    error;
+    FT_Error      error;
+    FT_Driver     driver;
+    FT_GlyphSlot  slot;
 
+    if ( !face || !face->size || !face->glyph )
+      return FT_Err_Invalid_Face_Handle;
 
-    if ( !driver )
-      return FT_Err_Invalid_Driver_Handle;
+    if ( glyph_index >= face->num_glyphs )
+      return FT_Err_Invalid_Argument;
 
-    library = driver->library;
-    memory  = driver->memory;
+    slot = face->glyph;
+    ft_glyphslot_clear( slot );
 
-    if ( !library || !memory )
-      return FT_Err_Invalid_Driver_Handle;
+    driver = face->driver;
 
-    /* look-up driver entry in library table */
-    error = FT_Err_Invalid_Driver_Handle;
-    cur   = library->drivers;
-    last  = cur + library->num_drivers - 1;
+    /* when the flag NO_RECURSE is set, we disable hinting and scaling */
+    if ( load_flags & FT_LOAD_NO_RECURSE )
+      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
 
-    for ( ; cur <= last; cur++ )
+    error = driver->clazz->load_glyph( slot,
+                                       face->size,
+                                       glyph_index,
+                                       load_flags );
+    if (error) goto Exit;
+
+    /* compute the advance */
+    if (load_flags & FT_LOAD_VERTICAL_LAYOUT)
     {
-      if ( *cur == driver )
-      {
-        /* destroy the driver object */
-        Destroy_Driver( driver );
+      slot->advance.x = 0;
+      slot->advance.y = slot->metrics.vertAdvance;
+    }
+    else
+    {
+      slot->advance.x = slot->metrics.horiAdvance;
+      slot->advance.y = 0;
+    }
 
-        /* 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;
-      }
+    /* now, transform the glyph image when needed */
+    if (face->transform_flags)
+    {
+      /* get renderer */
+      FT_Renderer  renderer = ft_lookup_glyph_renderer( slot );
+      
+      if (renderer)
+        error = renderer->clazz->transform_glyph( renderer, slot,
+                                                  &face->transform_matrix,
+                                                  &face->transform_delta );
+      /* transform advance */                                            
+      FT_Vector_Transform( &slot->advance, &face->transform_matrix );                                                  
     }
 
+  Exit:                                       
     return error;
   }
 
@@ -940,39 +949,131 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_Get_Driver                                                      */
+  /*    FT_Load_Char                                                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Returns the handle of the driver responsible for a given format    */
-  /*    (or service) according to its `name'.                              */
+  /*    A function used to load a single glyph within a given glyph slot,  */
+  /*    for a given size, according to its character code !                */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    library     :: A handle to the library object.                     */
-  /*    driver_name :: The name of the driver to look up.                  */
+  /*    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>                                                              */
-  /*    A handle to the driver object, 0 otherwise.                        */
+  /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_EXPORT_FUNC( FT_Driver )  FT_Get_Driver( FT_Library  library,
-                                              char*       driver_name )
+  /* <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..                                                            */
+  /*                                                                       */
+  /*    If the glyph image is not a bitmap, and if the bit flag            */
+  /*    FT_LOAD_IGNORE_TRANSFORM is unset, the glyph image will be         */
+  /*    transformed with the information passed to a previous call to      */
+  /*    FT_Set_Transform.                                                  */
+  /*                                                                       */
+  /*    Note that this also transforms the "face.glyph.advance" field,     */
+  /*    but **NOT** the values in "face.glyph.metrics"..                   */
+  /*                                                                       */
+  FT_EXPORT_FUNC( FT_Error )  FT_Load_Char( FT_Face   face,
+                                            FT_ULong  char_code,
+                                            FT_Int    load_flags )
   {
-    FT_Driver  *cur, *limit;
+    FT_UInt    glyph_index;
 
+    if ( !face )
+      return FT_Err_Invalid_Face_Handle;
 
-    if ( !library || !driver_name )
-      return 0;
+    glyph_index = (FT_UInt)char_code;
+    if (face->charmap)
+      glyph_index = FT_Get_Char_Index( face, char_code );
 
-    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;
+    return glyph_index ? FT_Load_Glyph( face, glyph_index, load_flags )
+                       : FT_Err_Invalid_Character_Code;
   }
 
 
+
+
+  /* destructor for sizes list */
+  static
+  void  destroy_size( FT_Memory  memory,
+                      FT_Size    size,
+                      FT_Driver  driver )
+  {
+    /* finalize client-specific data */
+    if (size->generic.finalizer)
+      size->generic.finalizer( size );
+
+    /* finalize format-specific stuff */
+    if (driver->clazz->done_size)
+      driver->clazz->done_size( size );
+
+    FREE( size );
+  }
+
+
+  /* destructor for faces list */
+  static
+  void  destroy_face( FT_Memory  memory,
+                      FT_Face    face,
+                      FT_Driver  driver )
+  {
+    FT_Driver_Class*  clazz = driver->clazz;
+
+    /* Discard glyph slots for this face                           */
+    /* 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;
+
+    /* Now discard client data */
+    if ( face->generic.finalizer )
+      face->generic.finalizer( face );
+
+    /* finalize format-specific stuff */
+    if (clazz->done_face)
+      clazz->done_face(face);
+
+    /* close the stream for this face if needed */
+    if ( (face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM) == 0 )
+      ft_done_stream( &face->stream );
+
+    /* get rid of it */
+    FREE( face );
+  }
+
+
+  static  void  Destroy_Driver( FT_Driver  driver )
+  {
+    FT_List_Finalize( &driver->faces_list,
+                      (FT_List_Destructor)destroy_face,
+                      driver->root.memory,
+                      driver );
+
+    /* see if we need to drop the driver's glyph loader */
+    if (FT_DRIVER_USES_OUTLINES(driver))
+      FT_GlyphLoader_Done( driver->glyph_loader );
+      
+    
+  }
+
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -989,17 +1090,16 @@
                        FT_Parameter*  params,
                        FT_Face*       aface )
   {
-    FT_Memory            memory;
-    FT_DriverInterface*  interface;
-    FT_Face              face = 0;
-    FT_Error             error;
+    FT_Memory         memory;
+    FT_Driver_Class*  clazz;
+    FT_Face           face = 0;
+    FT_Error          error;
 
+    clazz  = driver->clazz;
+    memory = driver->root.memory;
 
-    interface = &driver->interface;
-    memory    = driver->memory;
-
     /* allocate the face object, and perform basic initialization */
-    if ( ALLOC( face, interface->face_object_size ) )
+    if ( ALLOC( face, clazz->face_object_size ) )
       goto Fail;
 
     face->driver = driver;
@@ -1006,11 +1106,11 @@
     face->memory = memory;
     face->stream = stream;
 
-    error = interface->init_face( stream,
-                                  face,
-                                  face_index,
-                                  num_params,
-                                  params );
+    error = clazz->init_face( stream,
+                              face,
+                              face_index,
+                              num_params,
+                              params );
     if ( error )
       goto Fail;
 
@@ -1019,7 +1119,7 @@
   Fail:
     if ( error )
     {
-      interface->done_face( face );
+      clazz->done_face( face );
       FREE( face );
       *aface = 0;
     }
@@ -1073,9 +1173,7 @@
   {
     FT_Open_Args  args;
 
-
     /* test for valid `library' and `aface' delayed to FT_Open_Face() */
-
     if ( !pathname )
       return FT_Err_Invalid_Argument;
 
@@ -1134,9 +1232,7 @@
   {
     FT_Open_Args  args;
 
-
     /* test for valid `library' and `face' delayed to FT_Open_Face() */
-
     if ( !file_base )
       return FT_Err_Invalid_Argument;
 
@@ -1211,8 +1307,7 @@
 
     /* create input stream */
     error = ft_new_input_stream( library, args, &stream );
-    if ( error )
-      goto Exit;
+    if ( error ) goto Exit;
 
     memory = library->memory;
 
@@ -1220,14 +1315,14 @@
     /* it.  Otherwise, we'll scan the list of registered drivers.   */
     if ( args->flags & ft_open_driver && args->driver )
     {
-      driver = args->driver;
-      /* not all drivers directly support face objects, so check... */
-      if ( driver->interface.face_object_size )
+      driver = FT_DRIVER(args->driver);
+
+      /* not all modules are drivers, so check... */
+      if ( FT_MODULE_IS_DRIVER(driver) )
       {
         FT_Int         num_params = 0;
         FT_Parameter*  params     = 0;
 
-
         if ( args->flags & ft_open_params )
         {
           num_params = args->num_params;
@@ -1247,18 +1342,18 @@
     else
     {
       /* check each font driver for an appropriate format */
-      FT_Driver*  cur   = library->drivers;
-      FT_Driver*  limit = cur + library->num_drivers;
+      FT_Module*  cur   = library->modules;
+      FT_Module*  limit = cur + library->num_modules;
 
       for ( ; cur < limit; cur++ )
       {
-        driver = *cur;
-        /* not all drivers directly support face objects, so check... */
-        if ( driver->interface.face_object_size )
+        /* not all modules are font drivers, so check... */
+        if ( FT_MODULE_IS_DRIVER(cur[0]) )
         {
           FT_Int         num_params = 0;
           FT_Parameter*  params     = 0;
 
+          driver     = FT_DRIVER(cur[0]);
 
           if ( args->flags & ft_open_params )
           {
@@ -1284,6 +1379,10 @@
   Success:
     FT_TRACE4(( "FT_New_Face: New face object, adding to list\n" ));
 
+    /* set the EXTERNAL_STREAM bit for FT_Done_Face */
+    if ( args->flags & ft_open_stream && args->stream )
+      face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
+
     /* add the face object to its driver's list */
     if ( ALLOC( node, sizeof ( *node ) ) )
       goto Fail;
@@ -1300,8 +1399,9 @@
 
       FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
       error = FT_New_GlyphSlot( face, &slot );
-      if ( error )
-        goto Fail;
+      if ( error ) goto Fail;
+      
+      face->glyph = slot;
     }
 
     /* finally, allocate a size object for the face */
@@ -1311,8 +1411,9 @@
 
       FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
       error = FT_New_Size( face, &size );
-      if ( error )
-        goto Fail;
+      if ( error ) goto Fail;
+      
+      face->size = size;
     }
 
     /* initialize transformation for convenience functions */
@@ -1419,9 +1520,8 @@
     FT_Error   error;
     FT_Driver  driver;
 
-    FTDriver_getInterface  get_interface;
+    FT_Driver_Class*  clazz;
 
-
     /* test for valid `parameters' delayed to ft_new_input_stream() */
 
     if ( !face )
@@ -1431,7 +1531,7 @@
     if ( !driver )
       return FT_Err_Invalid_Driver_Handle;
 
-    error = ft_new_input_stream( driver->library, parameters, &stream );
+    error = ft_new_input_stream( driver->root.library, parameters, &stream );
     if ( error )
       goto Exit;
 
@@ -1439,20 +1539,13 @@
     /* `attach_file' interface                                  */
 
     error = FT_Err_Unimplemented_Feature;
+    clazz = driver->clazz;
+    if (clazz->attach_file)
+      error = clazz->attach_file( face, stream );
 
-    get_interface = driver->interface.get_interface;
-    if ( get_interface )
-    {
-      FT_Attach_Reader  reader;
-
-
-      reader = (FT_Attach_Reader)(get_interface( driver, "attach_file" ));
-      if ( reader )
-        error = reader( face, stream );
-    }
-
     /* close the attached stream */
-    ft_done_stream( &stream );
+    if ( !parameters->stream || (parameters->flags & ft_open_stream) )
+      ft_done_stream( &stream );
 
   Exit:
     return error;
@@ -1476,38 +1569,30 @@
   /*                                                                       */
   FT_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;
+    FT_Error          error;
+    FT_Driver         driver;
+    FT_Memory         memory;
+    FT_ListNode       node;
 
-
-    if ( !face )
-      return FT_Err_Invalid_Face_Handle;
-
-    driver = face->driver;
-    if ( !driver )
-      return FT_Err_Invalid_Driver_Handle;
-
-    interface = &driver->interface;
-    memory    = driver->memory;
-
-    /* find face in driver's list */
-    node = FT_List_Find( &driver->faces_list, face );
-    if ( node )
+    error = FT_Err_Invalid_Face_Handle;
+    if ( face && face->driver )
     {
-      /* 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;
+      driver = face->driver;
+      memory = driver->root.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;
   }
 
@@ -1532,38 +1617,32 @@
   FT_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_Error          error;
+    FT_Memory         memory;
+    FT_Driver         driver;
+    FT_Driver_Class*  clazz;
 
-    FT_Size              size = 0;
-    FT_ListNode          node = 0;
+    FT_Size           size = 0;
+    FT_ListNode       node = 0;
 
-
-    if ( !face )
-      return FT_Err_Invalid_Face_Handle;
-
-    if ( !asize )
-      return FT_Err_Invalid_Argument;
-
     *asize = 0;
 
+    if ( !face || !asize || !face->driver )
+      return FT_Err_Invalid_Handle;
+
     driver = face->driver;
-    if ( !driver )
-      return FT_Err_Invalid_Driver_Handle;
+    clazz  = driver->clazz;
+    memory = face->memory;
 
-    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 )   ) )
+    if ( ALLOC( size, clazz->size_object_size ) ||
+         ALLOC( node, sizeof ( FT_ListNodeRec ) ) )
       goto Exit;
 
     size->face = face;
 
-    error = interface->init_size( size );
+    if (clazz->init_size)
+      error = clazz->init_size( size );
 
     /* in case of success, add to the face's list */
     if ( !error )
@@ -1571,9 +1650,6 @@
       *asize     = size;
       node->data = size;
       FT_List_Add( &face->sizes_list, node );
-
-      /* record as current size for the face */
-      face->size = size;
     }
 
   Exit:
@@ -1621,7 +1697,7 @@
     if ( !driver )
       return FT_Err_Invalid_Driver_Handle;
 
-    memory = driver->memory;
+    memory = driver->root.memory;
 
     error = FT_Err_Ok;
     node  = FT_List_Find( &face->sizes_list, size );
@@ -1680,6 +1756,27 @@
   /*    When dealing with fixed-size faces (i.e., non-scalable formats),   */
   /*    use the function FT_Set_Pixel_Sizes().                             */
   /*                                                                       */
+  
+    static void  ft_recompute_scaled_metrics( FT_Face           face,
+                                              FT_Size_Metrics*  metrics )
+    {                                              
+      /* Compute root ascender, descender, test height, and max_advance */
+      metrics->ascender    = ( FT_MulFix( face->ascender,
+                                          metrics->y_scale ) + 32 ) & -64;
+  
+      metrics->descender   = ( FT_MulFix( face->descender,
+                                          metrics->y_scale ) + 32 ) & -64;
+  
+      metrics->height      = ( FT_MulFix( face->height,
+                                     metrics->y_scale ) + 32 ) & -64;
+  
+      metrics->max_advance = ( FT_MulFix( face->max_advance_width,
+                                          metrics->x_scale ) + 32 ) & -64;
+    }
+
+
+
+  
   FT_EXPORT_FUNC( FT_Error )  FT_Set_Char_Size( FT_Face     face,
                                                 FT_F26Dot6  char_width,
                                                 FT_F26Dot6  char_height,
@@ -1686,39 +1783,35 @@
                                                 FT_UInt     horz_resolution,
                                                 FT_UInt     vert_resolution )
   {
-    FT_Error             error;
-    FT_Driver            driver;
-    FT_Memory            memory;
-    FT_DriverInterface*  interface;
-    FT_Size_Metrics*     metrics;
-    FT_Long              dim_x, dim_y;
+    FT_Error          error = FT_Err_Ok;
+    FT_Driver         driver;
+    FT_Memory         memory;
+    FT_Driver_Class*  clazz;
+    FT_Size_Metrics*  metrics;
+    FT_Long           dim_x, dim_y;
 
 
-    if ( !face )
+    if ( !face || !face->size || !face->driver )
       return FT_Err_Invalid_Face_Handle;
 
-    if ( !face->size )
-      return FT_Err_Invalid_Size_Handle;
-
-    driver = face->driver;
-    if ( !driver )
-      return FT_Err_Invalid_Driver_Handle;
-
+    driver  = face->driver;
     metrics = &face->size->metrics;
 
     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;
+    driver = face->driver;
+    clazz  = driver->clazz;
+    memory = driver->root.memory;
 
     /* default processing -- this can be overridden by the driver */
     if ( char_width  < 1 * 64 ) char_width  = 1 * 64;
@@ -1740,11 +1833,14 @@
       metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM );
     }
 
-    error = interface->set_char_sizes( face->size,
-                                       char_width,
-                                       char_height,
-                                       horz_resolution,
-                                       vert_resolution );
+    ft_recompute_scaled_metrics( face, metrics );
+
+    if (clazz->set_char_sizes)
+      error = clazz->set_char_sizes( face->size,
+                                     char_width,
+                                     char_height,
+                                     horz_resolution,
+                                     vert_resolution );
     return error;
   }
 
@@ -1776,29 +1872,24 @@
                                                   FT_UInt  pixel_width,
                                                   FT_UInt  pixel_height )
   {
-    FT_Error             error;
-    FT_Driver            driver;
-    FT_Memory            memory;
-    FT_DriverInterface*  interface;
-    FT_Size_Metrics*     metrics = &face->size->metrics;
+    FT_Error          error = FT_Err_Ok;
+    FT_Driver         driver;
+    FT_Memory         memory;
+    FT_Driver_Class*  clazz;
+    FT_Size_Metrics*  metrics = &face->size->metrics;
 
 
-    if ( !face )
+    if ( !face || !face->size || !face->driver )
       return FT_Err_Invalid_Face_Handle;
 
-    if ( !face->size )
-      return FT_Err_Invalid_Size_Handle;
-
     driver = face->driver;
-    if ( !driver )
-      return FT_Err_Invalid_Driver_Handle;
+    clazz  = driver->clazz;
+    memory = driver->root.memory;
 
-    interface = &driver->interface;
-    memory    = driver->memory;
-
     /* default processing -- this can be overridden by the driver */
     if ( pixel_width == 0 )
       pixel_width = pixel_height;
+
     else if ( pixel_height == 0 )
       pixel_height = pixel_width;
 
@@ -1817,82 +1908,12 @@
                                     face->units_per_EM );
     }
 
-    error = interface->set_pixel_sizes( face->size,
-                                        pixel_width,
-                                        pixel_height );
-    return error;
-  }
+    ft_recompute_scaled_metrics( face, metrics );
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_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;
-
-
-    if ( !face )
-      return FT_Err_Invalid_Face_Handle;
-
-    if ( !aslot )
-      return FT_Err_Invalid_Argument;
-
-    *aslot = 0;
-
-    driver = face->driver;
-    if ( !driver )
-      return FT_Err_Invalid_Driver_Handle;
-
-    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 ));
+    if (clazz->set_pixel_sizes)
+      error = clazz->set_pixel_sizes( face->size,
+                                      pixel_width,
+                                      pixel_height );
     return error;
   }
 
@@ -1900,166 +1921,6 @@
   /*************************************************************************/
   /*                                                                       */
   /* <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.                           */
-  /*                                                                       */
-  FT_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 face.        */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face        :: A handle to a 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.                             */
-  /*                                                                       */
-  FT_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 )
-      return FT_Err_Invalid_Face_Handle;
-
-    if ( !face->size )
-      return FT_Err_Invalid_Size_Handle;
-
-    if ( !face->glyph )
-      return FT_Err_Invalid_Slot_Handle;
-
-    if ( glyph_index >= face->num_glyphs )
-      return FT_Err_Invalid_Argument;
-
-    driver = face->driver;
-
-    /* when the flag NO_RECURSE is set, we disable hinting and scaling */
-    if ( load_flags & FT_LOAD_NO_RECURSE )
-      load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
-
-    error = driver->interface.load_glyph( face->glyph,
-                                          face->size,
-                                          glyph_index,
-                                          load_flags );
-
-    return error;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_Load_Char                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A function used to load a single character within a given face     */
-  /*    and the selected charmap (to be done with the FT_Select_Charmap()  */
-  /*    function).                                                         */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face       :: A handle to a target face object where the           */
-  /*                  character will be loaded.                            */
-  /*                                                                       */
-  /*    char_code  :: The character code 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.                             */
-  /*                                                                       */
-  FT_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 )
-      return FT_Err_Invalid_Face_Handle;
-
-    if ( !face->size )
-      return FT_Err_Invalid_Size_Handle;
-
-    if ( !face->glyph )
-      return FT_Err_Invalid_Slot_Handle;
-
-    if ( !face->charmap )
-      return FT_Err_Invalid_CharMap_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>                                                         */
@@ -2103,11 +1964,11 @@
       return FT_Err_Invalid_Argument;
 
     driver = face->driver;
-    memory = driver->memory;
+    memory = driver->root.memory;
 
-    if ( driver->interface.get_kerning )
+    if ( driver->clazz->get_kerning )
     {
-      error = driver->interface.get_kerning( face,
+      error = driver->clazz->get_kerning( face,
                                              left_glyph,
                                              right_glyph,
                                              kerning );
@@ -2247,7 +2108,7 @@
     if ( face && face->charmap )
     {
       driver = face->driver;
-      result = driver->interface.get_char_index( face->charmap, charcode );
+      result = driver->clazz->get_char_index( face->charmap, charcode );
     }
     return result;
   }
@@ -2291,8 +2152,8 @@
       goto Exit;
 
     driver = face->driver;
-    func = (FT_Get_Sfnt_Table_Func)driver->interface.get_interface(
-                                             driver, "get_sfnt" );
+    func = (FT_Get_Sfnt_Table_Func)driver->root.clazz->get_interface(
+                                             FT_MODULE(driver), "get_sfnt" );
     if ( func )
       table = func( face, tag );
 
@@ -2299,6 +2160,764 @@
   Exit:
     return table;
   }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                        R E N D E R E R S                        ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+ /* lookup a renderer by glyph format in the library's list */
+  static FT_Renderer  ft_lookup_renderer( FT_Library       library,
+                                          FT_Glyph_Format  format,
+                                          FT_ListNode     *node )
+  {
+    FT_ListNode   cur    = library->renderers.head;
+    FT_Renderer   result = 0;
+    
+    if (node)
+      *node = 0;
+      
+    while (cur)
+    {
+      FT_Renderer  renderer = FT_RENDERER(cur->data);
+      
+      if (renderer->glyph_format == format)
+      {
+        if (node)
+          *node = cur;
+        
+        result = renderer;
+        break;
+      }
+        
+    }
+    return result;
+  }
+
+  
+  static  FT_Renderer  ft_lookup_glyph_renderer( FT_GlyphSlot  slot )
+  {
+    FT_Face     face    = slot->face;
+    FT_Library  library = FT_FACE_LIBRARY(face);
+    FT_Renderer result  = library->cur_renderer;
+    
+    if (!result || result->glyph_format != slot->format)
+      result = ft_lookup_renderer( library, slot->format, 0 );
+    
+    return result;
+  }
+
+  
+  static  void  ft_set_current_renderer( FT_Library  library )
+  {
+    FT_Renderer  renderer;
+
+    renderer = ft_lookup_renderer( library, ft_glyph_format_outline, 0 );
+    library->cur_renderer = renderer;
+  }
+
+
+  static  FT_Error  ft_add_renderer( FT_Module  module )
+  {
+    FT_Library   library = module->library;
+    FT_Memory    memory  = library->memory;
+    FT_Error     error;
+    FT_ListNode  node;
+    
+    if (ALLOC(node,sizeof(*node)))
+      goto Exit;
+      
+    {
+      FT_Renderer         render = FT_RENDERER(module);
+      FT_Renderer_Class*  clazz  = (FT_Renderer_Class*)module->clazz;
+
+      render->clazz        = clazz;
+      render->glyph_format = clazz->glyph_format;
+      
+      /* allocate raster object if needed */
+      if ( clazz->glyph_format == ft_glyph_format_outline &&
+           clazz->raster_class->raster_new )
+      {
+        error = clazz->raster_class->raster_new( memory, &render->raster );
+        if (error) goto Fail;
+        
+        render->raster_render = clazz->raster_class->raster_render;
+        render->render        = clazz->render_glyph;
+      }           
+      
+      /* add to list */
+      node->data = module;
+      FT_List_Add( &library->renderers, node );
+
+      ft_set_current_renderer( library );
+    }
+
+  Fail:
+    if (error)
+      FREE(node);
+
+  Exit:
+    return error;
+  }                                 
+
+
+  static void  ft_remove_renderer( FT_Module  module )
+  {
+    FT_Library   library = module->library;
+    FT_Memory    memory  = library->memory;
+    FT_ListNode  node;
+
+    node = FT_List_Find( &library->renderers, module );
+    if (node)
+    {
+      FT_Renderer  render = FT_RENDERER(module);
+      
+      /* release raster object, if any */
+      if (render->raster)
+        render->clazz->raster_class->raster_done( render->raster );
+      
+      /* remove from list */
+      FT_List_Remove( &library->renderers, node );
+      FREE( node );
+      
+      ft_set_current_renderer( library );
+    }
+  }
+
+
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Get_Renderer
+  *
+  *  <Description>
+  *     retrieves the current renderer for a given glyph format.
+  *
+  *  <Input>
+  *     library  :: handle to library object
+  *     format   :: glyph format
+  *
+  *  <Return>
+  *     renderer handle. 0 if none found.
+  *
+  *  <Note>
+  *     An error will be returned if a module already exists by that
+  *     name, or if the module requires a version of freetype that is
+  *     too great
+  *
+  *     To add a new renderer, simply use FT_Add_Module. To retrieve
+  *     a renderer by its name, use FT_Get_Module
+  *
+  *************************************************************************/
+  
+  FT_EXPORT_FUNC(FT_Renderer)  FT_Get_Renderer( FT_Library      library,
+                                               FT_Glyph_Format  format )
+  {
+    return  ft_lookup_renderer( library, format, 0 );
+  }                                               
+
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Set_Renderer
+  *
+  *  <Description>
+  *     Sets the current renderer to use, and set additional mode
+  *
+  *  <Input>
+  *     library     :: handle to library object
+  *     renderer    :: handle to renderer object
+  *     num_params  :: number of additional parameters
+  *     params      :: additional parameters
+  *
+  *  <Return>
+  *     Error code. 0 means success.
+  *
+  *  <Note>
+  *     in case of success, the renderer will be used to convert glyph
+  *     images in the renderer's known format into bitmaps.
+  *
+  *     This doesn't change the current renderer for other formats..
+  *
+  *************************************************************************/
+  
+  FT_EXPORT_DEF(FT_Error) FT_Set_Renderer( FT_Library     library,
+                                           FT_Renderer    renderer,
+                                           FT_UInt        num_params,
+                                           FT_Parameter*  parameters )
+  {
+    FT_ListNode  node;
+    FT_Error     error = FT_Err_Ok;
+    
+    node = FT_List_Find( &library->renderers, renderer );
+    if (!node)
+    {
+      error = FT_Err_Invalid_Argument;
+      goto Exit;
+    }
+      
+    FT_List_Up( &library->renderers, node );
+    
+    if (renderer->glyph_format == ft_glyph_format_outline )
+      library->cur_renderer = renderer;
+      
+    if (num_params > 0)
+    {
+      FTRenderer_setMode  set_mode = renderer->clazz->set_mode;
+      
+      for ( ; num_params > 0; num_params-- )
+      {
+        error = set_mode( renderer, parameters->tag, parameters->data );
+        if (error)
+          break;
+      }
+    }
+    
+  Exit:
+    return error;
+  }                                           
+
+
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Render_Glyph
+  *
+  *  <Description>
+  *     Converts a given glyph image to a bitmap. It does so by inspecting
+  *     the glyph image format, find the relevant renderer, and invoke it
+  *
+  *  <Input>
+  *     slot        :: handle to the glyph slot containing the image to
+  *                    convert
+  *
+  *     render_mode :: a set of bit flags indicating which kind of bitmap
+  *                    to render. For now, only 'ft_render_mode_anti_alias'
+  *                    is supported by the available renderers, but others
+  *                    could appear later (e.g. LCD or TV optimised)
+  *
+  *  <Return>
+  *     Error code. 0 means success.
+  *
+  *  <Note>
+  *     in case of success, the renderer will be used to convert glyph
+  *     images in the renderer's known format into bitmaps.
+  *
+  *     This doesn't change the current renderer for other formats..
+  *
+  *     The slot's native image should be considered lost after the
+  *     conversion..
+  *
+  *************************************************************************/
+  
+  FT_EXPORT_FUNC(FT_Error)  FT_Render_Glyph( FT_GlyphSlot  slot,
+                                             FT_UInt       render_mode )
+  {
+    FT_Error     error = FT_Err_Ok;
+    FT_Renderer  renderer;
+      
+    if (slot)
+    {
+      FT_Face           face    = slot->face;
+      FT_Library        library = FT_FACE_LIBRARY(face);
+
+      /* if it's already a bitmap, no need to do anything */
+      switch (slot->format)
+      {
+        case ft_glyph_format_bitmap:   /* already a bitmap, don't do anything */
+          break;
+        
+        default:
+        {
+          /* small shortcut for the very common case */
+          if (slot->format == ft_glyph_format_outline)
+            renderer = library->cur_renderer;
+          else
+            renderer = ft_lookup_renderer( library, slot->format, 0 );
+            
+          error = FT_Err_Unimplemented_Feature;
+          if (renderer)
+            error = renderer->render( renderer, slot, render_mode );
+        }
+      }
+    }
+    else
+      error = FT_Err_Invalid_Argument;
+    
+    return error;
+  }
+  
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                         M O D U L E S                           ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Destroy_Module                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Destroys a given module object.  For drivers, this also destroys   */
+  /*    all child faces..                                                  */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*     module :: A handle to the target driver object.                   */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*     The driver _must_ be LOCKED!                                      */
+  /*                                                                       */
+  static
+  void  Destroy_Module( FT_Module  module )
+  {
+    FT_Memory         memory = module->memory;
+    FT_Module_Class*  clazz  = module->clazz;
+
+    /* finalize client-data - before anything else */
+    if ( module->generic.finalizer )
+      module->generic.finalizer( module );
+
+    /* if the module is a renderer */
+    if (FT_MODULE_IS_RENDERER(module))
+      ft_remove_renderer(module);
+
+    /* if the module is a font driver, add some steps */
+    if (FT_MODULE_IS_DRIVER(module))
+      Destroy_Driver( FT_DRIVER(module) );
+
+    /* finalize the module object */
+    if (clazz->module_done)
+      clazz->module_done(module);
+
+    /* discard it */
+    FREE( module );
+  }
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Add_Module
+  *
+  *  <Description>
+  *     Add a new module to a given library instance.
+  *
+  *  <Input>
+  *     library  :: handle to library object
+  *     clazz    :: pointer to class descriptor for the module
+  *
+  *  <Return>
+  *     Error code. 0 means success
+  *
+  *  <Note>
+  *     An error will be returned if a module already exists by that
+  *     name, or if the module requires a version of freetype that is
+  *     too great
+  *
+  *************************************************************************/
+
+  FT_EXPORT_FUNC(FT_Error) FT_Add_Module( FT_Library              library,
+                                          const FT_Module_Class*  clazz )
+  {
+    FT_Error   error;
+    FT_Memory  memory;
+    FT_Module  module;
+    FT_UInt    nn;
+
+    #define FREETYPE_VER_FIXED (((FT_Long)FREETYPE_MAJOR << 16) | FREETYPE_MINOR)
+
+    if (!library || !clazz)
+      return FT_Err_Invalid_Argument;
+
+    /* check freetype version */
+    if ( clazz->module_requires > FREETYPE_VER_FIXED )
+      return FT_Err_Invalid_Version;
+
+    /* look for a module with the same name in the library's table */
+    for ( nn = 0; nn < library->num_modules; nn++ )
+    {
+      module = library->modules[nn];
+      if ( strcmp( module->clazz->module_name, clazz->module_name ) == 0 )
+      {
+        /* this installed module has the same name, compare their versions */
+        if ( clazz->module_version <= module->clazz->module_version )
+          return FT_Err_Lower_Module_Version;
+
+        /* remove the module from our list, then exit the loop to replace */
+        /* it by our new version..                                        */
+        FT_Remove_Module( library, module );
+        break;
+      }
+    }
+
+    memory = library->memory;
+    error  = FT_Err_Ok;
+
+    if ( library->num_modules >= FT_MAX_MODULES )
+    {
+      error = FT_Err_Too_Many_Drivers;
+      goto Exit;
+    }
+
+    /* allocate module object */
+    if (ALLOC(module,clazz->module_size))
+      goto Exit;
+
+    /* base initialisation */
+    module->library = library;
+    module->memory  = memory;
+    module->clazz   = (FT_Module_Class*)clazz;
+
+    /* if the module is a renderer - this must be performed before */
+    /* the normal module initialisation..                          */
+    if (FT_MODULE_IS_RENDERER(module))
+    {
+      /* add to the renderers list */
+      error = ft_add_renderer(module);
+      if (error) goto Fail;
+    }
+
+    /* if the module is a font driver */
+    if (FT_MODULE_IS_DRIVER(module))
+    {
+      /* allocate glyph loader if needed */
+      FT_Driver   driver = FT_DRIVER(module);
+      
+      driver->clazz = (FT_Driver_Class*)module->clazz;
+      if (FT_DRIVER_USES_OUTLINES(driver))
+      {
+        error = FT_GlyphLoader_New( memory, &driver->glyph_loader );
+        if (error) goto Fail;
+      }
+    }
+
+    if (clazz->module_init)
+    {
+      error = clazz->module_init(module);
+      if (error) goto Fail;
+    }
+
+    /* add module to the library's table */
+    library->modules[ library->num_modules++ ] = module;
+      
+    
+  Exit:
+    return error;
+    
+  Fail:
+    if (FT_MODULE_IS_DRIVER(module))
+    {
+      FT_Driver  driver = FT_DRIVER(module);
+      
+      if (FT_DRIVER_USES_OUTLINES(driver))
+        FT_GlyphLoader_Done( driver->glyph_loader );
+    }
+    
+    if (FT_MODULE_IS_RENDERER(module))
+    {
+      FT_Renderer  renderer = FT_RENDERER(module);
+      if (renderer->raster)
+        renderer->clazz->raster_class->raster_done( renderer->raster );
+    }
+    FREE(module);
+    goto Exit;
+  }
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Get_Module
+  *
+  *  <Description>
+  *     Find a module by its name.
+  *
+  *  <Input>
+  *     library     :: handle to library object
+  *     module_name :: the module's ASCII name.
+  *
+  *  <Return>
+  *     Module handle, 0 if none was found.
+  *
+  *  <Note>
+  *     You'd better be familiar with FreeType internals to know which
+  *     module to look for :-)
+  *
+  *************************************************************************/
+
+  FT_EXPORT_FUNC(FT_Module) FT_Get_Module( FT_Library   library,
+                                           const char*  module_name )
+  {
+    FT_Module  result = 0;
+    FT_Module* cur    = library->modules;
+    FT_Module* limit  = cur + library->num_modules;
+
+    for ( ; cur < limit; cur++ )
+      if ( strcmp( cur[0]->clazz->module_name, module_name ) == 0 )
+      {
+        result = cur[0];
+        break;
+      }
+
+    return result;
+  }
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Get_Module_Interface
+  *
+  *  <Description>
+  *     Find a module and returns it's specific interface as a void*
+  *
+  *  <Input>
+  *     library     :: handle to library object
+  *     module_name :: the module's ASCII name.
+  *
+  *  <Return>
+  *     Module specific interface, if any
+  *
+  *  <Note>
+  *     You'd better be familiar with FreeType internals to know which
+  *     module to look for, and what it's interface is :-)
+  *
+  *************************************************************************/
+  
+  FT_EXPORT_FUNC(const void*)  FT_Get_Module_Interface( FT_Library   library,
+                                                        const char*  mod_name )
+  {
+    FT_Module  module;
+    
+    module = FT_Get_Module( library, mod_name );
+    return module ? module->clazz->module_interface : 0;
+  }                                                 
+
+
+ /*************************************************************************
+  *
+  *  <Function>
+  *     FT_Remove_Module
+  *
+  *  <Description>
+  *     Removes a given module from a library instance.
+  *
+  *  <Input>
+  *     library  :: handle to library object
+  *     module   :: handle to module object
+  *
+  *  <Return>
+  *     Error code (module not listed)
+  *
+  *  <Note>
+  *     The module object is destroyed by the function in case of success
+  *
+  *************************************************************************/
+
+  FT_EXPORT_FUNC(FT_Error)  FT_Remove_Module( FT_Library  library,
+                                              FT_Module   module )
+  {
+    /* try to find the module from the table, then remove it from there */
+    if (library && module)
+    {
+      FT_Module*  cur   = library->modules;
+      FT_Module*  limit = cur + library->num_modules;
+
+      for ( ; cur < limit; cur++ )
+      {
+        if (cur[0] == module)
+        {
+          /* remove it from the table */
+          library->num_modules--;
+          limit--;
+          while (cur < limit)
+          {
+            cur[0] = cur[1];
+            cur++;
+          }
+          limit[0] = 0;
+
+          /* destroy the module */
+          Destroy_Module(module);
+
+          return FT_Err_Ok;
+        }
+      }
+    }
+    return FT_Err_Invalid_Handle;
+  }
+
+
+
+
+
+
+
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****                         L I B R A R Y                           ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <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>                                                              */
+  /*    alibrary :: A pointer to handle of a new library object.           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  FT_EXPORT_FUNC( FT_Error )  FT_New_Library( FT_Memory    memory,
+                                              FT_Library*  alibrary )
+  {
+    FT_Library  library = 0;
+    FT_Error    error;
+
+
+    if ( !memory )
+      return FT_Err_Invalid_Argument;
+
+    /* first of all, allocate the library object */
+    if ( ALLOC( library, sizeof ( *library ) ) )
+      return error;
+
+    library->memory = memory;
+
+    /* allocate the render pool */
+    library->raster_pool_size = FT_RENDER_POOL_SIZE;
+    if ( ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
+      goto Fail;
+
+    /* That's ok now */
+    *alibrary = library;
+
+    return FT_Err_Ok;
+
+  Fail:
+    FREE( library );
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <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>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  FT_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 modules in the library */
+    for ( n = 0; n < library->num_modules; n++ )
+    {
+      FT_Module  module = library->modules[n];
+
+      if ( module )
+      {
+        Destroy_Module( module );
+        library->modules[n] = 0;
+      }
+    }
+
+    /* Destroy raster objects */
+    FREE( library->raster_pool );
+    library->raster_pool_size = 0;
+
+    FREE( library );
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Debug_Hook                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets a debug hook function for debugging the interpreter of a      */
+  /*    font format.                                                       */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    library    :: A handle to the library object.                      */
+  /*                                                                       */
+  /*    hook_index :: The index of the debug hook.  You should use the     */
+  /*                  values defined in ftobjs.h, e.g.                     */
+  /*                  FT_DEBUG_HOOK_TRUETYPE                               */
+  /*                                                                       */
+  /*    debug_hook :: The function used to debug the interpreter.          */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Currently, four debug hook slots are available, but only two (for  */
+  /*    the TrueType and the Type 1 interpreter) are defined.              */
+  /*                                                                       */
+  FT_EXPORT_FUNC( void )  FT_Set_Debug_Hook( FT_Library         library,
+                                             FT_UInt            hook_index,
+                                             FT_DebugHook_Func  debug_hook )
+  {
+    if ( library && debug_hook &&
+         hook_index <
+           ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )
+      library->debug_hooks[hook_index] = debug_hook;
+  }
+
+
+
 
 
   /*************************************************************************/
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -569,11 +569,12 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_Outline_Get_Bitmap                                              */
+  /*    FT_Outline_Render                                                  */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Renders an outline within a bitmap.  The outline's image is simply */
-  /*    OR-ed to the target bitmap.                                        */
+  /*    Renders an outline within a bitmap using the current scan-convert. */
+  /*    This functions uses a FT_Raster_Params as argument, allowing       */
+  /*    advanced features like direct composition/translucency, etc.       */
   /*                                                                       */
   /* <Input>                                                               */
   /*    library :: A handle to a FreeType library object.                  */
@@ -580,7 +581,8 @@
   /*                                                                       */
   /*    outline :: A pointer to the source outline descriptor.             */
   /*                                                                       */
-  /*    map     :: A pointer to the target bitmap descriptor.              */
+  /*    params  :: A pointer to a FT_Raster_Params used to describe        */
+  /*               the rendering operation.                                */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
@@ -590,41 +592,45 @@
   /*    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!                       */
+  /*    You should know what you're doing and the role of FT_Raster_Params */
+  /*    to use this function.                                              */
   /*                                                                       */
-  /*    It will use the raster correponding to the default glyph format.   */
+  /*    The field `params.source' will be set to `outline' before the scan */
+  /*    converter is called, which means that the value you give to it is  */
+  /*    actually ignored.                                                  */
   /*                                                                       */
-  FT_EXPORT_FUNC( FT_Error )  FT_Outline_Get_Bitmap( FT_Library   library,
-                                                     FT_Outline*  outline,
-                                                     FT_Bitmap*   bitmap )
+  FT_EXPORT_FUNC( FT_Error )  FT_Outline_Render( FT_Library         library,
+                                                 FT_Outline*        outline,
+                                                 FT_Raster_Params*  params )
   {
-    FT_Error          error;
-    FT_Raster         raster;
-    FT_Raster_Funcs   funcs;
-    FT_Raster_Params  params;
+    FT_Error           error;
+    FT_Renderer        renderer;
 
-
     if ( !library )
-      return FT_Err_Invalid_Library_Handle;
+    {
+      error = FT_Err_Invalid_Library_Handle;
+      goto Exit;
+    }
 
-    if ( !outline || !bitmap )
-      return FT_Err_Invalid_Argument;
+    if ( !outline || !params )
+    {
+      error = FT_Err_Invalid_Argument;
+      goto Exit;
+    }
 
-    error  = FT_Err_Invalid_Glyph_Format;
-    raster = FT_Get_Raster( library, ft_glyph_format_outline, &funcs );
-    if ( !raster )
+    /* retrieve the current outline renderer */
+    renderer = library->cur_renderer;
+    if (!renderer)
+    {
+      /* XXXX: should use another error code */
+      error = FT_Err_Invalid_Argument;
       goto Exit;
+    }
 
-    params.target = bitmap;
-    params.source = outline;
-    params.flags  = 0;
+    params->source = (void*)outline;
+    
+    error = renderer->raster_render( renderer->raster, params );
 
-    if ( bitmap->pixel_mode == ft_pixel_mode_grays )
-      params.flags |= ft_raster_flag_aa;
-
-    error = funcs.raster_render( raster, &params );
-
   Exit:
     return error;
   }
@@ -633,12 +639,11 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_Outline_Render                                                  */
+  /*    FT_Outline_Get_Bitmap                                              */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Renders an outline within a bitmap using the current scan-convert. */
-  /*    This functions uses a FT_Raster_Params as argument, allowing       */
-  /*    advanced features like direct composition/translucency, etc.       */
+  /*    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.                  */
@@ -645,8 +650,7 @@
   /*                                                                       */
   /*    outline :: A pointer to the source outline descriptor.             */
   /*                                                                       */
-  /*    params  :: A pointer to a FT_Raster_Params used to describe        */
-  /*               the rendering operation.                                */
+  /*    map     :: A pointer to the target bitmap descriptor.              */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
@@ -656,41 +660,72 @@
   /*    scan-line converter will be serialized.                            */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    You should know what you're doing and the role of FT_Raster_Params */
-  /*    to use this function.                                              */
+  /*    This function does NOT CREATE the bitmap, it only renders an       */
+  /*    outline image within the one you pass to it!                       */
   /*                                                                       */
-  /*    The field `params.source' will be set to `outline' before the scan */
-  /*    converter is called, which means that the value you give to it is  */
-  /*    actually ignored.                                                  */
+  /*    It will use the raster correponding to the default glyph format.   */
   /*                                                                       */
-  FT_EXPORT_FUNC( FT_Error )  FT_Outline_Render( FT_Library         library,
-                                                 FT_Outline*        outline,
-                                                 FT_Raster_Params*  params )
+  FT_EXPORT_FUNC( FT_Error )  FT_Outline_Get_Bitmap( FT_Library   library,
+                                                     FT_Outline*  outline,
+                                                     FT_Bitmap*   bitmap )
   {
-    FT_Error         error;
-    FT_Raster        raster;
-    FT_Raster_Funcs  funcs;
+    FT_Raster_Params  params;
 
+    if (!bitmap)
+      return FT_Err_Invalid_Argument;
 
-    if ( !library )
-      return FT_Err_Invalid_Library_Handle;
+    /* other checks are delayed to FT_Outline_Render */
 
-    if ( !outline || !params )
-      return FT_Err_Invalid_Argument;
+    params.target = bitmap;
+    params.flags  = 0;
 
-    error  = FT_Err_Invalid_Glyph_Format;
-    raster = FT_Get_Raster( library, ft_glyph_format_outline, &funcs );
-    if ( !raster )
-      goto Exit;
+    if ( bitmap->pixel_mode == ft_pixel_mode_grays )
+      params.flags |= ft_raster_flag_aa;
 
-    params->source = (void*)outline;
-    error = funcs.raster_render( raster, params );
+    return FT_Outline_Render( library, outline, &params );
+  }
 
-  Exit:
-    return error;
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Vector_Transform                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Transforms a single vector through a 2x2 matrix.                   */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    vector :: The target vector to transform.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    matrix :: A pointer to the source 2x2 matrix.                      */
+  /*                                                                       */
+  /* <MT-Note>                                                             */
+  /*    Yes.                                                               */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The result is undefined if either `vector' or `matrix' is invalid. */
+  /*                                                                       */
+  FT_EXPORT_FUNC( void )  FT_Vector_Transform( FT_Vector*  vector,
+                                               FT_Matrix*  matrix )
+  {
+    FT_Pos xz, yz;
+
+    xz = FT_MulFix( vector->x, matrix->xx ) +
+         FT_MulFix( vector->y, matrix->xy );
+
+    yz = FT_MulFix( vector->x, matrix->yx ) +
+         FT_MulFix( vector->y, matrix->yy );
+
+    vector->x = xz;
+    vector->y = yz;
   }
 
 
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -715,26 +750,11 @@
   BASE_FUNC( void )  FT_Outline_Transform( 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++;
-    }
+    FT_Vector*  vec = outline->points;
+    FT_Vector*  limit = vec + outline->n_points;
+    
+    for ( ; vec < limit; vec++ )
+      FT_Vector_Transform( vec, matrix );
   }
 
 
@@ -804,46 +824,6 @@
     target->flags |= is_owner;
 
     return FT_Err_Ok;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    FT_Vector_Transform                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Transforms a single vector through a 2x2 matrix.                   */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    vector :: The target vector to transform.                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    matrix :: A pointer to the source 2x2 matrix.                      */
-  /*                                                                       */
-  /* <MT-Note>                                                             */
-  /*    Yes.                                                               */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The result is undefined if either `vector' or `matrix' is invalid. */
-  /*                                                                       */
-  FT_EXPORT_FUNC( void )  FT_Vector_Transform( FT_Vector*  vector,
-                                               FT_Matrix*  matrix )
-  {
-    FT_Pos xz, yz;
-
-
-    if ( !vector || !matrix )
-      return;
-
-    xz = FT_MulFix( vector->x, matrix->xx ) +
-         FT_MulFix( vector->y, matrix->xy );
-
-    yz = FT_MulFix( vector->x, matrix->yx ) +
-         FT_MulFix( vector->y, matrix->yy );
-
-    vector->x = xz;
-    vector->y = yz;
   }
 
 
--- a/src/base/ftraster.c
+++ /dev/null
@@ -1,3262 +1,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftraster.c                                                             */
-/*                                                                         */
-/*    The FreeType glyph rasterizer (body).                                */
-/*                                                                         */
-/*  Copyright 1996-2000 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* This is a rewrite of the FreeType 1.x scan-line converter             */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#include <freetype/ftraster.h>
-#include <freetype/internal/ftcalc.h>      /* for FT_MulDiv() only */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* A simple technical note on how the raster works:                      */
-  /*                                                                       */
-  /*   Converting an outline into a bitmap is achieved in several steps:   */
-  /*                                                                       */
-  /*   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 whether it 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.  Additionally, 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                                   top         */
-  /*                                                                       */
-  /*   The top of the profile stack is kept in the `top' 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 `y-turns' 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 |                     */
-  /*      _ _ __________________|____________________|                     */
-  /*                                                                       */
-  /*                            ^                    ^                     */
-  /*                            |                    |                     */
-  /*                       maxBuff             sizeBuff = end of 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.                                    */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /**                                                                     **/
-  /**  CONFIGURATION MACROS                                               **/
-  /**                                                                     **/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /* define DEBUG_RASTER if you want to compile a debugging version */
-#define xxxDEBUG_RASTER
-
-  /* The default render pool size in bytes */
-#define RASTER_RENDER_POOL  8192
-
-  /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */
-  /* 5-levels anti-aliasing                                                */
-#ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS
-#define FT_RASTER_OPTION_ANTI_ALIASING
-#endif
-
-  /* The size of the two-lines intermediate bitmap used */
-  /* for anti-aliasing, in bytes.                       */
-#define RASTER_GRAY_LINES  2048
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /**                                                                     **/
-  /**  OTHER MACROS (do not change)                                       **/
-  /**                                                                     **/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
-  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
-  /* messages during execution.                                            */
-  /*                                                                       */
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_raster
-
-
-#ifdef _STANDALONE_
-
-
-  /* This macro is used to indicate that a function parameter is unused. */
-  /* Its purpose is simply to reduce compiler warnings.  Note also that  */
-  /* simply defining it as `(void)x' doesn't avoid warnings with certain */
-  /* ANSI compilers (e.g. LCC).                                          */
-#define UNUSED( x )  (x) = (x)
-
-  /* Disable the tracing mechanism for simplicity -- developers can      */
-  /* activate it easily by redefining these two macros.                  */
-#ifndef FT_ERROR
-#define FT_ERROR( x )  do ; while ( 0 )     /* nothing */
-#endif
-
-#ifndef FT_TRACE
-#define FT_TRACE( x )  do ; while ( 0 )     /* nothing */
-#endif
-
-
-#else /* _STANDALONE_ */
-
-
-#include <freetype/internal/ftobjs.h>
-#include <freetype/internal/ftdebug.h> /* for FT_TRACE() and FT_ERROR() */
-
-
-#endif /* _STANDALONE_ */
-
-
-#define Raster_Err_None               0
-#define Raster_Err_Not_Ini           -1
-#define Raster_Err_Overflow          -2
-#define Raster_Err_Neg_Height        -3
-#define Raster_Err_Invalid           -4
-#define Raster_Err_Gray_Unsupported  -5
-#define Raster_Err_Unsupported       -6
-
-  /* FMulDiv means `Fast MulDiv', it is used in case where `b' is       */
-  /* typically a small value and the result of a*b is known to fit into */
-  /* 32 bits.                                                           */
-#define FMulDiv( a, b, c )  ( (a) * (b) / (c) )
-
-  /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */
-  /* for clipping computations.  It simply uses the FT_MulDiv() function   */
-  /* defined in `ftcalc.h'.                                                */
-#define SMulDiv  FT_MulDiv
-
-  /* The rasterizer is a very general purpose component; please leave */
-  /* the following redefinitions there (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 SUCCESS
-#define SUCCESS  0
-#endif
-
-#ifndef FAILURE
-#define FAILURE  1
-#endif
-
-
-#define MaxBezier  32   /* The maximum number of stacked Bezier curves. */
-                        /* Setting this constant to more than 32 is a   */
-                        /* pure waste of space.                         */
-
-#define Pixel_Bits  6   /* fractional bits of *input* coordinates */
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /**                                                                     **/
-  /**  SIMPLE TYPE DECLARATIONS                                           **/
-  /**                                                                     **/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  typedef int             Int;
-  typedef unsigned int    UInt;
-  typedef short           Short;
-  typedef unsigned short  UShort, *PUShort;
-  typedef long            Long, *PLong;
-  typedef unsigned long   ULong;
-
-  typedef unsigned char   Byte, *PByte;
-  typedef char            Bool;
-
-  typedef struct  TPoint_
-  {
-    Long  x;
-    Long  y;
-
-  } TPoint;
-
-
-  typedef enum  TFlow_
-  {
-    Flow_None = 0,
-    Flow_Up   = 1,
-    Flow_Down = -1
-
-  } TFlow;
-
-
-  /* States of each line, arc, and profile */
-  typedef enum  TStates_
-  {
-    Unknown,
-    Ascending,
-    Descending,
-    Flat
-
-  } TStates;
-
-
-  typedef struct TProfile_  TProfile;
-  typedef TProfile*         PProfile;
-
-  struct  TProfile_
-  {
-    FT_F26Dot6  X;           /* current coordinate during sweep        */
-    PProfile    link;        /* link to next profile - various purpose */
-    PLong       offset;      /* start of profile's data in render pool */
-    Int         flow;        /* Profile orientation: Asc/Descending    */
-    Long        height;      /* profile's height in scanlines          */
-    Long        start;       /* profile's starting scanline            */
-
-    UShort      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;
-
-
-  /* Simple record used to implement a stack of bands, required */
-  /* by the sub-banding mechanism                               */
-  typedef struct  TBand_
-  {
-    Short  y_min;   /* band's minimum */
-    Short  y_max;   /* band's maximum */
-
-  } TBand;
-
-
-#define AlignProfileSize \
-          ( ( sizeof ( TProfile ) + sizeof ( long ) - 1 ) / sizeof ( long ) )
-
-
-#ifdef TT_STATIC_RASTER
-
-#define RAS_ARGS       /* void */
-#define RAS_ARG        /* void */
-
-#define RAS_VARS       /* void */
-#define RAS_VAR        /* void */
-
-#define UNUSED_RASTER  do ; while ( 0 )
-
-#else /* TT_STATIC_RASTER */
-
-#define RAS_ARGS       TRaster_Instance*  raster,
-#define RAS_ARG        TRaster_Instance*  raster
-
-#define RAS_VARS       raster,
-#define RAS_VAR        raster
-
-#define UNUSED_RASTER  UNUSED( raster )
-
-#endif /* TT_STATIC_RASTER */
-
-
-  typedef struct TRaster_Instance_  TRaster_Instance;
-
-
-  /* prototypes used for sweep function dispatch */
-  typedef void  Function_Sweep_Init( RAS_ARGS Short*  min,
-                                              Short*  max );
-
-  typedef void  Function_Sweep_Span( RAS_ARGS Short       y,
-                                              FT_F26Dot6  x1,
-                                              FT_F26Dot6  x2,
-                                              PProfile    left,
-                                              PProfile    right );
-
-  typedef void  Function_Sweep_Step( RAS_ARG );
-
-
-  /* NOTE: These operations are only valid on 2's complement processors */
-
-#define FLOOR( x )    ( (x) & -ras.precision )
-#define CEILING( x )  ( ( (x) + ras.precision - 1 ) & -ras.precision )
-#define TRUNC( x )    ( (signed long)(x) >> ras.precision_bits )
-#define FRAC( x )     ( (x) & ( ras.precision - 1 ) )
-#define SCALED( x )   ( ( (x) << ras.scale_shift ) - ras.precision_half )
-
-  /* Note that I have moved the location of some fields in the */
-  /* structure to ensure that the most used variables are used */
-  /* at the top.  Thus, their offset can be coded with less    */
-  /* opcodes, and it results in a smaller executable.          */
-
-  struct  TRaster_Instance_
-  {
-    Int       precision_bits;       /* precision related variables         */
-    Int       precision;
-    Int       precision_half;
-    Long      precision_mask;
-    Int       precision_shift;
-    Int       precision_step;
-    Int       precision_jitter;
-
-    Int       scale_shift;          /* == precision_shift   for bitmaps    */
-                                    /* == precision_shift+1 for pixmaps    */
-
-    PLong     buff;                 /* The profiles buffer                 */
-    PLong     sizeBuff;             /* Render pool size                    */
-    PLong     maxBuff;              /* Profiles buffer size                */
-    PLong     top;                  /* Current cursor in buffer            */
-
-    FT_Error  error;
-
-    Int       numTurns;             /* number of Y-turns in outline        */
-
-    TPoint*   arc;                  /* current Bezier arc pointer          */
-
-    UShort    bWidth;               /* target bitmap width                 */
-    PByte     bTarget;              /* target bitmap buffer                */
-    PByte     gTarget;              /* target pixmap buffer                */
-
-    Long      lastX, lastY, minY, maxY;
-
-    UShort    num_Profs;            /* current number of profiles          */
-
-    Bool      fresh;                /* signals a fresh new profile which   */
-                                    /* 'start' field must be completed     */
-    Bool      joint;                /* signals that the last arc ended     */
-                                    /* exactly on a scanline.  Allows      */
-                                    /* removal of doublets                 */
-    PProfile  cProfile;             /* current profile                     */
-    PProfile  fProfile;             /* head of linked list of profiles     */
-    PProfile  gProfile;             /* contour's first profile in case     */
-                                    /* of impact                           */
-    TStates   state;                /* rendering state                     */
-
-    FT_Bitmap   target;             /* description of target bit/pixmap    */
-    FT_Outline  outline;
-
-    Long      traceOfs;             /* current offset in target bitmap     */
-    Long      traceG;               /* current offset in target pixmap     */
-
-    Short     traceIncr;            /* sweep's increment in target bitmap  */
-
-    Short     gray_min_x;           /* current min x during gray rendering */
-    Short     gray_max_x;           /* current max x during gray rendering */
-
-    /* dispatch variables */
-
-    Function_Sweep_Init*  Proc_Sweep_Init;
-    Function_Sweep_Span*  Proc_Sweep_Span;
-    Function_Sweep_Span*  Proc_Sweep_Drop;
-    Function_Sweep_Step*  Proc_Sweep_Step;
-
-    Byte      dropOutControl;       /* current drop_out control method     */
-
-    Bool      second_pass;          /* indicates wether 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.                          */
-    TPoint    arcs[2 * MaxBezier + 1]; /* The Bezier stack                 */
-
-    TBand     band_stack[16];       /* band stack used for sub-banding     */
-    Int       band_top;             /* band stack top                      */
-
-    Int       count_table[256];     /* Look-up table used to quickly count */
-                                    /* set bits in a gray 2x2 cell         */
-
-    void*     memory;
-
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-
-    Byte      grays[5];             /* Palette of gray levels used for     */
-                                    /* render.                             */
-
-    Byte      gray_lines[RASTER_GRAY_LINES];
-                                /* Intermediate table used to render the   */
-                                /* graylevels pixmaps.                     */
-                                /* gray_lines is a buffer holding two      */
-                                /* monochrome scanlines                    */
-    Short     gray_width;       /* width in bytes of one monochrome        */
-                                /* intermediate scanline of gray_lines.    */
-                                /* Each gray pixel takes 2 bits long there */
-
-                       /* The gray_lines must hold 2 lines, thus with size */
-                       /* in bytes of at least `gray_width*2'.             */
-
-#endif /* FT_RASTER_ANTI_ALIASING */
-
-#if 0
-    PByte       flags;              /* current flags table                 */
-    PUShort     outs;               /* current outlines table              */
-    FT_Vector*  coords;
-
-    UShort      nPoints;            /* number of points in current glyph   */
-    Short       nContours;          /* number of contours in current glyph */
-#endif
-
-  };
-
-
-#ifdef FT_CONFIG_OPTION_STATIC_RASTER
-
-  static TRaster_Instance  cur_ras;
-#define ras  cur_ras
-
-#else
-
-#define ras  (*raster)
-
-#endif /* FT_CONFIG_OPTION_STATIC_RASTER */
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /**                                                                     **/
-  /**  PROFILES COMPUTATION                                               **/
-  /**                                                                     **/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Set_High_Precision                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets precision variables according to param flag.                  */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    High :: Set to True for high precision (typically for ppem < 18),  */
-  /*            false otherwise.                                           */
-  /*                                                                       */
-  static
-  void  Set_High_Precision( RAS_ARGS Int  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;
-    }
-
-    FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" ));
-
-    ras.precision       = 1L << ras.precision_bits;
-    ras.precision_half  = ras.precision / 2;
-    ras.precision_shift = ras.precision_bits - Pixel_Bits;
-    ras.precision_mask  = -ras.precision;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    New_Profile                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Creates a new profile in the render pool.                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    aState :: The state/orientation of the new profile.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*   SUCCESS on success.  FAILURE in case of overflow or of incoherent   */
-  /*   profile.                                                            */
-  /*                                                                       */
-  static
-  Bool  New_Profile( RAS_ARGS TStates  aState )
-  {
-    if ( !ras.fProfile )
-    {
-      ras.cProfile  = (PProfile)ras.top;
-      ras.fProfile  = ras.cProfile;
-      ras.top      += AlignProfileSize;
-    }
-
-    if ( ras.top >= ras.maxBuff )
-    {
-      ras.error = Raster_Err_Overflow;
-      return FAILURE;
-    }
-
-    switch ( aState )
-    {
-    case Ascending:
-      ras.cProfile->flow = Flow_Up;
-      FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile ));
-      break;
-
-    case Descending:
-      ras.cProfile->flow = Flow_Down;
-      FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile ));
-      break;
-
-    default:
-      FT_ERROR(( "New_Profile: invalid profile direction!\n" ));
-      ras.error = Raster_Err_Invalid;
-      return FAILURE;
-    }
-
-    ras.cProfile->start  = 0;
-    ras.cProfile->height = 0;
-    ras.cProfile->offset = ras.top;
-    ras.cProfile->link   = (PProfile)0;
-    ras.cProfile->next   = (PProfile)0;
-
-    if ( !ras.gProfile )
-      ras.gProfile = ras.cProfile;
-
-    ras.state = aState;
-    ras.fresh = TRUE;
-    ras.joint = FALSE;
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    End_Profile                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Finalizes the current profile.                                     */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS on success.  FAILURE in case of overflow or incoherency.   */
-  /*                                                                       */
-  static
-  Bool  End_Profile( RAS_ARG )
-  {
-    Long      h;
-    PProfile  oldProfile;
-
-
-    h = ras.top - ras.cProfile->offset;
-
-    if ( h < 0 )
-    {
-      FT_ERROR(( "End_Profile: negative height encountered!\n" ));
-      ras.error = Raster_Err_Neg_Height;
-      return FAILURE;
-    }
-
-    if ( h > 0 )
-    {
-      FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n",
-                  (long)ras.cProfile, ras.cProfile->start, h ));
-
-      oldProfile           = ras.cProfile;
-      ras.cProfile->height = h;
-      ras.cProfile         = (PProfile)ras.top;
-
-      ras.top             += AlignProfileSize;
-
-      ras.cProfile->height = 0;
-      ras.cProfile->offset = ras.top;
-      oldProfile->next     = ras.cProfile;
-      ras.num_Profs++;
-    }
-
-    if ( ras.top >= ras.maxBuff )
-    {
-      FT_TRACE1(( "overflow in End_Profile\n" ));
-      ras.error = Raster_Err_Overflow;
-      return FAILURE;
-    }
-
-    ras.joint = FALSE;
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Insert_Y_Turn                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Inserts a salient into the sorted list placed on top of the render */
-  /*    pool.                                                              */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    New y scanline position.                                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS on success.  FAILURE in case of overflow.                  */
-  /*                                                                       */
-  static
-  Bool  Insert_Y_Turn( RAS_ARGS Int  y )
-  {
-    PLong     y_turns;
-    Int       y2, n;
-
-
-    n       = ras.numTurns - 1;
-    y_turns = ras.sizeBuff - ras.numTurns;
-
-    /* look for first y value that is <= */
-    while ( n >= 0 && y < y_turns[n] )
-      n--;
-
-    /* if it is <, simply insert it, ignore if == */
-    if ( n >= 0 && y > y_turns[n] )
-      while ( n >= 0 )
-      {
-        y2 = y_turns[n];
-        y_turns[n] = y;
-        y = y2;
-        n--;
-      }
-
-    if ( n < 0 )
-    {
-      if ( ras.maxBuff <= ras.top )
-      {
-        ras.error = Raster_Err_Overflow;
-        return FAILURE;
-      }
-      ras.maxBuff--;
-      ras.numTurns++;
-      ras.sizeBuff[-ras.numTurns] = y;
-    }
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Finalize_Profile_Table                                             */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Adjusts all links in the profiles list.                            */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS on success.  FAILURE in case of overflow.                  */
-  /*                                                                       */
-  static
-  Bool  Finalize_Profile_Table( RAS_ARG )
-  {
-    Int       bottom, top;
-    UShort    n;
-    PProfile  p;
-
-
-    n = ras.num_Profs;
-
-    if ( n > 1 )
-    {
-      p = ras.fProfile;
-      while ( n > 0 )
-      {
-        if ( n > 1 )
-          p->link = (PProfile)( p->offset + p->height );
-        else
-          p->link = NULL;
-
-        switch ( p->flow )
-        {
-        case Flow_Down:
-          bottom     = p->start - p->height+1;
-          top        = p->start;
-          p->start   = bottom;
-          p->offset += p->height - 1;
-          break;
-
-        case Flow_Up:
-        default:
-          bottom = p->start;
-          top    = p->start + p->height - 1;
-        }
-
-        if ( Insert_Y_Turn( RAS_VARS bottom )   ||
-             Insert_Y_Turn( RAS_VARS top + 1 )  )
-          return FAILURE;
-
-        p = p->link;
-        n--;
-      }
-    }
-    else
-      ras.fProfile = NULL;
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Split_Conic                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Subdivides one conic Bezier into two joint sub-arcs in the Bezier  */
-  /*    stack.                                                             */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    None (subdivided Bezier is taken from the top of the stack).       */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This routine is the `beef' of this component.  It is  _the_ inner  */
-  /*    loop that should be optimized to hell to get the best performance. */
-  /*                                                                       */
-  static
-  void  Split_Conic( TPoint*  base )
-  {
-    Long     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;
-
-    /* hand optimized.  gcc doesn't seem too good at common expression */
-    /* substitution and instruction scheduling ;-)                     */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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 )
-  {
-    Long  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 + 1 ) >> 1;
-    base[5].x = b = ( base[3].x + d + 1 ) >> 1;
-    c = ( c + d + 1 ) >> 1;
-    base[2].x = a = ( a + c + 1 ) >> 1;
-    base[4].x = b = ( b + c + 1 ) >> 1;
-    base[3].x = ( a + b + 1 ) >> 1;
-
-    base[6].y = base[3].y;
-    c = base[1].y;
-    d = base[2].y;
-    base[1].y = a = ( base[0].y + c + 1 ) >> 1;
-    base[5].y = b = ( base[3].y + d + 1 ) >> 1;
-    c = ( c + d + 1 ) >> 1;
-    base[2].y = a = ( a + c + 1 ) >> 1;
-    base[4].y = b = ( b + c + 1 ) >> 1;
-    base[3].y = ( a + b + 1 ) >> 1;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Line_Up                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the x-coordinates of an ascending line segment and stores */
-  /*    them in the render pool.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    x1   :: The x-coordinate of the segment's start point.             */
-  /*                                                                       */
-  /*    y1   :: The y-coordinate of the segment's start point.             */
-  /*                                                                       */
-  /*    x2   :: The x-coordinate of the segment's end point.               */
-  /*                                                                       */
-  /*    y2   :: The y-coordinate of the segment's end point.               */
-  /*                                                                       */
-  /*    miny :: A lower vertical clipping bound value.                     */
-  /*                                                                       */
-  /*    maxy :: An upper vertical clipping bound value.                    */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS on success, FAILURE on render pool overflow.               */
-  /*                                                                       */
-  static
-  Bool  Line_Up( RAS_ARGS Long  x1, Long  y1,
-                          Long  x2, Long  y2,
-                          Long  miny, Long  maxy )
-  {
-    Long   Dx, Dy;
-    Int    e1, e2, f1, f2, size;     /* XXX: is `Short' sufficient? */
-    Long   Ix, Rx, Ax;
-
-    PLong  top;
-
-
-    Dx = x2 - x1;
-    Dy = y2 - y1;
-
-    if ( Dy <= 0 || y2 < miny || y1 > maxy )
-      return SUCCESS;
-
-    if ( y1 < miny )
-    {
-      /* Take care: miny-y1 can be a very large value; we use     */
-      /*            a slow MulDiv function to avoid clipping bugs */
-      x1 += SMulDiv( Dx, miny - y1, Dy );
-      e1  = TRUNC( miny );
-      f1  = 0;
-    }
-    else
-    {
-      e1 = TRUNC( y1 );
-      f1 = FRAC( y1 );
-    }
-
-    if ( y2 > maxy )
-    {
-      /* x2 += FMulDiv( Dx, maxy - y2, Dy );  UNNECESSARY */
-      e2  = TRUNC( maxy );
-      f2  = 0;
-    }
-    else
-    {
-      e2 = TRUNC( y2 );
-      f2 = FRAC( y2 );
-    }
-
-    if ( f1 > 0 )
-    {
-      if ( e1 == e2 )
-        return SUCCESS;
-      else
-      {
-        x1 += FMulDiv( Dx, ras.precision - f1, Dy );
-        e1 += 1;
-      }
-    }
-    else
-      if ( ras.joint )
-      {
-        ras.top--;
-        ras.joint = FALSE;
-      }
-
-    ras.joint = ( f2 == 0 );
-
-    if ( ras.fresh )
-    {
-      ras.cProfile->start = e1;
-      ras.fresh           = FALSE;
-    }
-
-    size = e2 - e1 + 1;
-    if ( ras.top + size >= ras.maxBuff )
-    {
-      ras.error = Raster_Err_Overflow;
-      return FAILURE;
-    }
-
-    if ( Dx > 0 )
-    {
-      Ix = ( ras.precision * Dx ) / Dy;
-      Rx = ( ras.precision * Dx ) % Dy;
-      Dx = 1;
-    }
-    else
-    {
-      Ix = -( ( ras.precision * -Dx ) / Dy );
-      Rx =    ( ras.precision * -Dx ) % Dy;
-      Dx = -1;
-    }
-
-    Ax  = -Dy;
-    top = ras.top;
-
-    while ( size > 0 )
-    {
-      *top++ = x1;
-
-      x1 += Ix;
-      Ax += Rx;
-      if ( Ax >= 0 )
-      {
-        Ax -= Dy;
-        x1 += Dx;
-      }
-      size--;
-    }
-
-    ras.top = top;
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Line_Down                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the x-coordinates of an descending line segment and       */
-  /*    stores them in the render pool.                                    */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    x1   :: The x-coordinate of the segment's start point.             */
-  /*                                                                       */
-  /*    y1   :: The y-coordinate of the segment's start point.             */
-  /*                                                                       */
-  /*    x2   :: The x-coordinate of the segment's end point.               */
-  /*                                                                       */
-  /*    y2   :: The y-coordinate of the segment's end point.               */
-  /*                                                                       */
-  /*    miny :: A lower vertical clipping bound value.                     */
-  /*                                                                       */
-  /*    maxy :: An upper vertical clipping bound value.                    */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS on success, FAILURE on render pool overflow.               */
-  /*                                                                       */
-  static
-  Bool  Line_Down( RAS_ARGS Long  x1, Long  y1,
-                            Long  x2, Long  y2,
-                            Long  miny, Long  maxy )
-  {
-    Bool  result, fresh;
-
-
-    fresh  = ras.fresh;
-
-    result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny );
-
-    if ( fresh && !ras.fresh )
-      ras.cProfile->start = -ras.cProfile->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 x-coordinates of an ascending Bezier arc and stores   */
-  /*    them in the render pool.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    degree   :: The degree of the Bezier arc (either 2 or 3).          */
-  /*                                                                       */
-  /*    splitter :: The function to split Bezier arcs.                     */
-  /*                                                                       */
-  /*    miny     :: A lower vertical clipping bound value.                 */
-  /*                                                                       */
-  /*    maxy     :: An upper vertical clipping bound value.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS on success, FAILURE on render pool overflow.               */
-  /*                                                                       */
-  static
-  Bool  Bezier_Up( RAS_ARGS Int        degree,
-                            TSplitter  splitter,
-                            Long       miny,
-                            Long       maxy )
-  {
-    Long   y1, y2, e, e2, e0;
-    Short  f1;
-
-    TPoint*  arc;
-    TPoint*  start_arc;
-
-    PLong top;
-
-
-    arc = ras.arc;
-    y1  = arc[degree].y;
-    y2  = arc[0].y;
-    top = ras.top;
-
-    if ( y2 < miny || y1 > maxy )
-      goto Fin;
-
-    e2 = FLOOR( y2 );
-
-    if ( e2 > maxy )
-      e2 = maxy;
-
-    e0 = miny;
-
-    if ( y1 < miny )
-      e = miny;
-    else
-    {
-      e  = CEILING( y1 );
-      f1 = FRAC( y1 );
-      e0 = e;
-
-      if ( f1 == 0 )
-      {
-        if ( ras.joint )
-        {
-          top--;
-          ras.joint = FALSE;
-        }
-
-        *top++ = arc[degree].x;
-
-        e += ras.precision;
-      }
-    }
-
-    if ( ras.fresh )
-    {
-      ras.cProfile->start = TRUNC( e0 );
-      ras.fresh = FALSE;
-    }
-
-    if ( e2 < e )
-      goto Fin;
-
-    if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
-    {
-      ras.top   = top;
-      ras.error = Raster_Err_Overflow;
-      return FAILURE;
-    }
-
-    start_arc = arc;
-
-    while ( arc >= start_arc && e <= e2 )
-    {
-      ras.joint = FALSE;
-
-      y2 = arc[0].y;
-
-      if ( y2 > e )
-      {
-        y1 = arc[degree].y;
-        if ( y2 - y1 >= ras.precision_step )
-        {
-          splitter( arc );
-          arc += degree;
-        }
-        else
-        {
-          *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x,
-                                            e - y1, y2 - y1 );
-          arc -= degree;
-          e   += ras.precision;
-        }
-      }
-      else
-      {
-        if ( y2 == e )
-        {
-          ras.joint  = TRUE;
-          *top++     = arc[0].x;
-
-          e += ras.precision;
-        }
-        arc -= degree;
-      }
-    }
-
-  Fin:
-    ras.top  = top;
-    ras.arc -= degree;
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Bezier_Down                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the x-coordinates of an descending Bezier arc and stores  */
-  /*    them in the render pool.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    degree   :: The degree of the Bezier arc (either 2 or 3).          */
-  /*                                                                       */
-  /*    splitter :: The function to split Bezier arcs.                     */
-  /*                                                                       */
-  /*    miny     :: A lower vertical clipping bound value.                 */
-  /*                                                                       */
-  /*    maxy     :: An upper vertical clipping bound value.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS on success, FAILURE on render pool overflow.               */
-  /*                                                                       */
-  static
-  Bool  Bezier_Down( RAS_ARGS Int        degree,
-                              TSplitter  splitter,
-                              Long       miny,
-                              Long       maxy )
-  {
-    TPoint*  arc = ras.arc;
-    Bool     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_VARS degree, splitter, -maxy, -miny );
-
-    if ( fresh && !ras.fresh )
-      ras.cProfile->start = -ras.cProfile->start;
-
-    arc[0].y = -arc[0].y;
-    return result;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Line_To                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Injects a new line segment and adjusts Profiles list.              */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*   x :: The x-coordinate of the segment's end point (its start point   */
-  /*        is stored in `LastX').                                         */
-  /*                                                                       */
-  /*   y :: The y-coordinate of the segment's end point (its start point   */
-  /*        is stored in `LastY').                                         */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */
-  /*   profile.                                                            */
-  /*                                                                       */
-  static
-  Bool  Line_To( RAS_ARGS Long  x,
-                          Long  y )
-  {
-    /* First, detect a change of direction */
-
-    switch ( ras.state )
-    {
-    case Unknown:
-      if ( y > ras.lastY )
-      {
-        if ( New_Profile( RAS_VARS Ascending ) )
-          return FAILURE;
-      }
-      else
-      {
-        if ( y < ras.lastY )
-          if ( New_Profile( RAS_VARS Descending ) )
-            return FAILURE;
-      }
-      break;
-
-    case Ascending:
-      if ( y < ras.lastY )
-      {
-        if ( End_Profile( RAS_VAR )             ||
-             New_Profile( RAS_VARS Descending ) )
-          return FAILURE;
-      }
-      break;
-
-    case Descending:
-      if ( y > ras.lastY )
-      {
-        if ( End_Profile( RAS_VAR )            ||
-             New_Profile( RAS_VARS Ascending ) )
-          return FAILURE;
-      }
-      break;
-
-    default:
-      ;
-    }
-
-    /* Then compute the lines */
-
-    switch ( ras.state )
-    {
-    case Ascending:
-      if ( Line_Up ( RAS_VARS ras.lastX, ras.lastY,
-                     x, y, ras.minY, ras.maxY ) )
-        return FAILURE;
-      break;
-
-    case Descending:
-      if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,
-                      x, y, ras.minY, ras.maxY ) )
-        return FAILURE;
-      break;
-
-    default:
-      ;
-    }
-
-    ras.lastX = x;
-    ras.lastY = y;
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Conic_To                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Injects a new conic arc and adjusts the profile list.              */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*   cx :: The x-coordinate of the arc's new control point.              */
-  /*                                                                       */
-  /*   cy :: The y-coordinate of the arc's new control point.              */
-  /*                                                                       */
-  /*   x  :: The x-coordinate of the arc's end point (its start point is   */
-  /*         stored in `LastX').                                           */
-  /*                                                                       */
-  /*   y  :: The y-coordinate of the arc's end point (its start point is   */
-  /*         stored in `LastY').                                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */
-  /*   profile.                                                            */
-  /*                                                                       */
-  static
-  Bool  Conic_To( RAS_ARGS Long  cx,
-                           Long  cy,
-                           Long  x,
-                           Long  y )
-  {
-    Long     y1, y2, y3, x3, ymin, ymax;
-    TStates  state_bez;
-
-
-    ras.arc      = ras.arcs;
-    ras.arc[2].x = ras.lastX;
-    ras.arc[2].y = ras.lastY;
-    ras.arc[1].x = cx; ras.arc[1].y = cy;
-    ras.arc[0].x = x;  ras.arc[0].y = y;
-
-    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_VARS state_bez ) )
-            goto Fail;
-        }
-
-        /* now call the appropriate routine */
-        if ( state_bez == Ascending )
-        {
-          if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
-            goto Fail;
-        }
-        else
-          if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
-            goto Fail;
-      }
-
-    } while ( ras.arc >= ras.arcs );
-
-    ras.lastX = x3;
-    ras.lastY = y3;
-
-    return SUCCESS;
-
-  Fail:
-    return FAILURE;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Cubic_To                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Injects a new cubic arc and adjusts the profile list.              */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*   cx1 :: The x-coordinate of the arc's first new control point.       */
-  /*                                                                       */
-  /*   cy1 :: The y-coordinate of the arc's first new control point.       */
-  /*                                                                       */
-  /*   cx2 :: The x-coordinate of the arc's second new control point.      */
-  /*                                                                       */
-  /*   cy2 :: The y-coordinate of the arc's second new control point.      */
-  /*                                                                       */
-  /*   x   :: The x-coordinate of the arc's end point (its start point is  */
-  /*          stored in `LastX').                                          */
-  /*                                                                       */
-  /*   y   :: The y-coordinate of the arc's end point (its start point is  */
-  /*          stored in `LastY').                                          */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */
-  /*   profile.                                                            */
-  /*                                                                       */
-  static
-  Bool  Cubic_To( RAS_ARGS Long  cx1,
-                           Long  cy1,
-                           Long  cx2,
-                           Long  cy2,
-                           Long  x,
-                           Long  y )
-  {
-    Long     y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
-    TStates  state_bez;
-
-
-    ras.arc      = ras.arcs;
-    ras.arc[3].x = ras.lastX;
-    ras.arc[3].y = ras.lastY;
-    ras.arc[2].x = cx1; ras.arc[2].y = cy1;
-    ras.arc[1].x = cx2; ras.arc[1].y = cy2;
-    ras.arc[0].x = x;   ras.arc[0].y = y;
-
-    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_VARS state_bez ) )
-            goto Fail;
-        }
-
-        /* compute intersections */
-        if ( state_bez == Ascending )
-        {
-          if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
-            goto Fail;
-        }
-        else
-          if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
-            goto Fail;
-      }
-
-    } while ( ras.arc >= ras.arcs );
-
-    ras.lastX = x4;
-    ras.lastY = y4;
-
-    return SUCCESS;
-
-  Fail:
-    return FAILURE;
-  }
-
-
-#undef  SWAP_
-#define SWAP_( x, y )  do                \
-                       {                 \
-                         Long  swap = x; \
-                                         \
-                                         \
-                         x = y;          \
-                         y = swap;       \
-                       } while ( 0 )
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Decompose_Curve                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Scans the outline arays in order to emit individual segments and   */
-  /*    Beziers by calling Line_To() and Bezier_To().  It handles all      */
-  /*    weird cases, like when the first point is off the curve, or when   */
-  /*    there are simply no `on' points in the contour!                    */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    first   :: The index of the first point in the contour.            */
-  /*                                                                       */
-  /*    last    :: The index of the last point in the contour.             */
-  /*                                                                       */
-  /*    flipped :: If set, flip the direction of the curve.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS on success, FAILURE on error.                              */
-  /*                                                                       */
-  static
-  Bool  Decompose_Curve( RAS_ARGS UShort  first,
-                                  UShort  last,
-                                  int     flipped )
-  {
-    FT_Vector   v_last;
-    FT_Vector   v_control;
-    FT_Vector   v_start;
-
-    FT_Vector*  points;
-    FT_Vector*  point;
-    FT_Vector*  limit;
-    char*       tags;
-
-    char        tag;       /* current point's state           */
-
-
-    points = ras.outline.points;
-    limit  = points + last;
-
-    v_start.x = SCALED( points[first].x );
-    v_start.y = SCALED( points[first].y );
-    v_last.x  = SCALED( points[last].x );
-    v_last.y  = SCALED( points[last].y );
-
-    if ( flipped )
-    {
-      SWAP_( v_start.x, v_start.y );
-      SWAP_( v_last.x, v_last.y );
-    }
-
-    v_control = v_start;
-
-    point = points + first;
-    tags  = ras.outline.tags  + first;
-    tag   = FT_CURVE_TAG( tags[0] );
-
-    /* A contour cannot start with a cubic control point! */
-    if ( tag == FT_Curve_Tag_Cubic )
-      goto 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( ras.outline.tags[last] ) == FT_Curve_Tag_On )
-      {
-        /* start at last point if it is on the curve */
-        v_start = v_last;
-        limit--;
-      }
-      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;
-      }
-      point--;
-      tags--;
-    }
-
-    ras.lastX = v_start.x;
-    ras.lastY = v_start.y;
-
-    while ( point < limit )
-    {
-      point++;
-      tags++;
-
-      tag = FT_CURVE_TAG( tags[0] );
-
-      switch ( tag )
-      {
-      case FT_Curve_Tag_On:  /* emit a single line_to */
-        {
-          Long  x, y;
-
-
-          x = SCALED( point->x );
-          y = SCALED( point->y );
-          if ( flipped )
-            SWAP_( x, y );
-
-          if ( Line_To( RAS_VARS x, y ) )
-            goto Fail;
-          continue;
-        }
-
-      case FT_Curve_Tag_Conic:  /* consume conic arcs */
-        {
-          v_control.x = SCALED( point[0].x );
-          v_control.y = SCALED( point[0].y );
-
-          if ( flipped )
-            SWAP_( v_control.x, v_control.y );
-
-        Do_Conic:
-          if ( point < limit )
-          {
-            FT_Vector  v_middle;
-            Long       x, y;
-
-
-            point++;
-            tags++;
-            tag = FT_CURVE_TAG( tags[0] );
-
-            x = SCALED( point[0].x );
-            y = SCALED( point[0].y );
-
-            if ( flipped )
-              SWAP_( x, y );
-
-            if ( tag == FT_Curve_Tag_On )
-            {
-              if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) )
-                goto Fail;
-              continue;
-            }
-
-            if ( tag != FT_Curve_Tag_Conic )
-              goto Invalid_Outline;
-
-            v_middle.x = ( v_control.x + x ) / 2;
-            v_middle.y = ( v_control.y + y ) / 2;
-
-            if ( Conic_To( RAS_VARS v_control.x, v_control.y,
-                                    v_middle.x,  v_middle.y ) )
-              goto Fail;
-
-            v_control.x = x;
-            v_control.y = y;
-
-            goto Do_Conic;
-          }
-
-          if ( Conic_To( RAS_VARS v_control.x, v_control.y,
-                                  v_start.x,   v_start.y ) )
-            goto Fail;
-
-          goto Close;
-        }
-
-      default:  /* FT_Curve_Tag_Cubic */
-        {
-          Long  x1, y1, x2, y2, x3, y3;
-
-
-          if ( point + 1 > limit                             ||
-               FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic )
-            goto Invalid_Outline;
-
-          point += 2;
-          tags  += 2;
-
-          x1 = SCALED( point[-2].x );
-          y1 = SCALED( point[-2].y );
-          x2 = SCALED( point[-1].x );
-          y2 = SCALED( point[-1].y );
-          x3 = SCALED( point[ 0].x );
-          y3 = SCALED( point[ 0].y );
-
-          if ( flipped )
-          {
-            SWAP_( x1, y1 );
-            SWAP_( x2, y2 );
-            SWAP_( x3, y3 );
-          }
-
-          if ( point <= limit )
-          {
-            if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) )
-              goto Fail;
-            continue;
-          }
-
-          if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) )
-            goto Fail;
-          goto Close;
-        }
-      }
-    }
-
-    /* close the contour with a line segment */
-    if ( Line_To( RAS_VARS v_start.x, v_start.y ) )
-      goto Fail;
-
-  Close:
-    return SUCCESS;
-
-  Invalid_Outline:
-    ras.error = Raster_Err_Invalid;
-
-  Fail:
-    return FAILURE;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Convert_Glyph                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Converts a glyph into a series of segments and arcs and makes a    */
-  /*    profiles list with them.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    flipped :: If set, flip the direction of curve.                    */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS on success, FAILURE if any error was encountered during    */
-  /*    rendering.                                                         */
-  /*                                                                       */
-  static
-  Bool  Convert_Glyph( RAS_ARGS int  flipped )
-  {
-    Short     i;
-    UShort    start;
-
-    PProfile  lastProfile;
-
-
-    ras.fProfile = NULL;
-    ras.joint    = FALSE;
-    ras.fresh    = FALSE;
-
-    ras.maxBuff  = ras.sizeBuff - AlignProfileSize;
-
-    ras.numTurns = 0;
-
-    ras.cProfile         = (PProfile)ras.top;
-    ras.cProfile->offset = ras.top;
-    ras.num_Profs        = 0;
-
-    start = 0;
-
-    for ( i = 0; i < ras.outline.n_contours; i++ )
-    {
-      ras.state    = Unknown;
-      ras.gProfile = NULL;
-
-      if ( Decompose_Curve( RAS_VARS start, ras.outline.contours[i], flipped ) )
-        return FAILURE;
-
-      start = ras.outline.contours[i] + 1;
-
-      /* We must now see whether the extreme arcs join or not */
-      if ( FRAC( ras.lastY ) == 0 &&
-           ras.lastY >= ras.minY  &&
-           ras.lastY <= ras.maxY  )
-        if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow )
-          ras.top--;
-        /* Note that ras.gProfile can be nil if the contour was too small */
-        /* to be drawn.                                                   */
-
-      lastProfile = ras.cProfile;
-      if ( End_Profile( RAS_VAR ) )
-        return FAILURE;
-
-      /* close the `next profile in contour' linked list */
-      if ( ras.gProfile )
-        lastProfile->next = ras.gProfile;
-    }
-
-    if ( Finalize_Profile_Table( RAS_VAR ) )
-      return FAILURE;
-
-    return ( ras.top < ras.maxBuff ? SUCCESS : FAILURE );
-  }
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /**                                                                     **/
-  /**  SCAN-LINE SWEEPS AND DRAWING                                       **/
-  /**                                                                     **/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*  Init_Linked                                                          */
-  /*                                                                       */
-  /*    Initializes 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;
-    Long       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 get there, unless the profile was not part of */
-    /* the list.                                                     */
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*  Update                                                               */
-  /*                                                                       */
-  /*    Update 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.                                                        */
-  /*                                                                       */
-  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 Sweep Procedure Set                                         */
-  /*                                                                       */
-  /*  These four routines are used during the vertical black/white         */
-  /*  sweep phase by the generic Draw_Sweep() function.                    */
-  /*                                                                       */
-  /*************************************************************************/
-
-  static
-  void  Vertical_Sweep_Init( RAS_ARGS Short*  min,
-                                      Short*  max )
-  {
-    Long  pitch = ras.target.pitch;
-
-    UNUSED( max );
-
-
-    ras.traceIncr = (Short)-pitch;
-    ras.traceOfs  = -*min * pitch;
-    if ( pitch > 0 )
-      ras.traceOfs += ( ras.target.rows - 1 ) * pitch;
-
-    ras.gray_min_x = 0;
-    ras.gray_max_x = 0;
-  }
-
-
-  static
-  void  Vertical_Sweep_Span( RAS_ARGS Short       y,
-                                      FT_F26Dot6  x1,
-                                      FT_F26Dot6  x2,
-                                      PProfile    left,
-                                      PProfile    right )
-  {
-    Long   e1, e2;
-    Short  c1, c2;
-    Byte   f1, f2;
-    Byte*  target;
-
-    UNUSED( y );
-    UNUSED( left );
-    UNUSED( right );
-
-
-    /* Drop-out control */
-
-    e1 = TRUNC( CEILING( x1 ) );
-
-    if ( x2 - x1 - ras.precision <= ras.precision_jitter )
-      e2 = e1;
-    else
-      e2 = TRUNC( FLOOR( x2 ) );
-
-    if ( e2 >= 0 && e1 < ras.bWidth )
-    {
-      if ( e1 < 0 )           e1 = 0;
-      if ( e2 >= ras.bWidth ) e2 = ras.bWidth - 1;
-
-      c1 = (Short)( e1 >> 3 );
-      c2 = (Short)( e2 >> 3 );
-
-      f1 =   (unsigned char)0xFF >> ( e1 & 7 );
-      f2 = ~((unsigned char)0x7F >> ( e2 & 7 ));
-
-      if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
-      if ( ras.gray_max_x < c2 ) ras.gray_max_x = c2;
-
-      target = ras.bTarget + ras.traceOfs + 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 );
-    }
-  }
-
-
-  static
-  void Vertical_Sweep_Drop( RAS_ARGS Short       y,
-                                     FT_F26Dot6  x1,
-                                     FT_F26Dot6  x2,
-                                     PProfile    left,
-                                     PProfile    right )
-  {
-    Long   e1, e2;
-    Short  c1, f1;
-
-
-    /* Drop-out control */
-
-    e1 = CEILING( x1 );
-    e2 = FLOOR  ( x2 );
-
-    if ( e1 > e2 )
-    {
-      if ( e1 == e2 + ras.precision )
-      {
-        switch ( ras.dropOutControl )
-        {
-        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 if:          */
-          /*                                                        */
-          /*  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                          */
-          /*                                                        */
-
-          /* FIXXXME: uncommenting this line solves the disappearing */
-          /*          bit problem in the `7' of verdana 10pts, but   */
-          /*          makes a new one in the `C' of arial 14pts      */
-
-#if 0
-          if ( x2 - x1 < ras.precision_half )
-#endif
-          {
-            /* upper stub test */
-            if ( left->next == right && left->height <= 0 )
-              return;
-
-            /* lower stub test */
-            if ( right->next == left && left->start == y )
-              return;
-          }
-
-          /* check that the rightmost pixel isn't set */
-
-          e1 = TRUNC( e1 );
-
-          c1 = (Short)( e1 >> 3 );
-          f1 = e1 &  7;
-
-          if ( e1 >= 0 && e1 < ras.bWidth                      &&
-               ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
-            return;
-
-          if ( ras.dropOutControl == 2 )
-            e1 = e2;
-          else
-            e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
-
-          break;
-
-        default:
-          return;  /* unsupported mode */
-        }
-      }
-      else
-        return;
-    }
-
-    e1 = TRUNC( e1 );
-
-    if ( e1 >= 0 && e1 < ras.bWidth )
-    {
-      c1 = (Short)( e1 >> 3 );
-      f1 = e1 & 7;
-
-      if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
-      if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1;
-
-      ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
-    }
-  }
-
-
-  static
-  void Vertical_Sweep_Step( RAS_ARG )
-  {
-    ras.traceOfs += ras.traceIncr;
-  }
-
-
-  /***********************************************************************/
-  /*                                                                     */
-  /*  Horizontal Sweep Procedure Set                                     */
-  /*                                                                     */
-  /*  These four routines are used during the horizontal black/white     */
-  /*  sweep phase by the generic Draw_Sweep() function.                  */
-  /*                                                                     */
-  /***********************************************************************/
-
-  static
-  void  Horizontal_Sweep_Init( RAS_ARGS Short*  min,
-                                        Short*  max )
-  {
-    /* nothing, really */
-    UNUSED( raster );
-    UNUSED( min );
-    UNUSED( max );
-  }
-
-
-  static
-  void  Horizontal_Sweep_Span( RAS_ARGS Short       y,
-                                        FT_F26Dot6  x1,
-                                        FT_F26Dot6  x2,
-                                        PProfile    left,
-                                        PProfile    right )
-  {
-    Long   e1, e2;
-    PByte  bits;
-    Byte   f1;
-
-    UNUSED( left );
-    UNUSED( right );
-
-
-    if ( x2 - x1 < ras.precision )
-    {
-      e1 = CEILING( x1 );
-      e2 = FLOOR  ( x2 );
-
-      if ( e1 == e2 )
-      {
-        bits = ras.bTarget + ( y >> 3 );
-        f1   = (Byte)( 0x80 >> ( y & 7 ) );
-
-        e1 = TRUNC( e1 );
-
-        if ( e1 >= 0 && e1 < ras.target.rows )
-        {
-          PByte  p;
-
-
-          p = bits - e1*ras.target.pitch;
-          if ( ras.target.pitch > 0 )
-            p += ( ras.target.rows - 1 ) * ras.target.pitch;
-
-          p[0] |= f1;
-        }
-      }
-    }
-  }
-
-
-  static
-  void  Horizontal_Sweep_Drop( RAS_ARGS Short       y,
-                                        FT_F26Dot6  x1,
-                                        FT_F26Dot6  x2,
-                                        PProfile    left,
-                                        PProfile    right )
-  {
-    Long   e1, e2;
-    PByte  bits;
-    Byte   f1;
-
-
-    /* During the horizontal sweep, we only take care of drop-outs */
-
-    e1 = CEILING( x1 );
-    e2 = FLOOR  ( x2 );
-
-    if ( e1 > e2 )
-    {
-      if ( e1 == e2 + ras.precision )
-      {
-        switch ( ras.dropOutControl )
-        {
-        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'.    */
-          /*                                                        */
-
-          /* rightmost stub test */
-          if ( left->next == right && left->height <= 0 )
-            return;
-
-          /* leftmost stub test */
-          if ( right->next == left && left->start == y )
-            return;
-
-          /* check that the rightmost pixel isn't set */
-
-          e1 = TRUNC( e1 );
-
-          bits = ras.bTarget + ( y >> 3 );
-          f1   = (Byte)( 0x80 >> ( y & 7 ) );
-
-          bits -= e1 * ras.target.pitch;
-          if ( ras.target.pitch > 0 )
-            bits += ( ras.target.rows - 1 ) * ras.target.pitch;
-
-          if ( e1 >= 0              &&
-               e1 < ras.target.rows &&
-               *bits & f1 )
-            return;
-
-          if ( ras.dropOutControl == 2 )
-            e1 = e2;
-          else
-            e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
-
-          break;
-
-        default:
-          return;  /* unsupported mode */
-        }
-      }
-      else
-        return;
-    }
-
-    bits = ras.bTarget + ( y >> 3 );
-    f1   = (Byte)( 0x80 >> ( y & 7 ) );
-
-    e1 = TRUNC( e1 );
-
-    if ( e1 >= 0 && e1 < ras.target.rows )
-    {
-      bits -= e1 * ras.target.pitch;
-      if ( ras.target.pitch > 0 )
-        bits += ( ras.target.rows - 1 ) * ras.target.pitch;
-
-      bits[0] |= f1;
-    }
-  }
-
-
-  static
-  void Horizontal_Sweep_Step( RAS_ARG )
-  {
-    /* Nothing, really */
-    UNUSED( raster );
-  }
-
-
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*  Vertical Gray Sweep Procedure Set                                    */
-  /*                                                                       */
-  /*  These two routines are used during the vertical gray-levels sweep    */
-  /*  phase by the generic Draw_Sweep() function.                          */
-  /*                                                                       */
-  /*  NOTES                                                                */
-  /*                                                                       */
-  /*  - The target pixmap's width *must* be a multiple of 4.               */
-  /*                                                                       */
-  /*  - You have to use the function Vertical_Sweep_Span() for the gray    */
-  /*    span call.                                                         */
-  /*                                                                       */
-  /*************************************************************************/
-
-  static
-  void  Vertical_Gray_Sweep_Init( RAS_ARGS Short*  min,
-                                           Short*  max )
-  {
-    Long  pitch, byte_len;
-
-
-    *min = *min & -2;
-    *max = ( *max + 3 ) & -2;
-
-    ras.traceOfs  = 0;
-    pitch         = ras.target.pitch;
-    byte_len      = -pitch;
-    ras.traceIncr = (Short)byte_len;
-    ras.traceG    = ( *min / 2 ) * byte_len;
-
-    if ( pitch > 0 )
-    {
-      ras.traceG += ( ras.target.rows - 1 ) * pitch;
-      byte_len    = -byte_len;
-    }
-
-    ras.gray_min_x =  (Short)byte_len;
-    ras.gray_max_x = -(Short)byte_len;
-  }
-
-
-  static
-  void  Vertical_Gray_Sweep_Step( RAS_ARG )
-  {
-    Int    c1, c2;
-    PByte  pix, bit, bit2;
-    Int*   count = ras.count_table;
-    Byte*  grays;
-
-
-    ras.traceOfs += ras.gray_width;
-
-    if ( ras.traceOfs > ras.gray_width )
-    {
-      pix   = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
-      grays = ras.grays;
-
-      if ( ras.gray_max_x >= 0 )
-      {
-        Long   last_pixel = ras.target.width - 1;
-        Int    last_cell  = last_pixel >> 2;
-        Int    last_bit   = last_pixel & 3;
-        Bool   over       = 0;
-
-        if ( ras.gray_max_x >= last_cell && last_bit != 3 )
-        {
-          ras.gray_max_x = last_cell - 1;
-          over = 1;
-        }
-
-        if ( ras.gray_min_x < 0 )
-          ras.gray_min_x = 0;
-
-        bit   = ras.bTarget + ras.gray_min_x;
-        bit2  = bit + ras.gray_width;
-
-        c1 = ras.gray_max_x - ras.gray_min_x;
-
-        while ( c1 >= 0 )
-        {
-          c2 = count[*bit] + count[*bit2];
-
-          if ( c2 )
-          {
-            pix[0] = grays[(c2 >> 12) & 0x000F];
-            pix[1] = grays[(c2 >> 8 ) & 0x000F];
-            pix[2] = grays[(c2 >> 4 ) & 0x000F];
-            pix[3] = grays[ c2        & 0x000F];
-
-            *bit  = 0;
-            *bit2 = 0;
-          }
-
-          bit++;
-          bit2++;
-          pix += 4;
-          c1--;
-        }
-
-        if ( over )
-        {
-          c2 = count[*bit] + count[*bit2];
-          if ( c2 )
-          {
-            switch ( last_bit )
-            {
-            case 2:
-              pix[2] = grays[(c2 >> 4 ) & 0x000F];
-            case 1:
-              pix[1] = grays[(c2 >> 8 ) & 0x000F];
-            default:
-              pix[0] = grays[(c2 >> 12) & 0x000F];
-            }
-
-            *bit  = 0;
-            *bit2 = 0;
-          }
-        }
-      }
-
-      ras.traceOfs = 0;
-      ras.traceG  += ras.traceIncr;
-
-      ras.gray_min_x =  32000;
-      ras.gray_max_x = -32000;
-    }
-  }
-
-
-  static
-  void  Horizontal_Gray_Sweep_Span( RAS_ARGS Short       y,
-                                             FT_F26Dot6  x1,
-                                             FT_F26Dot6  x2,
-                                             PProfile    left,
-                                             PProfile    right )
-  {
-    /* nothing, really */
-    UNUSED( raster );
-    UNUSED( y );
-    UNUSED( x1 );
-    UNUSED( x2 );
-    UNUSED( left );
-    UNUSED( right );
-  }
-
-
-  static
-  void  Horizontal_Gray_Sweep_Drop( RAS_ARGS Short       y,
-                                             FT_F26Dot6  x1,
-                                             FT_F26Dot6  x2,
-                                             PProfile    left,
-                                             PProfile    right )
-  {
-    Long   e1, e2;
-    PByte  pixel;
-    Byte   color;
-
-
-    /* During the horizontal sweep, we only take care of drop-outs */
-    e1 = CEILING( x1 );
-    e2 = FLOOR  ( x2 );
-
-    if ( e1 > e2 )
-    {
-      if ( e1 == e2 + ras.precision )
-      {
-        switch ( ras.dropOutControl )
-        {
-        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'.    */
-          /*                                                        */
-
-          /* rightmost stub test */
-          if ( left->next == right && left->height <= 0 )
-            return;
-
-          /* leftmost stub test */
-          if ( right->next == left && left->start == y )
-            return;
-
-          if ( ras.dropOutControl == 2 )
-            e1 = e2;
-          else
-            e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
-
-          break;
-
-        default:
-          return;  /* unsupported mode */
-        }
-      }
-      else
-        return;
-    }
-
-    if ( e1 >= 0 )
-    {
-      if ( x2 - x1 >= ras.precision_half )
-        color = ras.grays[2];
-      else
-        color = ras.grays[1];
-
-      e1 = TRUNC( e1 ) / 2;
-      if ( e1 < ras.target.rows )
-      {
-        pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;
-        if ( ras.target.pitch > 0 )
-          pixel += ( ras.target.rows - 1 ) * ras.target.pitch;
-
-        if ( pixel[0] == ras.grays[0] )
-          pixel[0] = color;
-      }
-    }
-  }
-
-
-#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*  Generic Sweep Drawing routine                                        */
-  /*                                                                       */
-  /*************************************************************************/
-
-  static
-  Bool  Draw_Sweep( RAS_ARG )
-  {
-    Short  y, y_change, y_height;
-
-    PProfile  P, Q, P_Left, P_Right;
-
-    Short  min_Y, max_Y, top, bottom, dropouts;
-
-    Long  x1, x2, xs, e1, e2;
-
-    TProfileList  wait;
-    TProfileList  draw_left, draw_right;
-
-
-    /* Init empty linked lists */
-
-    Init_Linked( &wait );
-
-    Init_Linked( &draw_left  );
-    Init_Linked( &draw_right );
-
-    /* first, compute min and max Y */
-
-    P     = ras.fProfile;
-    max_Y = (short)TRUNC( ras.minY );
-    min_Y = (short)TRUNC( ras.maxY );
-
-    while ( P )
-    {
-      Q = P->link;
-
-      bottom = (Short)P->start;
-      top    = (Short)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 Y-turns */
-    if ( ras.numTurns == 0 )
-    {
-      ras.error = Raster_Err_Invalid;
-      return FAILURE;
-    }
-
-    /* Now inits the sweep */
-
-    ras.Proc_Sweep_Init( RAS_VARS &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.numTurns > 0 &&
-         ras.sizeBuff[-ras.numTurns] == min_Y )
-      ras.numTurns--;
-
-    while ( ras.numTurns > 0 )
-    {
-      /* look in the wait list for new activations */
-
-      P = wait;
-
-      while ( P )
-      {
-        Q = P->link;
-        P->countL -= y_height;
-        if ( P->countL == 0 )
-        {
-          DelOld( &wait, P );
-
-          switch ( P->flow )
-          {
-          case Flow_Up:
-            InsNew( &draw_left,  P );
-            break;
-
-          case Flow_Down:
-            InsNew( &draw_right, P );
-            break;
-          }
-        }
-
-        P = Q;
-      }
-
-      /* Sort the drawing lists */
-
-      Sort( &draw_left );
-      Sort( &draw_right );
-
-      y_change = (Short)ras.sizeBuff[-ras.numTurns--];
-      y_height = y_change - y;
-
-      while ( y < y_change )
-      {
-        /* Let's trace */
-
-        dropouts = 0;
-
-        P_Left  = draw_left;
-        P_Right = draw_right;
-
-        while ( P_Left )
-        {
-          x1 = P_Left ->X;
-          x2 = P_Right->X;
-
-          if ( x1 > x2 )
-          {
-            xs = x1;
-            x1 = x2;
-            x2 = xs;
-          }
-
-          if ( x2 - x1 <= ras.precision )
-          {
-            e1 = FLOOR( x1 );
-            e2 = CEILING( x2 );
-
-            if ( ras.dropOutControl != 0                 &&
-                 ( e1 > e2 || e2 == e1 + ras.precision ) )
-            {
-              /* a drop out was detected */
-
-              P_Left ->X = x1;
-              P_Right->X = x2;
-
-              /* mark profile for drop-out processing */
-              P_Left->countL = 1;
-              dropouts++;
-
-              goto Skip_To_Next;
-            }
-          }
-
-          ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right );
-
-        Skip_To_Next:
-
-          P_Left  = P_Left->link;
-          P_Right = P_Right->link;
-        }
-
-        /* 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.Proc_Sweep_Step( RAS_VAR );
-
-        y++;
-
-        if ( y < y_change )
-        {
-          Sort( &draw_left  );
-          Sort( &draw_right );
-        }
-      }
-
-      /* Now finalize the profiles that needs it */
-
-      {
-        PProfile  Q, P;
-
-
-        P = draw_left;
-        while ( P )
-        {
-          Q = P->link;
-          if ( P->height == 0 )
-            DelOld( &draw_left, P );
-          P = Q;
-        }
-      }
-
-      {
-        PProfile  Q, P = draw_right;
-
-
-        while ( P )
-        {
-          Q = P->link;
-          if ( P->height == 0 )
-            DelOld( &draw_right, P );
-          P = Q;
-        }
-      }
-    }
-
-    /* for gray-scaling, flushes the bitmap scanline cache */
-    while ( y <= max_Y )
-    {
-      ras.Proc_Sweep_Step( RAS_VAR );
-      y++;
-    }
-
-    return SUCCESS;
-
-  Scan_DropOuts:
-
-    P_Left  = draw_left;
-    P_Right = draw_right;
-
-    while ( P_Left )
-    {
-      if ( P_Left->countL )
-      {
-        P_Left->countL = 0;
-#if 0
-        dropouts--;  /* -- this is useful when debugging only */
-#endif
-        ras.Proc_Sweep_Drop( RAS_VARS y,
-                                      P_Left->X,
-                                      P_Right->X,
-                                      P_Left,
-                                      P_Right );
-      }
-
-      P_Left  = P_Left->link;
-      P_Right = P_Right->link;
-    }
-
-    goto Next_Line;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Render_Single_Pass                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Performs one sweep with sub-banding.                               */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    flipped :: If set, flip the direction of the outline.              */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Renderer error code.                                               */
-  /*                                                                       */
-  static
-  int  Render_Single_Pass( RAS_ARGS Bool  flipped )
-  {
-    Short  i, j, k;
-
-
-    while ( ras.band_top >= 0 )
-    {
-      ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision;
-      ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision;
-
-      ras.top = ras.buff;
-
-      ras.error = Raster_Err_None;
-
-      if ( Convert_Glyph( RAS_VARS flipped ) )
-      {
-        if ( ras.error != Raster_Err_Overflow )
-          return FAILURE;
-
-        ras.error = Raster_Err_None;
-
-        /* sub-banding */
-
-#ifdef DEBUG_RASTER
-        ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) );
-#endif
-
-        i = ras.band_stack[ras.band_top].y_min;
-        j = ras.band_stack[ras.band_top].y_max;
-
-        k = ( i + j ) / 2;
-
-        if ( ras.band_top >= 7 || k < i )
-        {
-          ras.band_top = 0;
-          ras.error    = Raster_Err_Invalid;
-
-          return ras.error;
-        }
-
-        ras.band_stack[ras.band_top + 1].y_min = k;
-        ras.band_stack[ras.band_top + 1].y_max = j;
-
-        ras.band_stack[ras.band_top].y_max = k - 1;
-
-        ras.band_top++;
-      }
-      else
-      {
-        if ( ras.fProfile )
-          if ( Draw_Sweep( RAS_VAR ) )
-             return ras.error;
-        ras.band_top--;
-      }
-    }
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Render_Glyph                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Renders a glyph in a bitmap.  Sub-banding if needed.               */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* XXX Fixme: ftraster's error codes don't harmonize with FT2's ones!    */
-  /*                                                                       */
-  LOCAL_FUNC
-  FT_Error  Render_Glyph( RAS_ARG )
-  {
-    FT_Error  error;
-
-
-    Set_High_Precision( RAS_VARS ras.outline.flags &
-                        ft_outline_high_precision );
-    ras.scale_shift    = ras.precision_shift;
-    ras.dropOutControl = 2;
-    ras.second_pass    = !( ras.outline.flags & ft_outline_single_pass );
-
-    /* Vertical Sweep */
-    ras.Proc_Sweep_Init = Vertical_Sweep_Init;
-    ras.Proc_Sweep_Span = Vertical_Sweep_Span;
-    ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
-    ras.Proc_Sweep_Step = Vertical_Sweep_Step;
-
-    ras.band_top            = 0;
-    ras.band_stack[0].y_min = 0;
-    ras.band_stack[0].y_max = ras.target.rows - 1;
-
-    ras.bWidth  = ras.target.width;
-    ras.bTarget = (Byte*)ras.target.buffer;
-
-    if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 )
-      return error;
-
-    /* Horizontal Sweep */
-    if ( ras.second_pass && ras.dropOutControl != 0 )
-    {
-      ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
-      ras.Proc_Sweep_Span = Horizontal_Sweep_Span;
-      ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;
-      ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
-
-      ras.band_top            = 0;
-      ras.band_stack[0].y_min = 0;
-      ras.band_stack[0].y_max = ras.target.width - 1;
-
-      if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 )
-        return error;
-    }
-
-    return FT_Err_Ok;
-  }
-
-
-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Render_Gray_Glyph                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Renders a glyph with grayscaling.  Sub-banding if needed.          */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_FUNC
-  FT_Error  Render_Gray_Glyph( RAS_ARG )
-  {
-    Long      pixel_width;
-    FT_Error  error;
-
-
-    Set_High_Precision( RAS_VARS ras.outline.flags &
-                        ft_outline_high_precision );
-    ras.scale_shift    = ras.precision_shift + 1;
-    ras.dropOutControl = 2;
-    ras.second_pass    = !( ras.outline.flags & ft_outline_single_pass );
-
-
-    /* Vertical Sweep */
-
-    ras.band_top            = 0;
-    ras.band_stack[0].y_min = 0;
-    ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
-
-    ras.bWidth  = ras.gray_width;
-    pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );
-
-    if ( ras.bWidth > pixel_width )
-      ras.bWidth = pixel_width;
-
-    ras.bWidth  = ras.bWidth * 8;
-    ras.bTarget = (Byte*)ras.gray_lines;
-    ras.gTarget = (Byte*)ras.target.buffer;
-
-    ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;
-    ras.Proc_Sweep_Span = Vertical_Sweep_Span;
-    ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
-    ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;
-
-    error = Render_Single_Pass( RAS_VARS 0 );
-    if (error)
-      return error;
-
-    /* Horizontal Sweep */
-    if ( ras.second_pass && ras.dropOutControl != 0 )
-    {
-      ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
-      ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
-      ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;
-      ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
-
-      ras.band_top            = 0;
-      ras.band_stack[0].y_min = 0;
-      ras.band_stack[0].y_max = ras.target.width * 2 - 1;
-
-      error = Render_Single_Pass( RAS_VARS 1 );
-      if (error)
-        return error;
-    }
-
-    return FT_Err_Ok;
-  }
-
-#else /* FT_RASTER_OPTION_ANTI_ALIASING */
-
-  LOCAL_FUNC
-  FT_Error  Render_Gray_Glyph( RAS_ARG )
-  {
-    UNUSED_RASTER;
-    return Raster_Err_Unsupported;
-  }
-
-#endif
-
-
-  static
-  void  ft_black_init( TRaster_Instance*  raster )
-  {
-    FT_UInt  n;
-    FT_ULong c;
-
-    /* setup count table */
-    for ( n = 0; n < 256; n++ )
-    {
-      c = ( n & 0x55 ) + ( ( n & 0xAA ) >> 1 );
-
-      c = ( ( c << 6 ) & 0x3000 ) |
-          ( ( c << 4 ) & 0x0300 ) |
-          ( ( c << 2 ) & 0x0030 ) |
-                   (c  & 0x0003 );
-
-      raster->count_table[n] = c;
-    }
-
-    /* set default 5-levels gray palette */
-    for ( n = 0; n < 5; n++ )
-      raster->grays[n] = n * 255 / 4;
-
-    raster->gray_width = RASTER_GRAY_LINES / 2;
-  }
-
-  /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/
-  /****                         a static object.                  *****/
-
-#ifdef _STANDALONE_
-
-
-  static
-  int  ft_black_new( void*  memory,
-                     FT_Raster *araster )
-  {
-     static FT_RasterRec_  the_raster;
-
-
-     *araster = &the_raster;
-     memset( &the_raster, sizeof ( the_raster ), 0 );
-     ft_black_init( &the_raster );
-
-     return 0;
-  }
-
-
-  static
-  void  ft_black_done( FT_Raster  raster )
-  {
-    /* nothing */
-    raster->init = 0;
-  }
-
-
-#else /* _STANDALONE_ */
-
-
-  static
-  int  ft_black_new( FT_Memory           memory,
-                     TRaster_Instance**  araster )
-  {
-    FT_Error           error;
-    TRaster_Instance*  raster;
-
-
-    *araster = 0;
-    if ( !ALLOC( raster, sizeof ( *raster ) ) )
-    {
-      raster->memory = memory;
-      ft_black_init( raster );
-
-      *araster = raster;
-    }
-
-    return error;
-  }
-
-
-  static
-  void ft_black_done( TRaster_Instance*  raster )
-  {
-    FT_Memory  memory = (FT_Memory)raster->memory;
-    FREE( raster );
-  }
-
-
-#endif /* _STANDALONE_ */
-
-
-  static
-  void ft_black_reset( TRaster_Instance* raster,
-                       const char*       pool_base,
-                       long              pool_size )
-  {
-    if ( raster && pool_base && pool_size >= 4096 )
-    {
-      /* save the pool */
-      raster->buff     = (PLong)pool_base;
-      raster->sizeBuff = raster->buff + pool_size / sizeof ( Long );
-    }
-  }
-
-
-  static
-  void ft_black_set_mode( TRaster_Instance* raster,
-                          unsigned long     mode,
-                          const char*       palette )
-  {
-    if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
-    {
-      /* set 5-levels gray palette */
-      raster->grays[0] = palette[0];
-      raster->grays[1] = palette[1];
-      raster->grays[2] = palette[2];
-      raster->grays[3] = palette[3];
-      raster->grays[4] = palette[4];
-    }
-  }
-
-
-  static
-  int  ft_black_render( TRaster_Instance*  raster,
-                        FT_Raster_Params*  params )
-  {
-    FT_Outline*  outline    = (FT_Outline*)params->source;
-    FT_Bitmap*   target_map = params->target;
-
-
-    if ( !raster || !raster->buff || !raster->sizeBuff )
-      return Raster_Err_Not_Ini;
-
-    if ( !outline || !outline->contours || !outline->points )
-      return Raster_Err_Invalid;
-
-    /* return immediately if the outline is empty */
-    if ( outline->n_points == 0 || outline->n_contours <= 0 )
-      return Raster_Err_None;
-
-    if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 )
-      return Raster_Err_Invalid;
-
-    if ( !target_map || !target_map->buffer )
-      return Raster_Err_Invalid;
-
-    /* this version of the raster does not support direct rendering, sorry */
-    if ( params->flags & ft_raster_flag_direct )
-      return Raster_Err_Unsupported;
-
-    ras.outline  = *outline;
-    ras.target   = *target_map;
-
-    return ( params->flags & ft_raster_flag_aa
-               ? Render_Gray_Glyph( raster )
-               : Render_Glyph( raster ) );
-  }
-
-
-  FT_Raster_Funcs  ft_default_raster =
-  {
-    ft_glyph_format_outline,
-    (FT_Raster_New_Func)     ft_black_new,
-    (FT_Raster_Reset_Func)   ft_black_reset,
-    (FT_Raster_Set_Mode_Func)ft_black_set_mode,
-    (FT_Raster_Render_Func)  ft_black_render,
-    (FT_Raster_Done_Func)    ft_black_done
-  };
-
-
-/* END */
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -45,10 +45,8 @@
 # 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_)ftraster.c \
-                $(BASE_)ftglyph.c  \
-                $(BASE_)ftmm.c     \
-                $(BASE_)ftgrays.c
+BASE_EXT_SRC := $(BASE_)ftglyph.c  \
+                $(BASE_)ftmm.c
 
 # Default extensions objects
 #
--- a/src/cff/module.mk
+++ b/src/cff/module.mk
@@ -1,7 +1,7 @@
 make_module_list: add_cff_driver
 
 add_cff_driver:
-	$(OPEN_DRIVER)cff_driver_interface$(CLOSE_DRIVER)
+	$(OPEN_DRIVER)cff_driver_class$(CLOSE_DRIVER)
 	$(ECHO_DRIVER)cff       $(ECHO_DRIVER_DESC)OpenType fonts with extension *.otf$(ECHO_DRIVER_DONE)
 
 # EOF
--- a/src/cff/t2driver.c
+++ b/src/cff/t2driver.c
@@ -78,7 +78,7 @@
   /*                   formats.                                            */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Only horizontal layouts (left-to-right & right-to-left) are        */
@@ -144,118 +144,10 @@
 #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.                              */
-  /*                                                                       */
-  /*    horz_resolution :: The horizontal resolution of the output device. */
-  /*                                                                       */
-  /*    vert_resolution :: The vertical resolution of the output device.   */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size        :: A handle to the target size object.                 */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  static
-  FT_Error  Set_Char_Sizes( T2_Size     size,
-                            FT_F26Dot6  char_width,
-                            FT_F26Dot6  char_height,
-                            FT_UInt     horz_resolution,
-                            FT_UInt     vert_resolution )
-  {
-    FT_Size_Metrics*  metrics = &size->metrics;
-    T2_Face           face    = (T2_Face)size->face;
-    FT_Long           dim_x, dim_y;
-
-
-    /* This bit flag, when set, indicates that the pixel size must be */
-    /* truncated to an integer.  Nearly all TrueType fonts have this  */
-    /* bit set, as hinting won't work really well otherwise.          */
-    /*                                                                */
-    /* However, for those rare fonts who do not set it, we override   */
-    /* the default computations performed by the base layer.  I       */
-    /* really don't know whether this is useful, but hey, that's the  */
-    /* spec :-)                                                       */
-    /*                                                                */
-    if ( ( face->header.Flags & 8 ) == 0 )
-    {
-      /* Compute pixel sizes in 26.6 units */
-      dim_x = ( char_width  * horz_resolution ) / 72;
-      dim_y = ( char_height * vert_resolution ) / 72;
-
-      metrics->x_scale = FT_DivFix( dim_x, face->root.units_per_EM );
-      metrics->y_scale = FT_DivFix( dim_y, face->root.units_per_EM );
-
-      metrics->x_ppem  = (FT_UShort)( dim_x >> 6 );
-      metrics->y_ppem  = (FT_UShort)( dim_y >> 6 );
-    }
-
-    return T2_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
-  FT_Error  Set_Pixel_Sizes( T2_Size  size,
-                             FT_UInt  pixel_width,
-                             FT_UInt  pixel_height )
-  {
-    UNUSED( pixel_width );
-    UNUSED( pixel_height );
-
-    return T2_Reset_Size( size );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
   /*    Load_Glyph                                                         */
   /*                                                                       */
   /* <Description>                                                         */
@@ -277,7 +169,7 @@
   /*                   whether to hint the outline, etc).                  */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  Load_Glyph( T2_GlyphSlot  slot,
@@ -385,58 +277,57 @@
 
 
   static
-  FTDriver_Interface  t2_get_interface( T2_Driver    driver,
-                                        const char*  interface )
+  FT_Module_Interface  t2_get_interface( T2_Driver    driver,
+                                         const char*  interface )
   {
-    FT_Driver        sfntd = FT_Get_Driver( driver->root.library, "sfnt" );
-    SFNT_Interface*  sfnt;
+    FT_Module  sfnt;
 
-
-    /* only return the default interface from the SFNT module */
-    if ( sfntd )
-    {
-      sfnt = (SFNT_Interface*)(sfntd->interface.format_interface);
-      if ( sfnt )
-        return sfnt->get_interface( (FT_Driver)driver, interface );
-    }
-
-    return 0;
+    /* we simply pass our request to the "sfnt" module */
+    sfnt = FT_Get_Module( driver->root.root.library, "sfnt" );
+    return sfnt ? sfnt->clazz->get_interface( sfnt, interface ) : 0;
   }
 
 
   /* The FT_DriverInterface structure is defined in ftdriver.h. */
 
-  const FT_DriverInterface  cff_driver_interface =
+  const FT_Driver_Class   cff_driver_class =
   {
-    sizeof ( T2_DriverRec ),
-    sizeof ( TT_FaceRec ),
-    sizeof ( FT_SizeRec ),
-    sizeof ( T2_GlyphSlotRec ),
+    /* begin with the FT_Module_Class fields */
+    {
+      ft_module_font_driver | ft_module_driver_scalable,
+      sizeof( T2_DriverRec ),
+      "cff",
+      0x10000,
+      0x20000,
 
-    "cff",           /* driver name                           */
-    100,             /* driver version == 1.0                 */
-    200,             /* driver requires FreeType 2.0 or above */
+      0,   /* module-specific interface */
+      
+      (FT_Module_Constructor)  T2_Init_Driver,
+      (FT_Module_Destructor)   T2_Done_Driver,
+      (FT_Module_Requester)    t2_get_interface,
+    },
+    
+    /* now the specific driver fields */
+    sizeof( TT_FaceRec ),
+    sizeof( FT_SizeRec ),
+    sizeof( T2_GlyphSlotRec ),
 
-    (void*)0,
-
-    (FTDriver_initDriver)     T2_Init_Driver,
-    (FTDriver_doneDriver)     T2_Done_Driver,
-    (FTDriver_getInterface)   t2_get_interface,
-
     (FTDriver_initFace)       T2_Init_Face,
     (FTDriver_doneFace)       T2_Done_Face,
-    (FTDriver_getKerning)     Get_Kerning,
+    (FTDriver_initSize)       0,
+    (FTDriver_doneSize)       0,
+    (FTDriver_initGlyphSlot)  0,
+    (FTDriver_doneGlyphSlot)  0,
 
-    (FTDriver_initSize)       T2_Init_Size,
-    (FTDriver_doneSize)       T2_Done_Size,
-    (FTDriver_setCharSizes)   Set_Char_Sizes,
-    (FTDriver_setPixelSizes)  Set_Pixel_Sizes,
-
-    (FTDriver_initGlyphSlot)  T2_Init_GlyphSlot,
-    (FTDriver_doneGlyphSlot)  T2_Done_GlyphSlot,
+    (FTDriver_setCharSizes)   0,
+    (FTDriver_setPixelSizes)  0,
+    
     (FTDriver_loadGlyph)      Load_Glyph,
-
     (FTDriver_getCharIndex)   Get_Char_Index,
+
+    (FTDriver_getKerning)     Get_Kerning,
+    (FTDriver_attachFile)     0,
+    (FTDriver_getAdvances)    0
   };
 
 
@@ -446,7 +337,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    getDriverInterface                                                 */
+  /*    getDriverClass                                                     */
   /*                                                                       */
   /* <Description>                                                         */
   /*    This function is used when compiling the TrueType driver as a      */
@@ -462,9 +353,9 @@
   /*    format-specific interface can then be retrieved through the method */
   /*    interface->get_format_interface.                                   */
   /*                                                                       */
-  EXPORT_FUNC( FT_DriverInterface* )  getDriverInterface( void )
+  EXPORT_FUNC( FT_Driver_Class* )  getDriverClass( void )
   {
-    return &cff_driver_interface;
+    return &cff_driver_class;
   }
 
 
--- a/src/cff/t2driver.h
+++ b/src/cff/t2driver.h
@@ -19,12 +19,9 @@
 #ifndef T2DRIVER_H
 #define T2DRIVER_H
 
-#include <freetype/freetype.h>
 #include <freetype/internal/ftdriver.h>
-#include <t2objs.h>
 
-
-  FT_EXPORT_VAR( const FT_DriverInterface )  cff_driver_interface;
+  FT_EXPORT_VAR( const FT_Driver_Class )  cff_driver_class;
 
 
 #endif /* T2DRIVER_H */
--- a/src/cff/t2gload.c
+++ b/src/cff/t2gload.c
@@ -231,9 +231,12 @@
 
     if ( glyph )
     {
-      builder->base         = glyph->root.outline;
-      builder->max_points   = glyph->max_points;
-      builder->max_contours = glyph->max_contours;
+      FT_GlyphLoader*  loader = glyph->root.loader;
+      
+      builder->loader  = loader;
+      builder->base    = &loader->base.outline;
+      builder->current = &loader->current.outline;
+      FT_GlyphLoader_Rewind( loader );
     }
 
     if ( size )
@@ -249,10 +252,6 @@
     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;
   }
 
 
@@ -274,13 +273,8 @@
   {
     T2_GlyphSlot  glyph = builder->glyph;
 
-
     if ( glyph )
-    {
-      glyph->root.outline = builder->base;
-      glyph->max_points   = builder->max_points;
-      glyph->max_contours = builder->max_contours;
-    }
+      glyph->root.outline = *builder->base;
   }
 
 
@@ -366,45 +360,11 @@
   FT_Error  check_points( T2_Builder*  builder,
                           FT_Int       count )
   {
-    FT_Outline*  base    = &builder->base;
-    FT_Outline*  outline = &builder->current;
+    return FT_GlyphLoader_Check_Points( builder->loader,
+                                        count, 0 );
+  }                                         
 
 
-    if ( !builder->load_points )
-      return T2_Err_Ok;
-
-    count += base->n_points + outline->n_points;
-
-    /* realloc points table if necessary */
-    if ( count >= builder->max_points )
-    {
-      FT_Error   error;
-      FT_Memory  memory    = builder->memory;
-      FT_Int     increment = outline->points - base->points;
-      FT_Int     current   = builder->max_points;
-
-
-      while ( builder->max_points < count )
-        builder->max_points += 8;
-
-      if ( REALLOC_ARRAY( base->points, current,
-                          builder->max_points, FT_Vector )  ||
-
-           REALLOC_ARRAY( base->tags, current,
-                          builder->max_points, FT_Byte )    )
-      {
-        builder->error = error;
-        return error;
-      }
-
-      outline->points = base->points + increment;
-      outline->tags  = base->tags  + increment;
-    }
-
-    return T2_Err_Ok;
-  }
-
-
   /* add a new point, do not check space */
   static
   void  add_point( T2_Builder*  builder,
@@ -412,15 +372,13 @@
                    FT_Pos       y,
                    FT_Byte      flag )
   {
-    FT_Outline*  outline = &builder->current;
+    FT_Outline*  outline = builder->current;
 
-
     if ( builder->load_points )
     {
       FT_Vector*  point   = outline->points + outline->n_points;
       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;
 
-
       point->x = x >> 16;
       point->y = y >> 16;
       *control = flag ? FT_Curve_Tag_On : FT_Curve_Tag_Cubic;
@@ -427,7 +385,6 @@
 
       builder->last = *point;
     }
-
     outline->n_points++;
   }
 
@@ -440,7 +397,6 @@
   {
     FT_Error  error;
 
-
     error = check_points( builder, 1 );
     if ( !error )
       add_point( builder, x, y, 1 );
@@ -453,10 +409,9 @@
   static
   FT_Error  add_contour( T2_Builder*  builder )
   {
-    FT_Outline*  base    = &builder->base;
-    FT_Outline*  outline = &builder->current;
+    FT_Outline*  outline = builder->current;
+    FT_Error     error;
 
-
     if ( !builder->load_points )
     {
       outline->n_contours++;
@@ -463,34 +418,15 @@
       return T2_Err_Ok;
     }
 
-    /* realloc contours array if necessary */
-    if ( base->n_contours + outline->n_contours >= builder->max_contours &&
-         builder->load_points )
+    error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 );
+    if (!error)
     {
-      FT_Error  error;
-      FT_Memory memory    = builder->memory;
-      FT_Int    increment = outline->contours - base->contours;
-      FT_Int    current   = builder->max_contours;
-
-
-      builder->max_contours += 4;
-
-      if ( REALLOC_ARRAY( base->contours,
-                          current, builder->max_contours, FT_Short ) )
-      {
-        builder->error = error;
-        return error;
-      }
-
-      outline->contours = base->contours + increment;
+      if ( outline->n_contours > 0 )
+        outline->contours[outline->n_contours - 1] = outline->n_points - 1;
+  
+      outline->n_contours++;
     }
-
-    if ( outline->n_contours > 0 )
-      outline->contours[outline->n_contours - 1] = outline->n_points - 1;
-
-    outline->n_contours++;
-
-    return T2_Err_Ok;
+    return error;
   }
 
 
@@ -505,7 +441,6 @@
     {
       FT_Error  error;
 
-
       builder->path_begun = 1;
       error = add_contour( builder );
       if ( error )
@@ -520,9 +455,8 @@
   static
   void  close_contour( T2_Builder*  builder )
   {
-    FT_Outline*  outline = &builder->current;
+    FT_Outline*  outline = builder->current;
 
-
     if ( outline->n_contours > 0 )
       outline->contours[outline->n_contours - 1] = outline->n_points - 1;
   }
@@ -550,7 +484,7 @@
   /*    charstring_len   :: The length in bytes of the charstring stream.  */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  T2_Parse_CharStrings( T2_Decoder*  decoder,
@@ -593,7 +527,7 @@
     ip    = zone->cursor = zone->base;
 
     error   = T2_Err_Ok;
-    outline = &builder->current;
+    outline = builder->current;
 
     x = builder->pos_x;
     y = builder->pos_y;
@@ -1182,8 +1116,7 @@
           close_contour( builder );
 
           /* add current outline to the glyph slot */
-          builder->base.n_points   += builder->current.n_points;
-          builder->base.n_contours += builder->current.n_contours;
+          FT_GlyphLoader_Add( builder->loader );
 
           /* return now! */
           FT_TRACE4(( "\n\n" ));
@@ -1769,7 +1702,7 @@
         {
           /* scale the outline and the metrics */
           FT_Int       n;
-          FT_Outline*  cur     = &decoder.builder.base;
+          FT_Outline*  cur     = &glyph->root.outline;
           FT_Vector*   vec     = cur->points;
           FT_Fixed     x_scale = glyph->x_scale;
           FT_Fixed     y_scale = glyph->y_scale;
--- a/src/cff/t2gload.h
+++ b/src/cff/t2gload.h
@@ -85,34 +85,31 @@
   /*                                                                       */
   typedef struct  T2_Builder_
   {
-    FT_Memory     memory;
-    TT_Face       face;
-    T2_GlyphSlot  glyph;
+    FT_Memory        memory;
+    TT_Face          face;
+    T2_GlyphSlot     glyph;
+    FT_GlyphLoader*  loader;
+    FT_Outline*      base;
+    FT_Outline*      current;
 
-    FT_Outline    current;       /* the current glyph outline   */
-    FT_Outline    base;          /* the composite glyph outline */
+    FT_Vector        last;
 
-    FT_Int        max_points;    /* capacity of base outline in points   */
-    FT_Int        max_contours;  /* capacity of base outline in contours */
+    FT_Fixed         scale_x;
+    FT_Fixed         scale_y;
 
-    FT_Vector     last;
+    FT_Pos           pos_x;
+    FT_Pos           pos_y;
 
-    FT_Fixed      scale_x;
-    FT_Fixed      scale_y;
+    FT_Vector        left_bearing;
+    FT_Vector        advance;
 
-    FT_Pos        pos_x;
-    FT_Pos        pos_y;
+    FT_BBox          bbox;          /* bounding box */
+    FT_Bool          path_begun;
+    FT_Bool          load_points;
+    FT_Bool          no_recurse;
 
-    FT_Vector     left_bearing;
-    FT_Vector     advance;
-
-    FT_BBox       bbox;          /* bounding box */
-    FT_Bool       path_begun;
-    FT_Bool       load_points;
-    FT_Bool       no_recurse;
-
-    FT_Error      error;         /* only used for memory errors */
-    FT_Bool       metrics_only;
+    FT_Error         error;         /* only used for memory errors */
+    FT_Bool          metrics_only;
 
   } T2_Builder;
 
--- a/src/cff/t2objs.c
+++ b/src/cff/t2objs.c
@@ -68,7 +68,7 @@
   /*    face       :: The newly built face object.                         */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeTrue error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_DEF
   FT_Error  T2_Init_Face( FT_Stream      stream,
@@ -78,18 +78,12 @@
                           FT_Parameter*  params )
   {
     FT_Error         error;
-    FT_Driver        sfnt_driver;
     SFNT_Interface*  sfnt;
 
+    sfnt = (SFNT_Interface*)
+              FT_Get_Module_Interface( face->root.driver->root.library,"sfnt" );
+    if ( !sfnt ) goto Bad_Format;
 
-    sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" );
-    if ( !sfnt_driver )
-      goto Bad_Format;
-
-    sfnt = (SFNT_Interface*)(sfnt_driver->interface.format_interface);
-    if ( !sfnt )
-      goto Bad_Format;
-
     /* create input stream from resource */
     if ( FILE_Seek( 0 ) )
       goto Exit;
@@ -163,13 +157,9 @@
   void  T2_Done_Face( T2_Face  face )
   {
     FT_Memory  memory = face->root.memory;
-#if 0
-    FT_Stream  stream = face->root.stream;
-#endif
 
     SFNT_Interface*  sfnt = face->sfnt;
 
-
     if ( sfnt )
       sfnt->done_face( face );
 
@@ -188,151 +178,7 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /*                           SIZE  FUNCTIONS                             */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
   /* <Function>                                                            */
-  /*    T2_Init_Size                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes a new OpenType size object.                            */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size :: A handle to the size object.                               */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_DEF
-  FT_Error  T2_Init_Size( T2_Size  size )
-  {
-    UNUSED( size );
-
-    return 0;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T2_Done_Size                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The OpenType size object finalizer.                                */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
-  LOCAL_FUNC
-  void  T2_Done_Size( T2_Size  size )
-  {
-    UNUSED( size );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T2_Reset_Size                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Resets a OpenType size when resolutions and character dimensions   */
-  /*    have been changed.                                                 */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_DEF
-  FT_Error  T2_Reset_Size( T2_Size  size )
-  {
-    T2_Face           face    = (T2_Face)size->face;
-    FT_Size_Metrics*  metrics = &size->metrics;
-
-
-    if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
-      return T2_Err_Invalid_PPem;
-
-    /* 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;
-
-    return T2_Err_Ok;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T2_Init_GlyphSlot                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The OpenType glyph slot initializer.                               */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    slot :: The glyph record to build.                                 */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_FUNC
-  FT_Error  T2_Init_GlyphSlot( T2_GlyphSlot  slot )
-  {
-    FT_Library  library = slot->root.face->driver->library;
-
-
-    slot->max_points         = 0;
-    slot->max_contours       = 0;
-    slot->root.bitmap.buffer = 0;
-
-    return FT_Outline_New( library, 0, 0, &slot->root.outline );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T2_Done_GlyphSlot                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The OpenType glyph slot finalizer.                                 */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    slot :: A handle to the glyph slot object.                         */
-  /*                                                                       */
-  LOCAL_FUNC
-  void  T2_Done_GlyphSlot( T2_GlyphSlot  slot )
-  {
-    FT_Library  library = slot->root.face->driver->library;
-    FT_Memory   memory  = library->memory;
-
-
-    if ( slot->root.flags & ft_glyph_own_bitmap )
-      FREE( slot->root.bitmap.buffer );
-
-    FT_Outline_Done( library, &slot->root.outline );
-    return;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
   /*    T2_Init_Driver                                                     */
   /*                                                                       */
   /* <Description>                                                         */
@@ -342,7 +188,7 @@
   /*    driver :: A handle to the target driver object.                    */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  T2_Init_Driver( T2_Driver  driver )
--- a/src/cff/t2objs.h
+++ b/src/cff/t2objs.h
@@ -69,9 +69,6 @@
     FT_Bool          hint;
     FT_Bool          scaled;
 
-    FT_Int           max_points;
-    FT_Int           max_contours;
-
     FT_Fixed         x_scale;
     FT_Fixed         y_scale;
 
@@ -118,31 +115,6 @@
 
   LOCAL_DEF
   void  T2_Done_Face( T2_Face  face );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Size functions                                                        */
-  /*                                                                       */
-  LOCAL_DEF
-  FT_Error  T2_Init_Size( T2_Size  size );
-
-  LOCAL_DEF
-  void  T2_Done_Size( T2_Size  size );
-
-  LOCAL_DEF
-  FT_Error  T2_Reset_Size( T2_Size  size );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* GlyphSlot functions                                                   */
-  /*                                                                       */
-  LOCAL_DEF
-  FT_Error  T2_Init_GlyphSlot( T2_GlyphSlot  slot );
-
-  LOCAL_DEF
-  void  T2_Done_GlyphSlot( T2_GlyphSlot  slot );
 
 
   /*************************************************************************/
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -157,9 +157,13 @@
 
     if ( glyph )
     {
-      builder->base         = glyph->root.outline;
-      builder->max_points   = glyph->max_points;
-      builder->max_contours = glyph->max_contours;
+      FT_GlyphLoader*  loader = glyph->root.loader;
+      
+      builder->loader  = loader;
+      builder->base    = &loader->base.outline;
+      builder->current = &loader->current.outline;
+      
+      FT_GlyphLoader_Rewind(loader);
     }
 
     if ( size )
@@ -176,9 +180,6 @@
     builder->advance.x      = 0;
     builder->advance.y      = 0;
 
-    builder->base.n_points   = 0;
-    builder->base.n_contours = 0;
-    builder->current         = builder->base;
   }
 
 
@@ -200,13 +201,8 @@
   {
     T1_GlyphSlot  glyph = builder->glyph;
 
-
     if ( glyph )
-    {
-      glyph->root.outline = builder->base;
-      glyph->max_points   = builder->max_points;
-      glyph->max_contours = builder->max_contours;
-    }
+      glyph->root.outline = *builder->base;
   }
 
 
@@ -236,42 +232,7 @@
   FT_Error  check_points( CID_Builder*  builder,
                           FT_Int        count )
   {
-    FT_Outline*  base    = &builder->base;
-    FT_Outline*  outline = &builder->current;
-
-
-    if ( !builder->load_points )
-      return T1_Err_Ok;
-
-    count += base->n_points + outline->n_points;
-
-    /* realloc points table if necessary */
-    if ( count >= builder->max_points )
-    {
-      FT_Error   error;
-      FT_Memory  memory    = builder->memory;
-      FT_Int     increment = outline->points - base->points;
-      FT_Int     current   = builder->max_points;
-
-
-      while ( builder->max_points < count )
-        builder->max_points += 8;
-
-      if ( REALLOC_ARRAY( base->points, current,
-                          builder->max_points, FT_Vector )  ||
-
-           REALLOC_ARRAY( base->tags, current,
-                          builder->max_points, FT_Byte )    )
-      {
-        builder->error = error;
-        return error;
-      }
-
-      outline->points = base->points + increment;
-      outline->tags  = base->tags  + increment;
-    }
-
-    return T1_Err_Ok;
+    return FT_GlyphLoader_Check_Points( builder->loader, count, 0 );
   }
 
 
@@ -282,9 +243,8 @@
                    FT_Pos        y,
                    FT_Byte       flag )
   {
-    FT_Outline*  outline = &builder->current;
+    FT_Outline*  outline = builder->current;
 
-
     if ( builder->load_points )
     {
       FT_Vector*  point   = outline->points + outline->n_points;
@@ -310,7 +270,6 @@
   {
     FT_Error  error;
 
-
     error = check_points( builder, 1 );
     if ( !error )
       add_point( builder, x, y, 1 );
@@ -323,10 +282,9 @@
   static
   FT_Error  add_contour( CID_Builder*  builder )
   {
-    FT_Outline*  base    = &builder->base;
-    FT_Outline*  outline = &builder->current;
+    FT_Outline*  outline = builder->current;
+    FT_Error     error;
 
-
     if ( !builder->load_points )
     {
       outline->n_contours++;
@@ -333,34 +291,15 @@
       return T1_Err_Ok;
     }
 
-    /* realloc contours array if necessary */
-    if ( base->n_contours + outline->n_contours >= builder->max_contours &&
-         builder->load_points )
+    error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 );
+    if (!error)
     {
-      FT_Error  error;
-      FT_Memory memory    = builder->memory;
-      FT_Int    increment = outline->contours - base->contours;
-      FT_Int    current   = builder->max_contours;
-
-
-      builder->max_contours += 4;
-
-      if ( REALLOC_ARRAY( base->contours,
-                          current, builder->max_contours, FT_Short ) )
-      {
-        builder->error = error;
-        return error;
-      }
-
-      outline->contours = base->contours + increment;
+      if ( outline->n_contours > 0 )
+        outline->contours[outline->n_contours - 1] = outline->n_points - 1;
+  
+      outline->n_contours++;
     }
-
-    if ( outline->n_contours > 0 )
-      outline->contours[outline->n_contours - 1] = outline->n_points - 1;
-
-    outline->n_contours++;
-
-    return T1_Err_Ok;
+    return error;
   }
 
 
@@ -375,7 +314,6 @@
     {
       FT_Error  error;
 
-
       builder->path_begun = 1;
       error = add_contour( builder );
       if ( error )
@@ -390,9 +328,8 @@
   static
   void  close_contour( CID_Builder*  builder )
   {
-    FT_Outline*  outline = &builder->current;
+    FT_Outline*  outline = builder->current;
 
-
     if ( outline->n_contours > 0 )
       outline->contours[outline->n_contours - 1] = outline->n_points - 1;
   }
@@ -473,7 +410,7 @@
   /*    achar    :: The accent character's StandardEncoding charcode.      */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    Type 1 error code.  0 means success.                               */
   /*                                                                       */
   static
   FT_Error  t1operator_seac( CID_Decoder*  decoder,
@@ -485,11 +422,10 @@
   {
     FT_Error     error;
     FT_Int       bchar_index, achar_index, n_base_points;
-    FT_Outline*  cur  = &decoder->builder.current;
-    FT_Outline*  base = &decoder->builder.base;
+    FT_Outline*  cur  = decoder->builder.current;
+    FT_Outline*  base = decoder->builder.base;
     FT_Vector    left_bearing, advance;
 
-
     bchar_index = bchar;
     achar_index = achar;
 
@@ -499,44 +435,22 @@
       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->tags       = base->tags     + base->n_points;
-    cur->contours   = base->contours + base->n_contours;
 
-    error = cid_load_glyph( decoder, bchar_index );
-    if ( error )
-      return error;
-
-    n_base_points = cur->n_points;
-
+    /* if we are trying to load a composite glyph, do not load the */
+    /* accent character and return the array of subglyphs.         */
     if ( decoder->builder.no_recurse )
     {
-      /* if we are trying to load a composite glyph, do not load the */
-      /* accent character and return the array of subglyphs.         */
 
-      FT_GlyphSlot  glyph = (FT_GlyphSlot)decoder->builder.glyph;
-      FT_SubGlyph*  subg;
+      FT_GlyphSlot     glyph = (FT_GlyphSlot)decoder->builder.glyph;
+      FT_GlyphLoader*  loader = glyph->loader;
+      FT_SubGlyph*     subg;
 
-
       /* reallocate subglyph array if necessary */
-      if ( glyph->max_subglyphs < 2 )
-      {
-        FT_Memory  memory = decoder->builder.face->root.memory;
+      error = FT_GlyphLoader_Check_Subglyphs( loader, 2 );
+      if (error) goto Exit;
+      
+      subg = loader->current.subglyphs;
 
-
-        if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs,
-                            2, FT_SubGlyph ) )
-          return error;
-
-        glyph->max_subglyphs = 2;
-      }
-
-      subg = glyph->subglyphs;
-
       /* subglyph 0 = base character */
       subg->index = bchar_index;
       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
@@ -554,8 +468,20 @@
       /* set up remaining glyph fields */
       glyph->num_subglyphs = 2;
       glyph->format        = ft_glyph_format_composite;
+      
+      loader->current.num_subglyphs = 2;
     }
-    else
+
+    /* First load `bchar' in builder */
+    /* now load the unscaled outline */
+    if (decoder->builder.loader)    
+      FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
+
+    error = cid_load_glyph( decoder, bchar_index );  /* load one glyph */
+    if ( error ) goto Exit;
+
+    n_base_points = cur->n_points;
+
     {
       /* save the left bearing and width of the base character */
       /* as they will be erased by the next load.              */
@@ -568,27 +494,10 @@
 
       /* 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->tags       = base->tags     + base->n_points;
-      cur->contours   = base->contours + base->n_contours;
-
       error = cid_load_glyph( decoder, achar_index );
       if ( error )
         return error;
 
-      /* adjust contours in accented character outline */
-      if ( decoder->builder.load_points )
-      {
-        FT_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 */
 
@@ -597,10 +506,16 @@
 
       /* Finally, move the accent */
       if ( decoder->builder.load_points )
-        FT_Outline_Translate( cur, adx - asb, ady );
+      {
+        FT_Outline  dummy;
+        
+        dummy.n_points = base->n_points - n_base_points;
+        dummy.points   = base->points   + n_base_points;
+        FT_Outline_Translate( &dummy, adx - asb, ady );
+      }
     }
-
-    return T1_Err_Ok;
+  Exit:
+    return error;
   }
 
 
@@ -626,7 +541,7 @@
   /*    charstring_len   :: The length in bytes of the charstring stream.  */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    Type1 error code.  0 means success.                                */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  CID_Parse_CharStrings( CID_Decoder*  decoder,
@@ -654,7 +569,7 @@
     ip    = zone->cursor = zone->base;
 
     error   = T1_Err_Ok;
-    outline = &builder->current;
+    outline = builder->current;
 
     x = builder->pos_x;
     y = builder->pos_y;
@@ -1011,8 +926,7 @@
           close_contour( builder );
 
           /* add current outline to the glyph slot */
-          builder->base.n_points   += builder->current.n_points;
-          builder->base.n_contours += builder->current.n_contours;
+          FT_GlyphLoader_Add( builder->loader );
 
           /* return now! */
           FT_TRACE4(( "\n\n" ));
@@ -1535,7 +1449,7 @@
         {
           /* scale the outline and the metrics */
           FT_Int       n;
-          FT_Outline*  cur     = &decoder.builder.base;
+          FT_Outline*  cur     = &glyph->root.outline;
           FT_Vector*   vec     = cur->points;
           FT_Fixed     x_scale = glyph->x_scale;
           FT_Fixed     y_scale = glyph->y_scale;
--- a/src/cid/cidgload.h
+++ b/src/cid/cidgload.h
@@ -80,34 +80,31 @@
   /*                                                                       */
   typedef struct  CID_Builder_
   {
-    FT_Memory     memory;
-    CID_Face      face;
-    T1_GlyphSlot  glyph;
+    FT_Memory        memory;
+    CID_Face         face;
+    T1_GlyphSlot     glyph;
+    FT_GlyphLoader*  loader;
+    FT_Outline*      base;
+    FT_Outline*      current;
 
-    FT_Outline    current;       /* the current glyph outline   */
-    FT_Outline    base;          /* the composite glyph outline */
+    FT_Vector        last;
 
-    FT_Int        max_points;    /* capacity of base outline in points   */
-    FT_Int        max_contours;  /* capacity of base outline in contours */
+    FT_Fixed         scale_x;
+    FT_Fixed         scale_y;
 
-    FT_Vector     last;
+    FT_Pos           pos_x;
+    FT_Pos           pos_y;
 
-    FT_Fixed      scale_x;
-    FT_Fixed      scale_y;
+    FT_Vector        left_bearing;
+    FT_Vector        advance;
 
-    FT_Pos        pos_x;
-    FT_Pos        pos_y;
+    FT_BBox          bbox;          /* bounding box */
+    FT_Bool          path_begun;
+    FT_Bool          load_points;
+    FT_Bool          no_recurse;
 
-    FT_Vector     left_bearing;
-    FT_Vector     advance;
-
-    FT_BBox       bbox;          /* bounding box */
-    FT_Bool       path_begun;
-    FT_Bool       load_points;
-    FT_Bool       no_recurse;
-
-    FT_Error      error;         /* only used for memory errors */
-    FT_Bool       metrics_only;
+    FT_Error         error;         /* only used for memory errors */
+    FT_Bool          metrics_only;
 
   } CID_Builder;
 
--- a/src/cid/cidobjs.c
+++ b/src/cid/cidobjs.c
@@ -37,97 +37,6 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /*                           SIZE  FUNCTIONS                             */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    CID_Done_Size                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The CID size object finalizer.                                     */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
-  LOCAL_FUNC
-  void  CID_Done_Size( T1_Size  size )
-  {
-    UNUSED( size );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    CID_Init_Size                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes a new CID size object.                                 */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size :: A handle to the size object.                               */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_DEF
-  FT_Error  CID_Init_Size( T1_Size  size )
-  {
-    size->valid = 0;
-
-    return T1_Err_Ok;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    CID_Reset_Size                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Resets a OpenType size when resolutions and character dimensions   */
-  /*    have been changed.                                                 */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_FUNC
-  FT_Error  CID_Reset_Size( T1_Size  size )
-  {
-    /* recompute ascender, descender, etc. */
-    CID_Face          face    = (CID_Face)size->root.face;
-    FT_Size_Metrics*  metrics = &size->root.metrics;
-
-
-    if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
-      return T1_Err_Invalid_Argument;
-
-    /* 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;
-
-    return T1_Err_Ok;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
   /*                           FACE  FUNCTIONS                             */
   /*                                                                       */
   /*************************************************************************/
@@ -201,7 +110,7 @@
   /*    face       :: The newly built face object.                         */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    Type1 error code.  0 means success.                                */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  CID_Init_Face( FT_Stream      stream,
@@ -225,13 +134,13 @@
     if ( !psnames )
     {
       /* look-up the PSNames driver */
-      FT_Driver  psnames_driver;
+      FT_Module  psnames_module;
 
-
-      psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" );
-      if ( psnames_driver )
+      psnames_module = FT_Get_Module( face->root.driver->root.library,
+                                      "psnames" );
+      if (psnames_module)                                      
         face->psnames = (PSNames_Interface*)
-                          (psnames_driver->interface.format_interface);
+                          (psnames_module->clazz->module_interface);
     }
 
     /* open the tokenizer; this will also check the font format */
@@ -423,60 +332,6 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    CID_Done_GlyphSlot                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The CID glyph slot finalizer.                                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    slot :: A handle to the glyph slot object.                         */
-  /*                                                                       */
-  LOCAL_FUNC
-  void  CID_Done_GlyphSlot( T1_GlyphSlot  glyph )
-  {
-    FT_Memory  memory  = glyph->root.face->memory;
-    FT_Library library = glyph->root.face->driver->library;
-
-
-	/* the bitmaps are created on demand */
-	FREE( glyph->root.bitmap.buffer );
-    FT_Outline_Done( library, &glyph->root.outline );
-
-    return;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    CID_Init_GlyphSlot                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The CID glyph slot initializer.                                    */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    slot :: The glyph record to build.                                 */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_FUNC
-  FT_Error  CID_Init_GlyphSlot( T1_GlyphSlot  glyph )
-  {
-    FT_Library  library = glyph->root.face->driver->library;
-
-
-    glyph->max_points         = 0;
-    glyph->max_contours       = 0;
-    glyph->root.bitmap.buffer = 0;
-
-    return FT_Outline_New( library, 0, 0, &glyph->root.outline );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
   /*    CID_Init_Driver                                                    */
   /*                                                                       */
   /* <Description>                                                         */
@@ -486,7 +341,7 @@
   /*    driver :: A handle to the target driver object.                    */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    Type1 error code.  0 means success.                                */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  CID_Init_Driver( T1_Driver  driver )
@@ -493,7 +348,7 @@
   {
     UNUSED( driver );
 
-    return T1_Err_Ok;
+    return FT_Err_Ok;
   }
 
 
--- a/src/cid/cidobjs.h
+++ b/src/cid/cidobjs.h
@@ -95,14 +95,10 @@
   {
     FT_SizeRec      root;
     FT_Bool         valid;
-    T1_Size_Hints*  hints;  /* defined in the hinter.  This allows */
-                            /* us to experiment with different     */
-                            /* hinting schemes without having to   */
-                            /* change `cidobjs' each time.         */
+
   } T1_SizeRec;
 
 
-
   typedef struct  T1_GlyphSlotRec_
   {
     FT_GlyphSlotRec  root;
@@ -110,14 +106,9 @@
     FT_Bool          hint;
     FT_Bool          scaled;
 
-    FT_Int           max_points;
-    FT_Int           max_contours;
-
     FT_Fixed         x_scale;
     FT_Fixed         y_scale;
 
-    T1_Glyph_Hints*  hints;  /* defined in the hinter */
-
   } T1_GlyphSlotRec;
 
 
@@ -130,23 +121,6 @@
 
   LOCAL_DEF
   void  CID_Done_Face( CID_Face  face );
-
-
-  LOCAL_DEF
-  FT_Error  CID_Init_Size( T1_Size  size );
-
-  LOCAL_DEF
-  void  CID_Done_Size( T1_Size  size );
-
-  LOCAL_DEF
-  FT_Error  CID_Reset_Size( T1_Size  size );
-
-
-  LOCAL_DEF
-  FT_Error  CID_Init_GlyphSlot( T1_GlyphSlot  slot );
-
-  LOCAL_DEF
-  void  CID_Done_GlyphSlot( T1_GlyphSlot  slot );
 
 
   LOCAL_DEF
--- a/src/cid/cidparse.c
+++ b/src/cid/cidparse.c
@@ -67,7 +67,7 @@
   /*              reallocations.                                           */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    Type1 error code.  0 means success.                                */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  T1_New_Table( T1_Table*  table,
@@ -157,7 +157,7 @@
   /*    length :: The length in bytes of the source object.                */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.  An error is returned if    */
+  /*    Type1 error code.  0 means success.  An error is returned if       */
   /*    reallocation fails.                                                */
   /*                                                                       */
   LOCAL_FUNC
@@ -934,7 +934,7 @@
 
     if ( strncmp( stream->cursor, "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
     {
-      FT_ERROR(( "[not a valid CID-keyed font]\n" ));
+      FT_TRACE2(( "[not a valid CID-keyed font]\n" ));
       error = FT_Err_Unknown_File_Format;
     }
 
--- a/src/cid/cidriver.c
+++ b/src/cid/cidriver.c
@@ -37,36 +37,9 @@
 #define FT_COMPONENT  trace_ciddriver
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Get_Interface                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Each driver can provide one or more extensions to the base         */
-  /*    FreeType API.  These can be used to access format specific         */
-  /*    features (e.g., all TrueType/OpenType resources share a common     */
-  /*    file structure and common tables which can be accessed through the */
-  /*    `sfnt' interface), or more simply generic ones (e.g., the          */
-  /*    `postscript names' interface which can be used to retrieve the     */
-  /*     PostScript name of a given glyph index).                          */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    driver    :: A handle to a driver object.                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    interface :: A string designing the interface.  Examples are       */
-  /*                 `sfnt', `post_names', `charmaps', etc.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    A typeless pointer to the extension's interface (normally a table  */
-  /*    of function pointers).  Returns NULL if the requested extension    */
-  /*    isn't available (i.e., wasn't compiled in the driver at build      */
-  /*    time).                                                             */
-  /*                                                                       */
   static
-  FTDriver_Interface  Get_Interface( FT_Driver         driver,
-                                     const FT_String*  interface )
+  FT_Module_Interface   CID_Get_Interface( FT_Driver         driver,
+                                           const FT_String*  interface )
   {
     UNUSED( driver );
     UNUSED( interface );
@@ -75,154 +48,39 @@
   }
 
 
-#ifndef T1_CONFIG_OPTION_NO_AFM
+#ifdef xxxT1_CONFIG_OPTION_NO_AFM
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Get_Kerning                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A driver method used to return the kerning vector between two      */
-  /*    glyphs of the same face.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face        :: A handle to the source face object.                 */
-  /*                                                                       */
-  /*    left_glyph  :: The index of the left glyph in the kern pair.       */
-  /*                                                                       */
-  /*    right_glyph :: The index of the right glyph in the kern pair.      */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    kerning     :: The kerning vector.  This is in font units for      */
-  /*                   scalable formats, and in pixels for fixed-sizes     */
-  /*                   formats.                                            */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    Only horizontal layouts (left-to-right & right-to-left) are        */
-  /*    supported by this function.  Other layouts, or more sophisticated  */
-  /*    kernings are out of scope of this method (the basic driver         */
-  /*    interface is meant to be simple).                                  */
-  /*                                                                       */
-  /*    They can be implemented by format-specific interfaces.             */
-  /*                                                                       */
   static
-  FT_Error  Get_Kerning( T1_Face     face,
-                         FT_UInt     left_glyph,
-                         FT_UInt     right_glyph,
-                         FT_Vector*  kerning )
+  FT_Error  cid_Get_Kerning( T1_Face     face,
+                             FT_UInt     left_glyph,
+                             FT_UInt     right_glyph,
+                             FT_Vector*  kerning )
   {
-#if 0
-
     T1_AFM*  afm;
 
-#endif
 
-
     kerning->x = 0;
     kerning->y = 0;
 
-#if 0
-
     afm = (T1_AFM*)face->afm_data;
     if ( afm )
       CID_Get_Kerning( afm, left_glyph, right_glyph, kerning );
 
-#endif /* 0 */
-
     return T1_Err_Ok;
   }
 
 
-#endif /* !T1_CONFIG_OPTION_NO_AFM */
+#endif /* xxxT1_CONFIG_OPTION_NO_AFM */
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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.                              */
-  /*                                                                       */
-  /*    horz_resolution :: The horizontal resolution of the output device. */
-  /*                                                                       */
-  /*    vert_resolution :: The vertical resolution of the output device.   */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size            :: A handle to the target size object.             */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  static
-  FT_Error  Set_Char_Sizes( T1_Size     size,
-                            FT_F26Dot6  char_width,
-                            FT_F26Dot6  char_height,
-                            FT_UInt     horz_resolution,
-                            FT_UInt     vert_resolution )
-  {
-    UNUSED( char_width );
-    UNUSED( char_height );
-    UNUSED( horz_resolution );
-    UNUSED( vert_resolution );
 
-    size->valid = FALSE;
-    return CID_Reset_Size( size );
-  }
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    Set_Pixel_Sizes                                                    */
+  /*    cid_get_char_index                                                 */
   /*                                                                       */
   /* <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
-  FT_Error  Set_Pixel_Sizes( T1_Size  size,
-                             FT_Int   pixel_width,
-                             FT_Int   pixel_height )
-  {
-    UNUSED( pixel_width );
-    UNUSED( pixel_height );
-
-    size->valid = FALSE;
-    return CID_Reset_Size( size );
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Get_Char_Index                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
   /*    Uses a charmap to return a given character code's glyph index.     */
   /*                                                                       */
   /* <Input>                                                               */
@@ -233,14 +91,13 @@
   /*    Glyph index.  0 means `undefined character code'.                  */
   /*                                                                       */
   static
-  FT_UInt  Get_Char_Index( FT_CharMap  charmap,
-                           FT_Long     charcode )
+  FT_UInt  CID_Get_Char_Index( FT_CharMap  charmap,
+                               FT_Long     charcode )
   {
     T1_Face             face;
     FT_UInt             result = 0;
     PSNames_Interface*  psnames;
 
-
     face = (T1_Face)charmap->face;
     psnames = (PSNames_Interface*)face->psnames;
     if ( psnames )
@@ -316,75 +173,55 @@
   }
 
 
-  const FT_DriverInterface  t1cid_driver_interface =
+
+  const FT_Driver_Class  t1cid_driver_class =
   {
-    sizeof( FT_DriverRec ),
+    /* firs of all, the FT_Module_Class fields */
+    {
+      ft_module_font_driver | ft_module_driver_scalable,
+      sizeof( FT_DriverRec ),
+      "t1cid",   /* module name           */
+      0x10000,   /* version 1.0 of driver */
+      0x20000,   /* requires FreeType 2.0 */
+      
+      0,
+      
+      (FT_Module_Constructor)   CID_Init_Driver,
+      (FT_Module_Destructor)    CID_Done_Driver,
+      (FT_Module_Requester)     CID_Get_Interface
+    },
+
+    /* then the other font drivers fields */
     sizeof( CID_FaceRec ),
     sizeof( T1_SizeRec ),
     sizeof( T1_GlyphSlotRec ),
 
-    "t1cid",
-    100,
-    200,
+    (FTDriver_initFace)      CID_Init_Face,
+    (FTDriver_doneFace)      CID_Done_Face,
 
-    0,   /* format interface */
+    (FTDriver_initSize)      0,
+    (FTDriver_doneSize)      0,
+    (FTDriver_initGlyphSlot) 0,
+    (FTDriver_doneGlyphSlot) 0,
 
-    (FTDriver_initDriver)   CID_Init_Driver,
-    (FTDriver_doneDriver)   CID_Done_Driver,
+    (FTDriver_setCharSizes)  0,
+    (FTDriver_setPixelSizes) 0,
 
-    (FTDriver_getInterface) Get_Interface,
+    (FTDriver_loadGlyph)     CID_Load_Glyph,
+    (FTDriver_getCharIndex)  CID_Get_Char_Index,
 
-    (FTDriver_initFace)     CID_Init_Face,
-    (FTDriver_doneFace)     CID_Done_Face,
-
-#ifdef T1_CONFIG_OPTION_NO_AFM
-    (FTDriver_getKerning)   0,
+#ifndef xxxxT1_CONFIG_OPTION_NO_AFM
+    (FTDriver_getKerning)    0,
+    (FTDriver_attachFile)    0,
 #else
-    (FTDriver_getKerning)   Get_Kerning,
+    (FTDriver_getKerning)    cid_Get_Kerning,
+    (FTDriver_attachFile)    CID_Read_AFM,
 #endif
 
-    (FTDriver_initSize)     CID_Init_Size,
-    (FTDriver_doneSize)     CID_Done_Size,
-    (FTDriver_setCharSizes) Set_Char_Sizes,
-    (FTDriver_setPixelSizes)Set_Pixel_Sizes,
-
-    (FTDriver_initGlyphSlot)CID_Init_GlyphSlot,
-    (FTDriver_doneGlyphSlot)CID_Done_GlyphSlot,
-    (FTDriver_loadGlyph)    CID_Load_Glyph,
-
-    (FTDriver_getCharIndex) Get_Char_Index,
+    (FTDriver_getAdvances)  0
   };
 
 
-#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    getDriverInterface                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This function is used when compiling the CID 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 CID's driver generic interface.  The            */
-  /*    format-specific interface can then be retrieved through the method */
-  /*    interface->get_format_interface.                                   */
-  /*                                                                       */
-  EXPORT_FUNC( FT_DriverInterface* )  getDriverInterface( void )
-  {
-    return &t1cid_driver_interface;
-  }
-
-
-#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
 
 
 /* END */
--- a/src/cid/cidriver.h
+++ b/src/cid/cidriver.h
@@ -22,7 +22,7 @@
 #include <cidobjs.h>
 #include <freetype/internal/t1errors.h>
 
-  FT_EXPORT_VAR( const  FT_DriverInterface )  t1cid_driver_interface;
+  FT_EXPORT_VAR( const  FT_Driver_Class )  t1cid_driver_class;
 
 #endif /* CIDRIVER_H */
 
--- a/src/cid/module.mk
+++ b/src/cid/module.mk
@@ -1,6 +1,6 @@
 make_module_list: add_type1cid_driver
 
 add_type1cid_driver:
-	$(OPEN_DRIVER)t1cid_driver_interface$(CLOSE_DRIVER)
+	$(OPEN_DRIVER)t1cid_driver_class$(CLOSE_DRIVER)
 	$(ECHO_DRIVER)cid       $(ECHO_DRIVER_DESC)Postscript CID-keyed fonts, no known extension$(ECHO_DRIVER_DONE)
 # EOF
--- a/src/psnames/module.mk
+++ b/src/psnames/module.mk
@@ -1,7 +1,7 @@
-make_module_list: add_psnames_driver
+make_module_list: add_psnames_module
 
-add_psnames_driver:
-	$(OPEN_DRIVER)psnames_driver_interface$(CLOSE_DRIVER)
+add_psnames_module:
+	$(OPEN_DRIVER)psnames_module_class$(CLOSE_DRIVER)
 	$(ECHO_DRIVER)psnames   $(ECHO_DRIVER_DESC)Postscript & Unicode Glyph name handling$(ECHO_DRIVER_DONE)
 
 # EOF
--- a/src/psnames/psdriver.h
+++ b/src/psnames/psdriver.h
@@ -1,10 +1,10 @@
 /***************************************************************************/
 /*                                                                         */
-/*  psdriver.h                                                             */
+/*  psmodule.h                                                             */
 /*                                                                         */
-/*    High-level PSNames driver interface (specification).                 */
+/*    High-level PSNames module interface (specification).                 */
 /*                                                                         */
-/*  Copyright 1996-2000 by                                                 */
+/*  Copyright 1996-1999 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -19,13 +19,11 @@
 #ifndef PSDRIVER_H
 #define PSDRIVER_H
 
+#include <freetype/ftmodule.h>
 
-#include <freetype/internal/ftdriver.h>
+  FT_EXPORT_VAR(const FT_Module_Class)  psnames_module_class;
 
-  FT_EXPORT_VAR( const FT_DriverInterface )  psnames_driver_interface;
-
-
-#endif /* PSDRIVER_H */
+#endif /* PSMODULE_H */
 
 
 /* END */
--- a/src/psnames/psnames.c
+++ b/src/psnames/psnames.c
@@ -1,23 +1,2 @@
-/***************************************************************************/
-/*                                                                         */
-/*  psnames.c                                                              */
-/*                                                                         */
-/*    FreeType PSNames driver component (body only).                       */
-/*                                                                         */
-/*  Copyright 1996-2000 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <psdriver.c>
-
-
-/* END */
+#include <psmodule.c>
--- a/src/psnames/rules.mk
+++ b/src/psnames/rules.mk
@@ -31,7 +31,7 @@
 
 # PSNames driver sources (i.e., C files)
 #
-PSNAMES_DRV_SRC := $(PSNAMES_DIR_)psdriver.c
+PSNAMES_DRV_SRC := $(PSNAMES_DIR_)psmodule.c
 
 
 # PSNames driver headers
@@ -50,7 +50,7 @@
 
 # PSNames driver source file for single build
 #
-PSNAMES_DRV_SRC_S := $(PSNAMES_DIR_)psdriver.c
+PSNAMES_DRV_SRC_S := $(PSNAMES_DIR_)psmodule.c
 
 
 # PSNames driver - single object
--- /dev/null
+++ b/src/renderer/ftgrays.c
@@ -1,0 +1,1952 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftgrays.c                                                              */
+/*                                                                         */
+/*    A new `perfect' anti-aliasing renderer (body).                       */
+/*                                                                         */
+/*  Copyright 2000 by                                                      */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  This file can be compiled without the rest of the FreeType engine,   */
+  /*  by defining the _STANDALONE_ macro when compiling it.  You also need */
+  /*  to put the files `ftgrays.h' and `ftimage.h' into the current        */
+  /*  compilation directory.  Typically, you could do something like       */
+  /*                                                                       */
+  /*  - copy `src/base/ftgrays.c' to your current directory                */
+  /*                                                                       */
+  /*  - copy `include/freetype/ftimage.h' and                              */
+  /*    `include/freetype/ftgrays.h' to the same directory                 */
+  /*                                                                       */
+  /*  - compile `ftgrays' with the _STANDALONE_ macro defined, as in       */
+  /*                                                                       */
+  /*      cc -c -D_STANDALONE_ ftgrays.c                                   */
+  /*                                                                       */
+  /*  The renderer can be initialized with a call to                       */
+  /*  `ft_grays_raster.grays_raster_new'; an anti-aliased bitmap can be    */
+  /*  generated with a call to `ft_grays_raster.grays_raster_render'.      */
+  /*                                                                       */
+  /*  See the comments and documentation in the file `ftimage.h' for       */
+  /*  more details on how the raster works.                                */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  This is a new anti-aliasing scan-converter for FreeType 2.  The      */
+  /*  algorithm used here is _very_ different from the one in the standard */
+  /*  `ftraster' module.  Actually, `ftgrays' computes the _exact_         */
+  /*  coverage of the outline on each pixel cell.                          */
+  /*                                                                       */
+  /*  It is based on ideas that I initially found in Raph Levien's         */
+  /*  excellent LibArt graphics library (see http://www.levien.com/libart  */
+  /*  for more information, though the web pages do not tell anything      */
+  /*  about the renderer; you'll have to dive into the source code to      */
+  /*  understand how it works).                                            */
+  /*                                                                       */
+  /*  Note, however, that this is a _very_ different implementation        */
+  /*  compared Raph's.  Coverage information is stored in a very different */
+  /*  way, and I don't use sorted vector paths.  Also, it doesn't use      */
+  /*  floating point values.                                               */
+  /*                                                                       */
+  /*  This renderer has the following advantages:                          */
+  /*                                                                       */
+  /*  - It doesn't need an intermediate bitmap.  Instead, one can supply   */
+  /*    a callback function that will be called by the renderer to draw    */
+  /*    gray spans on any target surface.  You can thus do direct          */
+  /*    composition on any kind of bitmap, provided that you give the      */
+  /*    renderer the right callback.                                       */
+  /*                                                                       */
+  /*  - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on  */
+  /*    each pixel cell                                                    */
+  /*                                                                       */
+  /*  - It performs a single pass on the outline (the `standard' FT2       */
+  /*    renderer makes two passes).                                        */
+  /*                                                                       */
+  /*  - It can easily be modified to render to _any_ number of gray levels */
+  /*    cheaply.                                                           */
+  /*                                                                       */
+  /*  - For small (< 20) pixel sizes, it is faster than the standard       */
+  /*    renderer.                                                          */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include <string.h>             /* for memcpy() */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_aaraster
+
+
+#define ErrRaster_Invalid_Outline  -1
+
+
+#ifdef _STANDALONE_
+
+
+#include "ftimage.h"
+#include "ftgrays.h"
+
+  /* This macro is used to indicate that a function parameter is unused. */
+  /* Its purpose is simply to reduce compiler warnings.  Note also that  */
+  /* simply defining it as `(void)x' doesn't avoid warnings with certain */
+  /* ANSI compilers (e.g. LCC).                                          */
+#define UNUSED( x )  (x) = (x)
+
+  /* Disable the tracing mechanism for simplicity -- developers can      */
+  /* activate it easily by redefining these two macros.                  */
+#ifndef FT_ERROR
+#define FT_ERROR( x )  do ; while ( 0 )     /* nothing */
+#endif
+
+#ifndef FT_TRACE
+#define FT_TRACE( x )  do ; while ( 0 )     /* nothing */
+#endif
+
+
+#else /* _STANDALONE_ */
+
+
+#include "ftgrays.h"
+#include <freetype/internal/ftobjs.h>  /* for UNUSED()                  */
+#include <freetype/internal/ftdebug.h> /* for FT_TRACE() and FT_ERROR() */
+#include <freetype/freetype.h>         /* for FT_Outline_Decompose()    */
+
+
+#endif /* _STANDALONE_ */
+
+
+  /* define this to dump debugging information */
+#define xxxDEBUG_GRAYS
+
+  /* as usual, for the speed hungry :-) */
+
+#ifndef FT_STATIC_RASTER
+
+
+#define RAS_ARG   PRaster  raster
+#define RAS_ARG_  PRaster  raster,
+
+#define RAS_VAR   raster
+#define RAS_VAR_  raster,
+
+#define ras       (*raster)
+
+
+#else /* FT_STATIC_RASTER */
+
+
+#define RAS_ARG   /* empty */
+#define RAS_ARG_  /* empty */
+#define RAS_VAR   /* empty */
+#define RAS_VAR_  /* empty */
+
+  static TRaster  ras;
+
+
+#endif /* FT_STATIC_RASTER */
+
+
+  /* must be at least 6 bits! */
+#define PIXEL_BITS  8
+
+#define ONE_PIXEL       ( 1L << PIXEL_BITS )
+#define PIXEL_MASK      ( -1L << PIXEL_BITS )
+#define TRUNC( x )      ( (x) >> PIXEL_BITS )
+#define SUBPIXELS( x )  ( (x) << PIXEL_BITS )
+#define FLOOR( x )      ( (x) & -ONE_PIXEL )
+#define CEILING( x )    ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
+#define ROUND( x )      ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
+
+#if PIXEL_BITS >= 6
+#define UPSCALE( x )    ( (x) << ( PIXEL_BITS - 6 ) )
+#define DOWNSCALE( x )  ( (x) >> ( PIXEL_BITS - 6 ) )
+#else
+#define UPSCALE( x )    ( (x) >> ( 6 - PIXEL_BITS ) )
+#define DOWNSCALE( x )  ( (x) << ( 6 - PIXEL_BITS ) )
+#endif
+
+  /* Define this if you want to use a more compact storage scheme.  This   */
+  /* increases the number of cells available in the render pool but slows  */
+  /* down the rendering a bit.  It is useful if you have a really tiny     */
+  /* render pool.                                                          */
+#define xxxGRAYS_COMPACT
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*   TYPE DEFINITIONS                                                    */
+  /*                                                                       */
+  typedef int   TScan;   /* integer scanline/pixel coordinate */
+  typedef long  TPos;    /* sub-pixel coordinate              */
+
+  /* maximal number of gray spans in a call to the span callback */
+#define FT_MAX_GRAY_SPANS  32
+
+
+#ifdef GRAYS_COMPACT
+
+  typedef struct  TCell_
+  {
+    short  x     : 14;
+    short  y     : 14;
+    int    cover : PIXEL_BITS + 2;
+    int    area  : PIXEL_BITS * 2 + 2;
+
+  } TCell, *PCell;
+
+#else /* GRAYS_COMPACT */
+
+  typedef struct  TCell_
+  {
+    TScan  x;
+    TScan  y;
+    int    cover;
+    int    area;
+
+  } TCell, *PCell;
+
+#endif /* GRAYS_COMPACT */
+
+
+  typedef struct TRaster_
+  {
+    PCell  cells;
+    int    max_cells;
+    int    num_cells;
+
+    TScan  min_ex, max_ex;
+    TScan  min_ey, max_ey;
+
+    int    area;
+    int    cover;
+    int    invalid;
+
+    TScan  ex, ey;
+    TScan  cx, cy;
+    TPos   x,  y;
+
+    TScan  last_ey;
+
+    FT_Vector   bez_stack[32 * 3];
+    int         lev_stack[32];
+
+    FT_Outline  outline;
+    FT_Bitmap   target;
+
+    FT_Span     gray_spans[FT_MAX_GRAY_SPANS];
+    int         num_gray_spans;
+
+    FT_Raster_Span_Func  render_span;
+    void*                render_span_data;
+    int                  span_y;
+
+    int    band_size;
+    int    band_shoot;
+    int    conic_level;
+    int    cubic_level;
+
+    void*  memory;
+
+  } TRaster, *PRaster;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Initialize the cells table.                                           */
+  /*                                                                       */
+  static
+  void  init_cells( RAS_ARG_ void*  buffer,
+                    long            byte_size )
+  {
+    ras.cells     = (PCell)buffer;
+    ras.max_cells = byte_size / sizeof ( TCell );
+    ras.num_cells = 0;
+    ras.area      = 0;
+    ras.cover     = 0;
+    ras.invalid   = 1;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Compute the outline bounding box.                                     */
+  /*                                                                       */
+  static
+  void  compute_cbox( RAS_ARG_ FT_Outline*  outline )
+  {
+    FT_Vector*  vec   = outline->points;
+    FT_Vector*  limit = vec + outline->n_points;
+
+
+    if ( outline->n_points <= 0 )
+    {
+      ras.min_ex = ras.max_ex = 0;
+      ras.min_ey = ras.max_ey = 0;
+      return;
+    }
+
+    ras.min_ex = ras.max_ex = vec->x;
+    ras.min_ey = ras.max_ey = vec->y;
+
+    vec++;
+
+    for ( ; vec < limit; vec++ )
+    {
+      TPos  x = vec->x;
+      TPos  y = vec->y;
+
+
+      if ( x < ras.min_ex ) ras.min_ex = x;
+      if ( x > ras.max_ex ) ras.max_ex = x;
+      if ( y < ras.min_ey ) ras.min_ey = y;
+      if ( y > ras.max_ey ) ras.max_ey = y;
+    }
+
+    /* truncate the bounding box to integer pixels */
+    ras.min_ex = ras.min_ex >> 6;
+    ras.min_ey = ras.min_ey >> 6;
+    ras.max_ex = ( ras.max_ex + 63 ) >> 6;
+    ras.max_ey = ( ras.max_ey + 63 ) >> 6;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Record the current cell in the table.                                 */
+  /*                                                                       */
+  static
+  int  record_cell( RAS_ARG )
+  {
+    PCell  cell;
+
+
+    if ( !ras.invalid && ( ras.area | ras.cover ) )
+    {
+      if ( ras.num_cells >= ras.max_cells )
+        return 1;
+
+      cell        = ras.cells + ras.num_cells++;
+      cell->x     = ras.ex - ras.min_ex;
+      cell->y     = ras.ey - ras.min_ey;
+      cell->area  = ras.area;
+      cell->cover = ras.cover;
+    }
+
+    return 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Set the current cell to a new position.                               */
+  /*                                                                       */
+  static
+  int  set_cell( RAS_ARG_ TScan  ex,
+                          TScan  ey )
+  {
+    int  invalid, record, clean;
+
+
+    /* Move the cell pointer to a new position.  We set the `invalid'      */
+    /* flag to indicate that the cell isn't part of those we're interested */
+    /* in during the render phase.  This means that:                       */
+    /*                                                                     */
+    /* . the new vertical position must be within min_ey..max_ey - 1.      */
+    /* . the new horizontal position must be strictly less than max_ex     */
+    /*                                                                     */
+    /* Note that if a cell is to the left of the clipping region, it is    */
+    /* actually set to the (min_ex-1) horizontal position.                 */
+
+    record  = 0;
+    clean   = 1;
+
+    invalid = ( ey < ras.min_ey || ey >= ras.max_ey || ex >= ras.max_ex );
+    if ( !invalid )
+    {
+      /* All cells that are on the left of the clipping region go to the */
+      /* min_ex - 1 horizontal position.                                 */
+      if ( ex < ras.min_ex )
+        ex = ras.min_ex - 1;
+
+      /* if our position is new, then record the previous cell */
+      if ( ex != ras.ex || ey != ras.ey )
+        record = 1;
+      else
+        clean = ras.invalid;  /* do not clean if we didn't move from */
+                              /* a valid cell                        */
+    }
+
+    /* record the previous cell if needed (i.e., if we changed the cell */
+    /* position, of changed the `invalid' flag)                         */
+    if ( ( ras.invalid != invalid || record ) && record_cell( RAS_VAR ) )
+      return 1;
+
+    if ( clean )
+    {
+      ras.area  = 0;
+      ras.cover = 0;
+    }
+
+    ras.invalid = invalid;
+    ras.ex      = ex;
+    ras.ey      = ey;
+    return 0;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Start a new contour at a given cell.                                  */
+  /*                                                                       */
+  static
+  void  start_cell( RAS_ARG_  TScan  ex,
+                              TScan  ey )
+  {
+    if ( ex < ras.min_ex )
+      ex = ras.min_ex - 1;
+
+    ras.area    = 0;
+    ras.cover   = 0;
+    ras.ex      = ex;
+    ras.ey      = ey;
+    ras.last_ey = SUBPIXELS( ey );
+    ras.invalid = 0;
+
+    (void)set_cell( RAS_VAR_ ex, ey );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Render a scanline as one or more cells.                               */
+  /*                                                                       */
+  static
+  int  render_scanline( RAS_ARG_  TScan  ey,
+                                  TPos   x1,
+                                  TScan  y1,
+                                  TPos   x2,
+                                  TScan  y2 )
+  {
+    TScan  ex1, ex2, fx1, fx2, delta;
+    long   p, first, dx;
+    int    incr, lift, mod, rem;
+
+
+    dx = x2 - x1;
+
+    ex1 = TRUNC( x1 ); /* if (ex1 >= ras.max_ex) ex1 = ras.max_ex-1; */
+    ex2 = TRUNC( x2 ); /* if (ex2 >= ras.max_ex) ex2 = ras.max_ex-1; */
+    fx1 = x1 - SUBPIXELS( ex1 );
+    fx2 = x2 - SUBPIXELS( ex2 );
+
+    /* trivial case.  Happens often */
+    if ( y1 == y2 )
+      return set_cell( RAS_VAR_ ex2, ey );
+
+    /* everything is located in a single cell.  That is easy! */
+    /*                                                        */
+    if ( ex1 == ex2 )
+    {
+      delta      = y2 - y1;
+      ras.area  += ( fx1 + fx2 ) * delta;
+      ras.cover += delta;
+      return 0;
+    }
+
+    /* ok, we'll have to render a run of adjacent cells on the same */
+    /* scanline...                                                  */
+    /*                                                              */
+    p     = ( ONE_PIXEL - fx1 ) * ( y2 - y1 );
+    first = ONE_PIXEL;
+    incr  = 1;
+
+    if ( dx < 0 )
+    {
+      p     = fx1 * ( y2 - y1 );
+      first = 0;
+      incr  = -1;
+      dx    = -dx;
+    }
+
+    delta = p / dx;
+    mod   = p % dx;
+    if ( mod < 0 )
+    {
+      delta--;
+      mod += dx;
+    }
+
+    ras.area  += ( fx1 + first ) * delta;
+    ras.cover += delta;
+
+    ex1 += incr;
+    if ( set_cell( RAS_VAR_ ex1, ey ) )
+      goto Error;
+    y1  += delta;
+
+    if ( ex1 != ex2 )
+    {
+      p     = ONE_PIXEL * ( y2 - y1 );
+      lift  = p / dx;
+      rem   = p % dx;
+      if ( rem < 0 )
+      {
+        lift--;
+        rem += dx;
+      }
+
+      mod -= dx;
+
+      while ( ex1 != ex2 )
+      {
+        delta = lift;
+        mod  += rem;
+        if ( mod >= 0 )
+        {
+          mod -= dx;
+          delta++;
+        }
+
+        ras.area  += ONE_PIXEL * delta;
+        ras.cover += delta;
+        y1        += delta;
+        ex1       += incr;
+        if ( set_cell( RAS_VAR_ ex1, ey ) )
+          goto Error;
+      }
+    }
+
+    delta      = y2 - y1;
+    ras.area  += ( fx2 + ONE_PIXEL - first ) * delta;
+    ras.cover += delta;
+
+    return 0;
+
+  Error:
+    return 1;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Render a given line as a series of scanlines.                         */
+  /*                                                                       */
+  static
+  int  render_line( RAS_ARG_ TPos  to_x,
+                             TPos  to_y )
+  {
+    TScan  ey1, ey2, fy1, fy2;
+    TPos   dx, dy, x, x2;
+    int    p, rem, mod, lift, delta, first, incr;
+
+
+    ey1 = TRUNC( ras.last_ey );
+    ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
+    fy1 = ras.y - ras.last_ey;
+    fy2 = to_y - SUBPIXELS( ey2 );
+
+    dx = to_x - ras.x;
+    dy = to_y - ras.y;
+
+    /* we should do something about the trivial case where dx == 0, */
+    /* as it happens very often!       XXXXX                        */
+
+    /* perform vertical clipping */
+    {
+      TScan  min, max;
+
+
+      min = ey1;
+      max = ey2;
+      if ( ey1 > ey2 )
+      {
+        min = ey2;
+        max = ey1;
+      }
+      if ( min >= ras.max_ey || max < ras.min_ey )
+        goto End;
+    }
+
+    /* everything is on a single scanline */
+    if ( ey1 == ey2 )
+    {
+      if ( render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ) )
+        goto Error;
+      goto End;
+    }
+
+    /* ok, we'll have to render several scanlines */
+    p     = ( ONE_PIXEL - fy1 ) * dx;
+    first = ONE_PIXEL;
+    incr  = 1;
+
+    if ( dy < 0 )
+    {
+      p     = fy1 * dx;
+      first = 0;
+      incr  = -1;
+      dy    = -dy;
+    }
+
+    delta = p / dy;
+    mod   = p % dy;
+    if ( mod < 0 )
+    {
+      delta--;
+      mod += dy;
+    }
+
+    x = ras.x + delta;
+    if ( render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first ) )
+      goto Error;
+
+    ey1 += incr;
+    if ( set_cell( RAS_VAR_ TRUNC( x ), ey1 ) )
+      goto Error;
+
+    if ( ey1 != ey2 )
+    {
+      p     = ONE_PIXEL * dx;
+      lift  = p / dy;
+      rem   = p % dy;
+      if ( rem < 0 )
+      {
+        lift--;
+        rem += dy;
+      }
+      mod -= dy;
+
+      while ( ey1 != ey2 )
+      {
+        delta = lift;
+        mod  += rem;
+        if ( mod >= 0 )
+        {
+          mod -= dy;
+          delta++;
+        }
+
+        x2 = x + delta;
+        if ( render_scanline( RAS_VAR_ ey1,
+                              x, ONE_PIXEL - first, x2, first ) )
+          goto Error;
+        x = x2;
+        ey1 += incr;
+        if ( set_cell( RAS_VAR_ TRUNC( x ), ey1 ) )
+          goto Error;
+      }
+    }
+
+    if ( render_scanline( RAS_VAR_ ey1,
+                          x, ONE_PIXEL - first, to_x, fy2 ) )
+      goto Error;
+
+  End:
+    ras.x       = to_x;
+    ras.y       = to_y;
+    ras.last_ey = SUBPIXELS( ey2 );
+
+    return 0;
+
+  Error:
+    return 1;
+  }
+
+
+  static
+  void  split_conic( FT_Vector*  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;
+  }
+
+
+  static
+  int  render_conic( RAS_ARG_ FT_Vector*  control,
+                              FT_Vector*  to )
+  {
+    TPos        dx, dy;
+    int         top, level;
+    int*        levels;
+    FT_Vector*  arc;
+
+
+    dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 );
+    if ( dx < 0 )
+      dx = -dx;
+    dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 );
+    if ( dy < 0 )
+      dy = -dy;
+    if ( dx < dy )
+      dx = dy;
+
+    level = 1;
+    dx = dx / ras.conic_level;
+    while ( dx > 0 )
+    {
+      dx >>= 1;
+      level++;
+    }
+
+    /* a shortcut to speed things up */
+    if ( level <= 1 )
+    {
+      /* we compute the mid-point directly in order to avoid */
+      /* calling split_conic()                               */
+      TPos   to_x, to_y, mid_x, mid_y;
+
+
+      to_x  = UPSCALE( to->x );
+      to_y  = UPSCALE( to->y );
+      mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4;
+      mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4;
+
+      return render_line( RAS_VAR_ mid_x, mid_y ) ||
+             render_line( RAS_VAR_ to_x, to_y );
+    }
+
+    arc       = ras.bez_stack;
+    levels    = ras.lev_stack;
+    top       = 0;
+    levels[0] = level;
+
+    arc[0].x = UPSCALE( to->x );
+    arc[0].y = UPSCALE( to->y );
+    arc[1].x = UPSCALE( control->x );
+    arc[1].y = UPSCALE( control->y );
+    arc[2].x = ras.x;
+    arc[2].y = ras.y;
+
+    while ( top >= 0 )
+    {
+      level = levels[top];
+      if ( level > 1 )
+      {
+        /* check that the arc crosses the current band */
+        TPos  min, max, y;
+
+
+        min = max = arc[0].y;
+
+        y = arc[1].y;
+        if ( y < min ) min = y;
+        if ( y > max ) max = y;
+
+        y = arc[2].y;
+        if ( y < min ) min = y;
+        if ( y > max ) max = y;
+
+        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
+          goto Draw;
+
+        split_conic( arc );
+        arc += 2;
+        top++;
+        levels[top] = levels[top - 1] = level - 1;
+        continue;
+      }
+
+    Draw:
+      {
+        TPos  to_x, to_y, mid_x, mid_y;
+
+
+        to_x  = arc[0].x;
+        to_y  = arc[0].y;
+        mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4;
+        mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4;
+
+        if ( render_line( RAS_VAR_ mid_x, mid_y ) ||
+             render_line( RAS_VAR_ to_x, to_y )   )
+          return 1;
+
+        top--;
+        arc -= 2;
+      }
+    }
+    return 0;
+  }
+
+
+  static
+  void  split_cubic( FT_Vector*  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;
+  }
+
+
+  static
+  int  render_cubic( RAS_ARG_ FT_Vector*  control1,
+                              FT_Vector*  control2,
+                              FT_Vector*  to )
+  {
+    TPos        dx, dy, da, db;
+    int         top, level;
+    int*        levels;
+    FT_Vector*  arc;
+
+
+    dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 );
+    if ( dx < 0 )
+      dx = -dx;
+    dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 );
+    if ( dy < 0 )
+      dy = -dy;
+    if ( dx < dy )
+      dx = dy;
+    da = dx;
+
+    dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x );
+    if ( dx < 0 )
+      dx = -dx;
+    dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y );
+    if ( dy < 0 )
+      dy = -dy;
+    if ( dx < dy )
+      dx = dy;
+    db = dx;
+
+    level = 1;
+    da    = da / ras.cubic_level;
+    db    = db / ras.conic_level;
+    while ( da > 0 || db > 0 )
+    {
+      da >>= 1;
+      db >>= 2;
+      level++;
+    }
+
+    if ( level <= 1 )
+    {
+      TPos   to_x, to_y, mid_x, mid_y;
+
+
+      to_x  = UPSCALE( to->x );
+      to_y  = UPSCALE( to->y );
+      mid_x = ( ras.x + to_x +
+                3 * UPSCALE( control1->x + control2->x ) ) / 8;
+      mid_y = ( ras.y + to_y +
+                3 * UPSCALE( control1->y + control2->y ) ) / 8;
+
+      return render_line( RAS_VAR_ mid_x, mid_y ) ||
+             render_line( RAS_VAR_ to_x, to_y );
+    }
+
+    arc      = ras.bez_stack;
+    arc[0].x = UPSCALE( to->x );
+    arc[0].y = UPSCALE( to->y );
+    arc[1].x = UPSCALE( control2->x );
+    arc[1].y = UPSCALE( control2->y );
+    arc[2].x = UPSCALE( control1->x );
+    arc[2].y = UPSCALE( control1->y );
+    arc[3].x = ras.x;
+    arc[3].y = ras.y;
+
+    levels    = ras.lev_stack;
+    top       = 0;
+    levels[0] = level;
+
+    while ( top >= 0 )
+    {
+      level = levels[top];
+      if ( level > 1 )
+      {
+        /* check that the arc crosses the current band */
+        TPos  min, max, y;
+
+
+        min = max = arc[0].y;
+        y = arc[1].y;
+        if ( y < min ) min = y;
+        if ( y > max ) max = y;
+        y = arc[2].y;
+        if ( y < min ) min = y;
+        if ( y > max ) max = y;
+        y = arc[3].y;
+        if ( y < min ) min = y;
+        if ( y > max ) max = y;
+        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
+          goto Draw;
+        split_cubic( arc );
+        arc += 3;
+        top ++;
+        levels[top] = levels[top - 1] = level - 1;
+        continue;
+      }
+
+    Draw:
+      {
+        TPos   to_x, to_y, mid_x, mid_y;
+
+
+        to_x  = arc[0].x;
+        to_y  = arc[0].y;
+        mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8;
+        mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8;
+
+        if ( render_line( RAS_VAR_ mid_x, mid_y ) ||
+             render_line( RAS_VAR_ to_x, to_y )   )
+          return 1;
+        top --;
+        arc -= 3;
+      }
+    }
+    return 0;
+  }
+
+
+  /* a macro comparing two cell pointers.  Returns true if a <= b. */
+#if 1
+#define PACK( a )          ( ( (long)(a)->y << 16 ) + (a)->x )
+#define LESS_THAN( a, b )  ( PACK( a ) < PACK( b ) )
+#else /* 1 */
+#define LESS_THAN( a, b )  ( (a)->y < (b)->y || \
+                             ( (a)->y == (b)->y && (a)->x < (b)->x ) )
+#endif /* 1 */
+
+#define SWAP_CELLS( a, b, temp )  do             \
+                                  {              \
+                                    temp = *(a); \
+                                    *(a) = *(b); \
+                                    *(b) = temp; \
+                                  } while ( 0 )
+#define DEBUG_SORT
+#define QUICK_SORT
+
+#ifdef SHELL_SORT
+
+  /* A simple shell sort algorithm that works directly on our */
+  /* cells table..                                            */
+  static
+  void  shell_sort ( PCell  cells,
+                     int    count )
+  {
+    PCell  i, j, limit = cells + count;
+    TCell  temp;
+    int    gap;
+
+
+    /* compute initial gap */
+    for ( gap = 0; ++gap < count; gap *= 3 )
+      ;
+
+    while ( gap /= 3 )
+    {
+      for ( i = cells + gap; i < limit; i++ )
+      {
+        for ( j = i - gap; ; j -= gap )
+        {
+          PCell  k = j + gap;
+
+
+          if ( LESS_THAN( j, k ) )
+            break;
+
+          SWAP_CELLS( j, k, temp );
+
+          if ( j < cells + gap )
+            break;
+        }
+      }
+    }
+  }
+
+#endif /* SHELL_SORT */
+
+
+#ifdef QUICK_SORT
+
+  /* This is a non-recursive quicksort that directly process our cells     */
+  /* array.  It should be faster than calling the stdlib qsort(), and we   */
+  /* can even tailor our insertion threshold...                            */
+
+#define QSORT_THRESHOLD  9  /* below this size, a sub-array will be sorted */
+                            /* through a normal insertion sort..           */
+
+  static
+  void  quick_sort( PCell  cells,
+                    int    count )
+  {
+    PCell   stack[40];  /* should be enough ;-) */
+    PCell*  top;        /* top of stack */
+    PCell   base, limit;
+    TCell   temp;
+
+
+    limit = cells + count;
+    base  = cells;
+    top   = stack;
+
+    for (;;)
+    {
+      int    len = limit - base;
+      PCell  i, j, pivot;
+
+
+      if ( len > QSORT_THRESHOLD )
+      {
+        /* we use base + len/2 as the pivot */
+        pivot = base + len / 2;
+        SWAP_CELLS( base, pivot, temp );
+
+        i = base + 1;
+        j = limit - 1;
+
+        /* now ensure that *i <= *base <= *j */
+        if ( LESS_THAN( j, i ) )
+          SWAP_CELLS( i, j, temp );
+
+        if ( LESS_THAN( base, i ) )
+          SWAP_CELLS( base, i, temp );
+
+        if ( LESS_THAN( j, base ) )
+          SWAP_CELLS( base, j, temp );
+
+        for (;;)
+        {
+          do i++; while ( LESS_THAN( i, base ) );
+          do j--; while ( LESS_THAN( base, j ) );
+
+          if ( i > j )
+            break;
+
+          SWAP_CELLS( i, j, temp );
+        }
+
+        SWAP_CELLS( base, j, temp );
+
+        /* now, push the largest sub-array */
+        if ( j - base > limit - i )
+        {
+          top[0] = base;
+          top[1] = j;
+          base   = i;
+        }
+        else
+        {
+          top[0] = i;
+          top[1] = limit;
+          limit  = j;
+        }
+        top += 2;
+      }
+      else
+      {
+        /* the sub-array is small, perform insertion sort */
+        j = base;
+        i = j + 1;
+
+        for ( ; i < limit; j = i, i++ )
+        {
+          for ( ; LESS_THAN( j + 1, j ); j-- )
+          {
+            SWAP_CELLS( j + 1, j, temp );
+            if ( j == base )
+              break;
+          }
+        }
+        if ( top > stack )
+        {
+          top  -= 2;
+          base  = top[0];
+          limit = top[1];
+        }
+        else
+          break;
+      }
+    }
+  }
+
+#endif /* QUICK_SORT */
+
+
+#ifdef DEBUG_GRAYS
+#ifdef DEBUG_SORT
+
+  static
+  int  check_sort( PCell  cells,
+                   int    count )
+  {
+    PCell  p, q;
+
+
+    for ( p = cells + count - 2; p >= cells; p-- )
+    {
+      q = p + 1;
+      if ( !LESS_THAN( p, q ) )
+        return 0;
+    }
+    return 1;
+  }
+
+#endif /* DEBUG_SORT */
+#endif /* DEBUG_GRAYS */
+
+
+  static
+  int  Move_To( FT_Vector*  to,
+                FT_Raster   raster )
+  {
+    TPos  x, y;
+
+
+    /* record current cell, if any */
+    record_cell( (PRaster)raster );
+
+    /* start to a new position */
+    x = UPSCALE( to->x );
+    y = UPSCALE( to->y );
+    start_cell( (PRaster)raster, TRUNC( x ), TRUNC( y ) );
+    ((PRaster)raster)->x = x;
+    ((PRaster)raster)->y = y;
+    return 0;
+  }
+
+
+  static
+  int  Line_To( FT_Vector*  to,
+                FT_Raster   raster )
+  {
+    return render_line( (PRaster)raster,
+                        UPSCALE( to->x ), UPSCALE( to->y ) );
+  }
+
+
+  static
+  int  Conic_To( FT_Vector*  control,
+                 FT_Vector*  to,
+                 FT_Raster   raster )
+  {
+    return render_conic( (PRaster)raster, control, to );
+  }
+
+
+  static
+  int  Cubic_To( FT_Vector*  control1,
+                 FT_Vector*  control2,
+                 FT_Vector*  to,
+                 FT_Raster   raster )
+  {
+    return render_cubic( (PRaster)raster, control1, control2, to );
+  }
+
+
+  static
+  void  grays_render_span( int       y,
+                           int       count,
+                           FT_Span*  spans,
+                           PRaster   raster )
+  {
+    unsigned char*  p;
+    FT_Bitmap*      map = &raster->target;
+
+
+    /* first of all, compute the scanline offset */
+    p = (unsigned char*)map->buffer - y * map->pitch;
+    if ( map->pitch >= 0 )
+      p += ( map->rows - 1 ) * map->pitch;
+
+    for ( ; count > 0; count--, spans++ )
+    {
+      if ( spans->coverage )
+#if 1
+        memset( p + spans->x, (unsigned char)spans->coverage, spans->len );
+#else /* 1 */
+      {
+        q     = p + spans->x;
+        limit = q + spans->len;
+        for ( ; q < limit; q++ )
+          q[0] = (unsigned char)spans->coverage;
+      }
+#endif /* 1 */
+    }
+  }
+
+
+#ifdef DEBUG_GRAYS
+
+#include <stdio.h>
+
+  static
+  void  dump_cells( RAS_ARG )
+  {
+    PCell  cell, limit;
+    int    y = -1;
+
+
+    cell  = ras.cells;
+    limit = cell + ras.num_cells;
+
+    for ( ; cell < limit; cell++ )
+    {
+      if ( cell->y != y )
+      {
+        fprintf( stderr, "\n%2d: ", cell->y );
+        y = cell->y;
+      }
+      fprintf( stderr, "[%d %d %d]",
+               cell->x, cell->area, cell->cover );
+    }
+    fprintf(stderr, "\n" );
+  }
+
+#endif /* DEBUG_GRAYS */
+
+
+  static
+  void  grays_hline( RAS_ARG_ TScan  x,
+                              TScan  y,
+                              TPos   area,
+                              int    acount )
+  {
+    FT_Span*   span;
+    int        count;
+    int        coverage;
+
+
+    /* compute the coverage line's coverage, depending on the    */
+    /* outline fill rule                                         */
+    /*                                                           */
+    /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */
+    /*                                                           */
+    coverage = area >> ( PIXEL_BITS * 2 + 1 - 8);  /* use range 0..256 */
+
+    if ( ras.outline.flags & ft_outline_even_odd_fill )
+    {
+      if ( coverage < 0 )
+        coverage = -coverage;
+
+      while ( coverage >= 512 )
+        coverage -= 512;
+
+      if ( coverage > 256 )
+        coverage = 512 - coverage;
+      else if ( coverage == 256 )
+        coverage = 255;
+    }
+    else
+    {
+      /* normal non-zero winding rule */
+      if ( coverage < 0 )
+        coverage = -coverage;
+
+      if ( coverage >= 256 )
+        coverage = 255;
+    }
+
+    y += ras.min_ey;
+    x += ras.min_ex;
+
+    if ( coverage )
+    {
+      /* see if we can add this span to the current list */
+      count = ras.num_gray_spans;
+      span  = ras.gray_spans + count - 1;
+      if ( count > 0                          &&
+           ras.span_y == y                    &&
+           (int)span->x + span->len == (int)x &&
+           span->coverage == coverage )
+      {
+        span->len += acount;
+        return;
+      }
+
+      if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS )
+      {
+        if ( ras.render_span )
+          ras.render_span( ras.span_y, count, ras.gray_spans,
+                           ras.render_span_data );
+        /* ras.render_span( span->y, ras.gray_spans, count ); */
+
+#ifdef DEBUG_GRAYS
+
+        if ( ras.span_y >= 0 )
+        {
+          int  n;
+
+
+          fprintf( stderr, "y=%3d ", ras.span_y );
+          span = ras.gray_spans;
+          for ( n = 0; n < count; n++, span++ )
+            fprintf( stderr, "[%d..%d]:%02x ",
+                     span->x, span->x + span->len - 1, span->coverage );
+          fprintf( stderr, "\n" );
+        }
+
+#endif /* DEBUG_GRAYS */
+
+        ras.num_gray_spans = 0;
+        ras.span_y         = y;
+
+        count = 0;
+        span  = ras.gray_spans;
+      }
+      else
+        span++;
+
+      /* add a gray span to the current list */
+      span->x        = (short)x;
+      span->len      = (unsigned short)acount;
+      span->coverage = (unsigned char)coverage;
+      ras.num_gray_spans++;
+    }
+  }
+
+
+  static
+  void  grays_sweep( RAS_ARG_ FT_Bitmap*  target )
+  {
+    TScan  x, y, cover, area;
+    PCell  start, cur, limit;
+
+    UNUSED( target );
+
+
+    cur   = ras.cells;
+    limit = cur + ras.num_cells;
+
+    cover              = 0;
+    ras.span_y         = -1;
+    ras.num_gray_spans = 0;
+
+    for (;;)
+    {
+      start  = cur;
+      y      = start->y;
+      x      = start->x;
+
+      area   = start->area;
+      cover += start->cover;
+
+      /* accumulate all start cells */
+      for (;;)
+      {
+        ++cur;
+        if ( cur >= limit || cur->y != start->y || cur->x != start->x )
+          break;
+
+        area  += cur->area;
+        cover += cur->cover;
+      }
+
+      /* if the start cell has a non-null area, we must draw an */
+      /* individual gray pixel there                            */
+      if ( area && x >= 0 )
+      {
+        grays_hline( RAS_VAR_ x, y, cover * ( ONE_PIXEL * 2 ) - area, 1 );
+        x++;
+      }
+
+      if ( x < 0 )
+        x = 0;
+
+      if ( cur < limit && start->y == cur->y )
+      {
+        /* draw a gray span between the start cell and the current one */
+        if ( cur->x > x )
+          grays_hline( RAS_VAR_ x, y,
+                       cover * ( ONE_PIXEL * 2 ), cur->x - x );
+      }
+      else
+      {
+        /* draw a gray span until the end of the clipping region */
+        if ( cover && x < ras.max_ex - ras.min_ex )
+          grays_hline( RAS_VAR_ x, y,
+                       cover * ( ONE_PIXEL * 2 ),
+                       ras.max_ex - x - ras.min_ex );
+        cover = 0;
+      }
+
+      if ( cur >= limit )
+        break;
+    }
+
+    if ( ras.render_span && ras.num_gray_spans > 0 )
+      ras.render_span( ras.span_y, ras.num_gray_spans,
+                       ras.gray_spans, ras.render_span_data );
+
+#ifdef DEBUG_GRAYS
+
+    {
+      int       n;
+      FT_Span*  span;
+
+
+      fprintf( stderr, "y=%3d ", ras.span_y );
+      span = ras.gray_spans;
+      for ( n = 0; n < ras.num_gray_spans; n++, span++ )
+        fprintf( stderr, "[%d..%d]:%02x ",
+                 span->x, span->x + span->len - 1, span->coverage );
+      fprintf( stderr, "\n" );
+    }
+
+#endif /* DEBUG_GRAYS */
+
+  }
+
+
+#ifdef _STANDALONE_
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  The following function should only compile in stand_alone mode,      */
+  /*  i.e., when building this component without the rest of FreeType.     */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Outline_Decompose                                               */
+  /*                                                                       */
+  /* <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.                                       */
+  /*                                                                       */
+  static
+  int  FT_Outline_Decompose( FT_Outline*        outline,
+                             FT_Outline_Funcs*  interface,
+                             void*              user )
+  {
+#undef SCALED
+#define SCALED( x )  ( ( (x) << shift ) - delta )
+
+    FT_Vector   v_last;
+    FT_Vector   v_control;
+    FT_Vector   v_start;
+
+    FT_Vector*  point;
+    FT_Vector*  limit;
+    char*       tags;
+
+    int     n;         /* index of contour in outline     */
+    int     first;     /* index of first point in contour */
+    int     error;
+    char    tag;       /* current point's state           */
+
+    int     shift = interface->shift;
+    FT_Pos  delta = interface->delta;
+
+
+    first = 0;
+
+    for ( n = 0; n < outline->n_contours; n++ )
+    {
+      int  last;  /* index of last point in contour */
+
+
+      last  = outline->contours[n];
+      limit = outline->points + last;
+
+      v_start = outline->points[first];
+      v_last  = outline->points[last];
+
+      v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y );
+      v_last.x  = SCALED( v_last.x );  v_last.y  = SCALED( v_last.y );
+
+      v_control = v_start;
+
+      point = outline->points + first;
+      tags  = outline->tags  + first;
+      tag   = FT_CURVE_TAG( tags[0] );
+
+      /* A contour cannot start with a cubic control point! */
+      if ( tag == FT_Curve_Tag_Cubic )
+        goto 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->tags[last] ) == FT_Curve_Tag_On )
+        {
+          /* start at last point if it is on the curve */
+          v_start = v_last;
+          limit--;
+        }
+        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;
+        }
+        point--;
+        tags--;
+      }
+
+      error = interface->move_to( &v_start, user );
+      if ( error )
+        goto Exit;
+
+      while ( point < limit )
+      {
+        point++;
+        tags++;
+
+        tag = FT_CURVE_TAG( tags[0] );
+        switch ( tag )
+        {
+        case FT_Curve_Tag_On:  /* emit a single line_to */
+          {
+            FT_Vector  vec;
+
+
+            vec.x = SCALED( point->x );
+            vec.y = SCALED( point->y );
+
+            error = interface->line_to( &vec, user );
+            if ( error )
+              goto Exit;
+            continue;
+          }
+
+        case FT_Curve_Tag_Conic:  /* consume conic arcs */
+          {
+            v_control.x = SCALED( point->x );
+            v_control.y = SCALED( point->y );
+
+          Do_Conic:
+            if ( point < limit )
+            {
+              FT_Vector  vec;
+              FT_Vector  v_middle;
+
+
+              point++;
+              tags++;
+              tag = FT_CURVE_TAG( tags[0] );
+
+              vec.x = SCALED( point->x );
+              vec.y = SCALED( point->y );
+
+              if ( tag == FT_Curve_Tag_On )
+              {
+                error = interface->conic_to( &v_control, &vec, user );
+                if ( error )
+                  goto Exit;
+                continue;
+              }
+
+              if ( tag != FT_Curve_Tag_Conic )
+                goto Invalid_Outline;
+
+              v_middle.x = ( v_control.x + vec.x ) / 2;
+              v_middle.y = ( v_control.y + vec.y ) / 2;
+
+              error = interface->conic_to( &v_control, &v_middle, user );
+              if ( error )
+                goto Exit;
+
+              v_control = vec;
+              goto Do_Conic;
+            }
+
+            error = interface->conic_to( &v_control, &v_start, user );
+            goto Close;
+          }
+
+        default:  /* FT_Curve_Tag_Cubic */
+          {
+            FT_Vector  vec1, vec2;
+
+
+            if ( point + 1 > limit                             ||
+                 FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic )
+              goto Invalid_Outline;
+
+            point += 2;
+            tags  += 2;
+
+            vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y );
+            vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y );
+
+            if ( point <= limit )
+            {
+              FT_Vector  vec;
+
+
+              vec.x = SCALED( point->x );
+              vec.y = SCALED( point->y );
+
+              error = interface->cubic_to( &vec1, &vec2, &vec, user );
+              if ( error )
+                goto Exit;
+              continue;
+            }
+
+            error = interface->cubic_to( &vec1, &vec2, &v_start, user );
+            goto Close;
+          }
+        }
+      }
+
+      /* close the contour with a line segment */
+      error = interface->line_to( &v_start, user );
+
+   Close:
+      if ( error )
+        goto Exit;
+
+      first = last + 1;
+    }
+
+    return 0;
+
+  Exit:
+    return error;
+
+  Invalid_Outline:
+    return ErrRaster_Invalid_Outline;
+  }
+
+#endif /* _STANDALONE_ */
+
+
+  typedef struct  TBand_
+  {
+    FT_Pos  min, max;
+
+  } TBand;
+
+
+  static
+  int  grays_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,
+      0,
+      0
+    };
+
+    TBand    bands[40], *band;
+    int      n, num_bands;
+    TPos     min, max, max_y;
+
+
+    /* Set up state in the raster object */
+    compute_cbox( RAS_VAR_ outline );
+
+    /* clip to target bitmap, exit if nothing to do */
+    if ( ras.max_ex <= 0 || ras.min_ex >= ras.target.width ||
+         ras.max_ey <= 0 || ras.min_ey >= ras.target.rows  )
+      return 0;
+
+    if ( ras.min_ex < 0 ) ras.min_ex = 0;
+    if ( ras.min_ey < 0 ) ras.min_ey = 0;
+
+    if ( ras.max_ex > ras.target.width ) ras.max_ex = ras.target.width;
+    if ( ras.max_ey > ras.target.rows )  ras.max_ey = ras.target.rows;
+
+    /* simple heuristic used to speed-up the bezier decomposition     */
+    /* see the code in render_conic and render_cubic for more details */
+    ras.conic_level = 32;
+    ras.cubic_level = 16;
+
+    {
+      int level = 0;
+
+
+      if ( ras.max_ex > 24 || ras.max_ey > 24 )
+        level++;
+      if ( ras.max_ex > 120 || ras.max_ey > 120 )
+        level += 2;
+
+      ras.conic_level <<= level;
+      ras.cubic_level <<= level;
+    }
+
+    /* setup vertical bands */
+    num_bands = ( ras.max_ey - ras.min_ey ) / ras.band_size;
+    if ( num_bands == 0 )  num_bands = 1;
+    if ( num_bands >= 39 ) num_bands = 39;
+
+    ras.band_shoot = 0;
+
+    min   = ras.min_ey;
+    max_y = ras.max_ey;
+
+    for ( n = 0; n < num_bands; n++, min = max )
+    {
+      max = min + ras.band_size;
+      if ( n == num_bands - 1 || max > max_y )
+        max = max_y;
+
+      bands[0].min = min;
+      bands[0].max = max;
+      band         = bands;
+
+      while ( band >= bands )
+      {
+        FT_Pos  bottom, top, middle;
+        int     error;
+
+
+        ras.num_cells = 0;
+        ras.invalid   = 1;
+        ras.min_ey    = band->min;
+        ras.max_ey    = band->max;
+
+        error = FT_Outline_Decompose( outline, &interface, &ras ) ||
+                record_cell( RAS_VAR );
+
+        if ( !error )
+        {
+#ifdef SHELL_SORT
+          shell_sort( ras.cells, ras.num_cells );
+#else
+          quick_sort( ras.cells, ras.num_cells );
+#endif
+
+#ifdef DEBUG_GRAYS
+          check_sort( ras.cells, ras.num_cells );
+          dump_cells( RAS_VAR );
+#endif
+
+          grays_sweep( RAS_VAR_  &ras.target );
+          band--;
+          continue;
+        }
+
+        /* render pool overflow, we will reduce the render band by half */
+        bottom = band->min;
+        top    = band->max;
+        middle = bottom + ( ( top - bottom ) >> 1 );
+
+        /* waoow! This is too complex for a single scanline, something */
+        /* must be really rotten here!                                 */
+        if ( middle == bottom )
+        {
+#ifdef DEBUG_GRAYS
+          fprintf( stderr, "Rotten glyph!\n" );
+#endif
+          return 1;
+        }
+
+        if ( bottom-top >= ras.band_size )
+          ras.band_shoot++;
+
+        band[1].min = bottom;
+        band[1].max = middle;
+        band[0].min = middle;
+        band[0].max = top;
+        band++;
+      }
+    }
+
+    if ( ras.band_shoot > 8 && ras.band_size > 16 )
+      ras.band_size = ras.band_size / 2;
+
+    return 0;
+  }
+
+
+  extern
+  int  grays_raster_render( PRaster            raster,
+                            FT_Raster_Params*  params )
+  {
+    FT_Outline*  outline = (FT_Outline*)params->source;
+    FT_Bitmap*   target_map = params->target;
+
+
+    if ( !raster || !raster->cells || !raster->max_cells )
+      return -1;
+
+    /* return immediately if the outline is empty */
+    if ( outline->n_points == 0 || outline->n_contours <= 0 )
+      return 0;
+
+    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 -1;
+
+    /* XXXX: this version does not support monochrome rendering yet! */
+    if ( !(params->flags & ft_raster_flag_aa) )
+      return -1;
+
+    ras.outline   = *outline;
+    ras.target    = *target_map;
+    ras.num_cells = 0;
+    ras.invalid   = 1;
+
+    ras.render_span      = (FT_Raster_Span_Func)grays_render_span;
+    ras.render_span_data = &ras;
+
+    if ( params->flags & ft_raster_flag_direct )
+    {
+      ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
+      ras.render_span_data = params->user;
+    }
+
+    return grays_convert_glyph( (PRaster)raster, outline );
+  }
+
+
+  /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/
+  /****                         a static object.                  *****/
+
+#ifdef _STANDALONE_
+
+  static
+  int  grays_raster_new( void*       memory,
+                         FT_Raster*  araster )
+  {
+    static TRaster  the_raster;
+
+    UNUSED( memory );
+
+
+    *araster = (FT_Raster)&the_raster;
+    memset( &the_raster, 0, sizeof ( the_raster ) );
+
+    return 0;
+  }
+
+
+  static
+  void  grays_raster_done( FT_Raster  raster )
+  {
+    /* nothing */
+    UNUSED( raster );
+  }
+
+#else /* _STANDALONE_ */
+
+  static
+  int  grays_raster_new( FT_Memory   memory,
+                         FT_Raster*  araster )
+  {
+    FT_Error  error;
+    PRaster   raster;
+
+
+    *araster = 0;
+    if ( !ALLOC( raster, sizeof ( TRaster ) ) )
+    {
+      raster->memory = memory;
+      *araster = (FT_Raster)raster;
+    }
+
+    return error;
+  }
+
+
+  static
+  void grays_raster_done( FT_Raster  raster )
+  {
+    FT_Memory  memory = (FT_Memory)((PRaster)raster)->memory;
+
+
+    FREE( raster );
+  }
+
+#endif /* _STANDALONE_ */
+
+
+  static
+  void  grays_raster_reset( FT_Raster    raster,
+                            const char*  pool_base,
+                            long         pool_size )
+  {
+    PRaster  rast = (PRaster)raster;
+
+
+    if ( raster && pool_base && pool_size >= 4096 )
+      init_cells( rast, (char*)pool_base, pool_size );
+
+    rast->band_size  = ( pool_size / sizeof ( TCell ) ) / 8;
+  }
+
+
+  FT_Raster_Funcs  ft_grays_raster =
+  {
+    ft_glyph_format_outline,
+
+    (FT_Raster_New_Func)     grays_raster_new,
+    (FT_Raster_Reset_Func)   grays_raster_reset,
+    (FT_Raster_Set_Mode_Func)0,
+    (FT_Raster_Render_Func)  grays_raster_render,
+    (FT_Raster_Done_Func)    grays_raster_done
+  };
+
+
+/* END */
--- /dev/null
+++ b/src/renderer/ftgrays.h
@@ -1,0 +1,49 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftgrays.h                                                              */
+/*                                                                         */
+/*    FreeType smooth renderer declaration                                 */
+/*                                                                         */
+/*  Copyright 1996-2000 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used        */
+/*  modified and distributed under the terms of the FreeType project       */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+#ifndef FTGRAYS_H
+#define FTGRAYS_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+#ifdef _STANDALONE_
+#include "ftimage.h"
+#else
+#include <freetype/ftimage.h>
+#endif
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* To make ftgrays.h independent from configuration files we check       */
+  /* whether FT_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 FT_EXPORT_VAR
+#define FT_EXPORT_VAR(x)  extern  x
+#endif
+
+  FT_EXPORT_VAR(FT_Raster_Funcs)  ft_grays_raster;
+
+  #ifdef __cplusplus
+  }
+  #endif
+
+#endif
--- /dev/null
+++ b/src/renderer/ftraster.c
@@ -1,0 +1,3262 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftraster.c                                                             */
+/*                                                                         */
+/*    The FreeType glyph rasterizer (body).                                */
+/*                                                                         */
+/*  Copyright 1996-2000 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* This is a rewrite of the FreeType 1.x scan-line converter             */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#include "ftraster.h"
+#include <freetype/internal/ftcalc.h>      /* for FT_MulDiv() only */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* A simple technical note on how the raster works:                      */
+  /*                                                                       */
+  /*   Converting an outline into a bitmap is achieved in several steps:   */
+  /*                                                                       */
+  /*   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 whether it 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.  Additionally, 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                                   top         */
+  /*                                                                       */
+  /*   The top of the profile stack is kept in the `top' 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 `y-turns' 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 |                     */
+  /*      _ _ __________________|____________________|                     */
+  /*                                                                       */
+  /*                            ^                    ^                     */
+  /*                            |                    |                     */
+  /*                       maxBuff             sizeBuff = end of 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.                                    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /**                                                                     **/
+  /**  CONFIGURATION MACROS                                               **/
+  /**                                                                     **/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /* define DEBUG_RASTER if you want to compile a debugging version */
+#define xxxDEBUG_RASTER
+
+  /* The default render pool size in bytes */
+#define RASTER_RENDER_POOL  8192
+
+  /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */
+  /* 5-levels anti-aliasing                                                */
+#ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS
+#define FT_RASTER_OPTION_ANTI_ALIASING
+#endif
+
+  /* The size of the two-lines intermediate bitmap used */
+  /* for anti-aliasing, in bytes.                       */
+#define RASTER_GRAY_LINES  2048
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /**                                                                     **/
+  /**  OTHER MACROS (do not change)                                       **/
+  /**                                                                     **/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_raster
+
+
+#ifdef _STANDALONE_
+
+
+  /* This macro is used to indicate that a function parameter is unused. */
+  /* Its purpose is simply to reduce compiler warnings.  Note also that  */
+  /* simply defining it as `(void)x' doesn't avoid warnings with certain */
+  /* ANSI compilers (e.g. LCC).                                          */
+#define UNUSED( x )  (x) = (x)
+
+  /* Disable the tracing mechanism for simplicity -- developers can      */
+  /* activate it easily by redefining these two macros.                  */
+#ifndef FT_ERROR
+#define FT_ERROR( x )  do ; while ( 0 )     /* nothing */
+#endif
+
+#ifndef FT_TRACE
+#define FT_TRACE( x )  do ; while ( 0 )     /* nothing */
+#endif
+
+
+#else /* _STANDALONE_ */
+
+
+#include <freetype/internal/ftobjs.h>
+#include <freetype/internal/ftdebug.h> /* for FT_TRACE() and FT_ERROR() */
+
+
+#endif /* _STANDALONE_ */
+
+
+#define Raster_Err_None               0
+#define Raster_Err_Not_Ini           -1
+#define Raster_Err_Overflow          -2
+#define Raster_Err_Neg_Height        -3
+#define Raster_Err_Invalid           -4
+#define Raster_Err_Gray_Unsupported  -5
+#define Raster_Err_Unsupported       -6
+
+  /* FMulDiv means `Fast MulDiv', it is used in case where `b' is       */
+  /* typically a small value and the result of a*b is known to fit into */
+  /* 32 bits.                                                           */
+#define FMulDiv( a, b, c )  ( (a) * (b) / (c) )
+
+  /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */
+  /* for clipping computations.  It simply uses the FT_MulDiv() function   */
+  /* defined in `ftcalc.h'.                                                */
+#define SMulDiv  FT_MulDiv
+
+  /* The rasterizer is a very general purpose component; please leave */
+  /* the following redefinitions there (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 SUCCESS
+#define SUCCESS  0
+#endif
+
+#ifndef FAILURE
+#define FAILURE  1
+#endif
+
+
+#define MaxBezier  32   /* The maximum number of stacked Bezier curves. */
+                        /* Setting this constant to more than 32 is a   */
+                        /* pure waste of space.                         */
+
+#define Pixel_Bits  6   /* fractional bits of *input* coordinates */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /**                                                                     **/
+  /**  SIMPLE TYPE DECLARATIONS                                           **/
+  /**                                                                     **/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  typedef int             Int;
+  typedef unsigned int    UInt;
+  typedef short           Short;
+  typedef unsigned short  UShort, *PUShort;
+  typedef long            Long, *PLong;
+  typedef unsigned long   ULong;
+
+  typedef unsigned char   Byte, *PByte;
+  typedef char            Bool;
+
+  typedef struct  TPoint_
+  {
+    Long  x;
+    Long  y;
+
+  } TPoint;
+
+
+  typedef enum  TFlow_
+  {
+    Flow_None = 0,
+    Flow_Up   = 1,
+    Flow_Down = -1
+
+  } TFlow;
+
+
+  /* States of each line, arc, and profile */
+  typedef enum  TStates_
+  {
+    Unknown,
+    Ascending,
+    Descending,
+    Flat
+
+  } TStates;
+
+
+  typedef struct TProfile_  TProfile;
+  typedef TProfile*         PProfile;
+
+  struct  TProfile_
+  {
+    FT_F26Dot6  X;           /* current coordinate during sweep        */
+    PProfile    link;        /* link to next profile - various purpose */
+    PLong       offset;      /* start of profile's data in render pool */
+    Int         flow;        /* Profile orientation: Asc/Descending    */
+    Long        height;      /* profile's height in scanlines          */
+    Long        start;       /* profile's starting scanline            */
+
+    UShort      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;
+
+
+  /* Simple record used to implement a stack of bands, required */
+  /* by the sub-banding mechanism                               */
+  typedef struct  TBand_
+  {
+    Short  y_min;   /* band's minimum */
+    Short  y_max;   /* band's maximum */
+
+  } TBand;
+
+
+#define AlignProfileSize \
+          ( ( sizeof ( TProfile ) + sizeof ( long ) - 1 ) / sizeof ( long ) )
+
+
+#ifdef TT_STATIC_RASTER
+
+#define RAS_ARGS       /* void */
+#define RAS_ARG        /* void */
+
+#define RAS_VARS       /* void */
+#define RAS_VAR        /* void */
+
+#define UNUSED_RASTER  do ; while ( 0 )
+
+#else /* TT_STATIC_RASTER */
+
+#define RAS_ARGS       TRaster_Instance*  raster,
+#define RAS_ARG        TRaster_Instance*  raster
+
+#define RAS_VARS       raster,
+#define RAS_VAR        raster
+
+#define UNUSED_RASTER  UNUSED( raster )
+
+#endif /* TT_STATIC_RASTER */
+
+
+  typedef struct TRaster_Instance_  TRaster_Instance;
+
+
+  /* prototypes used for sweep function dispatch */
+  typedef void  Function_Sweep_Init( RAS_ARGS Short*  min,
+                                              Short*  max );
+
+  typedef void  Function_Sweep_Span( RAS_ARGS Short       y,
+                                              FT_F26Dot6  x1,
+                                              FT_F26Dot6  x2,
+                                              PProfile    left,
+                                              PProfile    right );
+
+  typedef void  Function_Sweep_Step( RAS_ARG );
+
+
+  /* NOTE: These operations are only valid on 2's complement processors */
+
+#define FLOOR( x )    ( (x) & -ras.precision )
+#define CEILING( x )  ( ( (x) + ras.precision - 1 ) & -ras.precision )
+#define TRUNC( x )    ( (signed long)(x) >> ras.precision_bits )
+#define FRAC( x )     ( (x) & ( ras.precision - 1 ) )
+#define SCALED( x )   ( ( (x) << ras.scale_shift ) - ras.precision_half )
+
+  /* Note that I have moved the location of some fields in the */
+  /* structure to ensure that the most used variables are used */
+  /* at the top.  Thus, their offset can be coded with less    */
+  /* opcodes, and it results in a smaller executable.          */
+
+  struct  TRaster_Instance_
+  {
+    Int       precision_bits;       /* precision related variables         */
+    Int       precision;
+    Int       precision_half;
+    Long      precision_mask;
+    Int       precision_shift;
+    Int       precision_step;
+    Int       precision_jitter;
+
+    Int       scale_shift;          /* == precision_shift   for bitmaps    */
+                                    /* == precision_shift+1 for pixmaps    */
+
+    PLong     buff;                 /* The profiles buffer                 */
+    PLong     sizeBuff;             /* Render pool size                    */
+    PLong     maxBuff;              /* Profiles buffer size                */
+    PLong     top;                  /* Current cursor in buffer            */
+
+    FT_Error  error;
+
+    Int       numTurns;             /* number of Y-turns in outline        */
+
+    TPoint*   arc;                  /* current Bezier arc pointer          */
+
+    UShort    bWidth;               /* target bitmap width                 */
+    PByte     bTarget;              /* target bitmap buffer                */
+    PByte     gTarget;              /* target pixmap buffer                */
+
+    Long      lastX, lastY, minY, maxY;
+
+    UShort    num_Profs;            /* current number of profiles          */
+
+    Bool      fresh;                /* signals a fresh new profile which   */
+                                    /* 'start' field must be completed     */
+    Bool      joint;                /* signals that the last arc ended     */
+                                    /* exactly on a scanline.  Allows      */
+                                    /* removal of doublets                 */
+    PProfile  cProfile;             /* current profile                     */
+    PProfile  fProfile;             /* head of linked list of profiles     */
+    PProfile  gProfile;             /* contour's first profile in case     */
+                                    /* of impact                           */
+    TStates   state;                /* rendering state                     */
+
+    FT_Bitmap   target;             /* description of target bit/pixmap    */
+    FT_Outline  outline;
+
+    Long      traceOfs;             /* current offset in target bitmap     */
+    Long      traceG;               /* current offset in target pixmap     */
+
+    Short     traceIncr;            /* sweep's increment in target bitmap  */
+
+    Short     gray_min_x;           /* current min x during gray rendering */
+    Short     gray_max_x;           /* current max x during gray rendering */
+
+    /* dispatch variables */
+
+    Function_Sweep_Init*  Proc_Sweep_Init;
+    Function_Sweep_Span*  Proc_Sweep_Span;
+    Function_Sweep_Span*  Proc_Sweep_Drop;
+    Function_Sweep_Step*  Proc_Sweep_Step;
+
+    Byte      dropOutControl;       /* current drop_out control method     */
+
+    Bool      second_pass;          /* indicates wether 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.                          */
+    TPoint    arcs[2 * MaxBezier + 1]; /* The Bezier stack                 */
+
+    TBand     band_stack[16];       /* band stack used for sub-banding     */
+    Int       band_top;             /* band stack top                      */
+
+    Int       count_table[256];     /* Look-up table used to quickly count */
+                                    /* set bits in a gray 2x2 cell         */
+
+    void*     memory;
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIASING
+
+    Byte      grays[5];             /* Palette of gray levels used for     */
+                                    /* render.                             */
+
+    Byte      gray_lines[RASTER_GRAY_LINES];
+                                /* Intermediate table used to render the   */
+                                /* graylevels pixmaps.                     */
+                                /* gray_lines is a buffer holding two      */
+                                /* monochrome scanlines                    */
+    Short     gray_width;       /* width in bytes of one monochrome        */
+                                /* intermediate scanline of gray_lines.    */
+                                /* Each gray pixel takes 2 bits long there */
+
+                       /* The gray_lines must hold 2 lines, thus with size */
+                       /* in bytes of at least `gray_width*2'.             */
+
+#endif /* FT_RASTER_ANTI_ALIASING */
+
+#if 0
+    PByte       flags;              /* current flags table                 */
+    PUShort     outs;               /* current outlines table              */
+    FT_Vector*  coords;
+
+    UShort      nPoints;            /* number of points in current glyph   */
+    Short       nContours;          /* number of contours in current glyph */
+#endif
+
+  };
+
+
+#ifdef FT_CONFIG_OPTION_STATIC_RASTER
+
+  static TRaster_Instance  cur_ras;
+#define ras  cur_ras
+
+#else
+
+#define ras  (*raster)
+
+#endif /* FT_CONFIG_OPTION_STATIC_RASTER */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /**                                                                     **/
+  /**  PROFILES COMPUTATION                                               **/
+  /**                                                                     **/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Set_High_Precision                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Sets precision variables according to param flag.                  */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    High :: Set to True for high precision (typically for ppem < 18),  */
+  /*            false otherwise.                                           */
+  /*                                                                       */
+  static
+  void  Set_High_Precision( RAS_ARGS Int  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;
+    }
+
+    FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" ));
+
+    ras.precision       = 1L << ras.precision_bits;
+    ras.precision_half  = ras.precision / 2;
+    ras.precision_shift = ras.precision_bits - Pixel_Bits;
+    ras.precision_mask  = -ras.precision;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    New_Profile                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Creates a new profile in the render pool.                          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    aState :: The state/orientation of the new profile.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   SUCCESS on success.  FAILURE in case of overflow or of incoherent   */
+  /*   profile.                                                            */
+  /*                                                                       */
+  static
+  Bool  New_Profile( RAS_ARGS TStates  aState )
+  {
+    if ( !ras.fProfile )
+    {
+      ras.cProfile  = (PProfile)ras.top;
+      ras.fProfile  = ras.cProfile;
+      ras.top      += AlignProfileSize;
+    }
+
+    if ( ras.top >= ras.maxBuff )
+    {
+      ras.error = Raster_Err_Overflow;
+      return FAILURE;
+    }
+
+    switch ( aState )
+    {
+    case Ascending:
+      ras.cProfile->flow = Flow_Up;
+      FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile ));
+      break;
+
+    case Descending:
+      ras.cProfile->flow = Flow_Down;
+      FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile ));
+      break;
+
+    default:
+      FT_ERROR(( "New_Profile: invalid profile direction!\n" ));
+      ras.error = Raster_Err_Invalid;
+      return FAILURE;
+    }
+
+    ras.cProfile->start  = 0;
+    ras.cProfile->height = 0;
+    ras.cProfile->offset = ras.top;
+    ras.cProfile->link   = (PProfile)0;
+    ras.cProfile->next   = (PProfile)0;
+
+    if ( !ras.gProfile )
+      ras.gProfile = ras.cProfile;
+
+    ras.state = aState;
+    ras.fresh = TRUE;
+    ras.joint = FALSE;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    End_Profile                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Finalizes the current profile.                                     */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS on success.  FAILURE in case of overflow or incoherency.   */
+  /*                                                                       */
+  static
+  Bool  End_Profile( RAS_ARG )
+  {
+    Long      h;
+    PProfile  oldProfile;
+
+
+    h = ras.top - ras.cProfile->offset;
+
+    if ( h < 0 )
+    {
+      FT_ERROR(( "End_Profile: negative height encountered!\n" ));
+      ras.error = Raster_Err_Neg_Height;
+      return FAILURE;
+    }
+
+    if ( h > 0 )
+    {
+      FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n",
+                  (long)ras.cProfile, ras.cProfile->start, h ));
+
+      oldProfile           = ras.cProfile;
+      ras.cProfile->height = h;
+      ras.cProfile         = (PProfile)ras.top;
+
+      ras.top             += AlignProfileSize;
+
+      ras.cProfile->height = 0;
+      ras.cProfile->offset = ras.top;
+      oldProfile->next     = ras.cProfile;
+      ras.num_Profs++;
+    }
+
+    if ( ras.top >= ras.maxBuff )
+    {
+      FT_TRACE1(( "overflow in End_Profile\n" ));
+      ras.error = Raster_Err_Overflow;
+      return FAILURE;
+    }
+
+    ras.joint = FALSE;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Insert_Y_Turn                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Inserts a salient into the sorted list placed on top of the render */
+  /*    pool.                                                              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    New y scanline position.                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS on success.  FAILURE in case of overflow.                  */
+  /*                                                                       */
+  static
+  Bool  Insert_Y_Turn( RAS_ARGS Int  y )
+  {
+    PLong     y_turns;
+    Int       y2, n;
+
+
+    n       = ras.numTurns - 1;
+    y_turns = ras.sizeBuff - ras.numTurns;
+
+    /* look for first y value that is <= */
+    while ( n >= 0 && y < y_turns[n] )
+      n--;
+
+    /* if it is <, simply insert it, ignore if == */
+    if ( n >= 0 && y > y_turns[n] )
+      while ( n >= 0 )
+      {
+        y2 = y_turns[n];
+        y_turns[n] = y;
+        y = y2;
+        n--;
+      }
+
+    if ( n < 0 )
+    {
+      if ( ras.maxBuff <= ras.top )
+      {
+        ras.error = Raster_Err_Overflow;
+        return FAILURE;
+      }
+      ras.maxBuff--;
+      ras.numTurns++;
+      ras.sizeBuff[-ras.numTurns] = y;
+    }
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Finalize_Profile_Table                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Adjusts all links in the profiles list.                            */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS on success.  FAILURE in case of overflow.                  */
+  /*                                                                       */
+  static
+  Bool  Finalize_Profile_Table( RAS_ARG )
+  {
+    Int       bottom, top;
+    UShort    n;
+    PProfile  p;
+
+
+    n = ras.num_Profs;
+
+    if ( n > 1 )
+    {
+      p = ras.fProfile;
+      while ( n > 0 )
+      {
+        if ( n > 1 )
+          p->link = (PProfile)( p->offset + p->height );
+        else
+          p->link = NULL;
+
+        switch ( p->flow )
+        {
+        case Flow_Down:
+          bottom     = p->start - p->height+1;
+          top        = p->start;
+          p->start   = bottom;
+          p->offset += p->height - 1;
+          break;
+
+        case Flow_Up:
+        default:
+          bottom = p->start;
+          top    = p->start + p->height - 1;
+        }
+
+        if ( Insert_Y_Turn( RAS_VARS bottom )   ||
+             Insert_Y_Turn( RAS_VARS top + 1 )  )
+          return FAILURE;
+
+        p = p->link;
+        n--;
+      }
+    }
+    else
+      ras.fProfile = NULL;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Split_Conic                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Subdivides one conic Bezier into two joint sub-arcs in the Bezier  */
+  /*    stack.                                                             */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    None (subdivided Bezier is taken from the top of the stack).       */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    This routine is the `beef' of this component.  It is  _the_ inner  */
+  /*    loop that should be optimized to hell to get the best performance. */
+  /*                                                                       */
+  static
+  void  Split_Conic( TPoint*  base )
+  {
+    Long     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;
+
+    /* hand optimized.  gcc doesn't seem too good at common expression */
+    /* substitution and instruction scheduling ;-)                     */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <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 )
+  {
+    Long  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 + 1 ) >> 1;
+    base[5].x = b = ( base[3].x + d + 1 ) >> 1;
+    c = ( c + d + 1 ) >> 1;
+    base[2].x = a = ( a + c + 1 ) >> 1;
+    base[4].x = b = ( b + c + 1 ) >> 1;
+    base[3].x = ( a + b + 1 ) >> 1;
+
+    base[6].y = base[3].y;
+    c = base[1].y;
+    d = base[2].y;
+    base[1].y = a = ( base[0].y + c + 1 ) >> 1;
+    base[5].y = b = ( base[3].y + d + 1 ) >> 1;
+    c = ( c + d + 1 ) >> 1;
+    base[2].y = a = ( a + c + 1 ) >> 1;
+    base[4].y = b = ( b + c + 1 ) >> 1;
+    base[3].y = ( a + b + 1 ) >> 1;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Line_Up                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the x-coordinates of an ascending line segment and stores */
+  /*    them in the render pool.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    x1   :: The x-coordinate of the segment's start point.             */
+  /*                                                                       */
+  /*    y1   :: The y-coordinate of the segment's start point.             */
+  /*                                                                       */
+  /*    x2   :: The x-coordinate of the segment's end point.               */
+  /*                                                                       */
+  /*    y2   :: The y-coordinate of the segment's end point.               */
+  /*                                                                       */
+  /*    miny :: A lower vertical clipping bound value.                     */
+  /*                                                                       */
+  /*    maxy :: An upper vertical clipping bound value.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS on success, FAILURE on render pool overflow.               */
+  /*                                                                       */
+  static
+  Bool  Line_Up( RAS_ARGS Long  x1, Long  y1,
+                          Long  x2, Long  y2,
+                          Long  miny, Long  maxy )
+  {
+    Long   Dx, Dy;
+    Int    e1, e2, f1, f2, size;     /* XXX: is `Short' sufficient? */
+    Long   Ix, Rx, Ax;
+
+    PLong  top;
+
+
+    Dx = x2 - x1;
+    Dy = y2 - y1;
+
+    if ( Dy <= 0 || y2 < miny || y1 > maxy )
+      return SUCCESS;
+
+    if ( y1 < miny )
+    {
+      /* Take care: miny-y1 can be a very large value; we use     */
+      /*            a slow MulDiv function to avoid clipping bugs */
+      x1 += SMulDiv( Dx, miny - y1, Dy );
+      e1  = TRUNC( miny );
+      f1  = 0;
+    }
+    else
+    {
+      e1 = TRUNC( y1 );
+      f1 = FRAC( y1 );
+    }
+
+    if ( y2 > maxy )
+    {
+      /* x2 += FMulDiv( Dx, maxy - y2, Dy );  UNNECESSARY */
+      e2  = TRUNC( maxy );
+      f2  = 0;
+    }
+    else
+    {
+      e2 = TRUNC( y2 );
+      f2 = FRAC( y2 );
+    }
+
+    if ( f1 > 0 )
+    {
+      if ( e1 == e2 )
+        return SUCCESS;
+      else
+      {
+        x1 += FMulDiv( Dx, ras.precision - f1, Dy );
+        e1 += 1;
+      }
+    }
+    else
+      if ( ras.joint )
+      {
+        ras.top--;
+        ras.joint = FALSE;
+      }
+
+    ras.joint = ( f2 == 0 );
+
+    if ( ras.fresh )
+    {
+      ras.cProfile->start = e1;
+      ras.fresh           = FALSE;
+    }
+
+    size = e2 - e1 + 1;
+    if ( ras.top + size >= ras.maxBuff )
+    {
+      ras.error = Raster_Err_Overflow;
+      return FAILURE;
+    }
+
+    if ( Dx > 0 )
+    {
+      Ix = ( ras.precision * Dx ) / Dy;
+      Rx = ( ras.precision * Dx ) % Dy;
+      Dx = 1;
+    }
+    else
+    {
+      Ix = -( ( ras.precision * -Dx ) / Dy );
+      Rx =    ( ras.precision * -Dx ) % Dy;
+      Dx = -1;
+    }
+
+    Ax  = -Dy;
+    top = ras.top;
+
+    while ( size > 0 )
+    {
+      *top++ = x1;
+
+      x1 += Ix;
+      Ax += Rx;
+      if ( Ax >= 0 )
+      {
+        Ax -= Dy;
+        x1 += Dx;
+      }
+      size--;
+    }
+
+    ras.top = top;
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Line_Down                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the x-coordinates of an descending line segment and       */
+  /*    stores them in the render pool.                                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    x1   :: The x-coordinate of the segment's start point.             */
+  /*                                                                       */
+  /*    y1   :: The y-coordinate of the segment's start point.             */
+  /*                                                                       */
+  /*    x2   :: The x-coordinate of the segment's end point.               */
+  /*                                                                       */
+  /*    y2   :: The y-coordinate of the segment's end point.               */
+  /*                                                                       */
+  /*    miny :: A lower vertical clipping bound value.                     */
+  /*                                                                       */
+  /*    maxy :: An upper vertical clipping bound value.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS on success, FAILURE on render pool overflow.               */
+  /*                                                                       */
+  static
+  Bool  Line_Down( RAS_ARGS Long  x1, Long  y1,
+                            Long  x2, Long  y2,
+                            Long  miny, Long  maxy )
+  {
+    Bool  result, fresh;
+
+
+    fresh  = ras.fresh;
+
+    result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny );
+
+    if ( fresh && !ras.fresh )
+      ras.cProfile->start = -ras.cProfile->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 x-coordinates of an ascending Bezier arc and stores   */
+  /*    them in the render pool.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    degree   :: The degree of the Bezier arc (either 2 or 3).          */
+  /*                                                                       */
+  /*    splitter :: The function to split Bezier arcs.                     */
+  /*                                                                       */
+  /*    miny     :: A lower vertical clipping bound value.                 */
+  /*                                                                       */
+  /*    maxy     :: An upper vertical clipping bound value.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS on success, FAILURE on render pool overflow.               */
+  /*                                                                       */
+  static
+  Bool  Bezier_Up( RAS_ARGS Int        degree,
+                            TSplitter  splitter,
+                            Long       miny,
+                            Long       maxy )
+  {
+    Long   y1, y2, e, e2, e0;
+    Short  f1;
+
+    TPoint*  arc;
+    TPoint*  start_arc;
+
+    PLong top;
+
+
+    arc = ras.arc;
+    y1  = arc[degree].y;
+    y2  = arc[0].y;
+    top = ras.top;
+
+    if ( y2 < miny || y1 > maxy )
+      goto Fin;
+
+    e2 = FLOOR( y2 );
+
+    if ( e2 > maxy )
+      e2 = maxy;
+
+    e0 = miny;
+
+    if ( y1 < miny )
+      e = miny;
+    else
+    {
+      e  = CEILING( y1 );
+      f1 = FRAC( y1 );
+      e0 = e;
+
+      if ( f1 == 0 )
+      {
+        if ( ras.joint )
+        {
+          top--;
+          ras.joint = FALSE;
+        }
+
+        *top++ = arc[degree].x;
+
+        e += ras.precision;
+      }
+    }
+
+    if ( ras.fresh )
+    {
+      ras.cProfile->start = TRUNC( e0 );
+      ras.fresh = FALSE;
+    }
+
+    if ( e2 < e )
+      goto Fin;
+
+    if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
+    {
+      ras.top   = top;
+      ras.error = Raster_Err_Overflow;
+      return FAILURE;
+    }
+
+    start_arc = arc;
+
+    while ( arc >= start_arc && e <= e2 )
+    {
+      ras.joint = FALSE;
+
+      y2 = arc[0].y;
+
+      if ( y2 > e )
+      {
+        y1 = arc[degree].y;
+        if ( y2 - y1 >= ras.precision_step )
+        {
+          splitter( arc );
+          arc += degree;
+        }
+        else
+        {
+          *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x,
+                                            e - y1, y2 - y1 );
+          arc -= degree;
+          e   += ras.precision;
+        }
+      }
+      else
+      {
+        if ( y2 == e )
+        {
+          ras.joint  = TRUE;
+          *top++     = arc[0].x;
+
+          e += ras.precision;
+        }
+        arc -= degree;
+      }
+    }
+
+  Fin:
+    ras.top  = top;
+    ras.arc -= degree;
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Bezier_Down                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Computes the x-coordinates of an descending Bezier arc and stores  */
+  /*    them in the render pool.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    degree   :: The degree of the Bezier arc (either 2 or 3).          */
+  /*                                                                       */
+  /*    splitter :: The function to split Bezier arcs.                     */
+  /*                                                                       */
+  /*    miny     :: A lower vertical clipping bound value.                 */
+  /*                                                                       */
+  /*    maxy     :: An upper vertical clipping bound value.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS on success, FAILURE on render pool overflow.               */
+  /*                                                                       */
+  static
+  Bool  Bezier_Down( RAS_ARGS Int        degree,
+                              TSplitter  splitter,
+                              Long       miny,
+                              Long       maxy )
+  {
+    TPoint*  arc = ras.arc;
+    Bool     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_VARS degree, splitter, -maxy, -miny );
+
+    if ( fresh && !ras.fresh )
+      ras.cProfile->start = -ras.cProfile->start;
+
+    arc[0].y = -arc[0].y;
+    return result;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Line_To                                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Injects a new line segment and adjusts Profiles list.              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*   x :: The x-coordinate of the segment's end point (its start point   */
+  /*        is stored in `LastX').                                         */
+  /*                                                                       */
+  /*   y :: The y-coordinate of the segment's end point (its start point   */
+  /*        is stored in `LastY').                                         */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */
+  /*   profile.                                                            */
+  /*                                                                       */
+  static
+  Bool  Line_To( RAS_ARGS Long  x,
+                          Long  y )
+  {
+    /* First, detect a change of direction */
+
+    switch ( ras.state )
+    {
+    case Unknown:
+      if ( y > ras.lastY )
+      {
+        if ( New_Profile( RAS_VARS Ascending ) )
+          return FAILURE;
+      }
+      else
+      {
+        if ( y < ras.lastY )
+          if ( New_Profile( RAS_VARS Descending ) )
+            return FAILURE;
+      }
+      break;
+
+    case Ascending:
+      if ( y < ras.lastY )
+      {
+        if ( End_Profile( RAS_VAR )             ||
+             New_Profile( RAS_VARS Descending ) )
+          return FAILURE;
+      }
+      break;
+
+    case Descending:
+      if ( y > ras.lastY )
+      {
+        if ( End_Profile( RAS_VAR )            ||
+             New_Profile( RAS_VARS Ascending ) )
+          return FAILURE;
+      }
+      break;
+
+    default:
+      ;
+    }
+
+    /* Then compute the lines */
+
+    switch ( ras.state )
+    {
+    case Ascending:
+      if ( Line_Up ( RAS_VARS ras.lastX, ras.lastY,
+                     x, y, ras.minY, ras.maxY ) )
+        return FAILURE;
+      break;
+
+    case Descending:
+      if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,
+                      x, y, ras.minY, ras.maxY ) )
+        return FAILURE;
+      break;
+
+    default:
+      ;
+    }
+
+    ras.lastX = x;
+    ras.lastY = y;
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Conic_To                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Injects a new conic arc and adjusts the profile list.              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*   cx :: The x-coordinate of the arc's new control point.              */
+  /*                                                                       */
+  /*   cy :: The y-coordinate of the arc's new control point.              */
+  /*                                                                       */
+  /*   x  :: The x-coordinate of the arc's end point (its start point is   */
+  /*         stored in `LastX').                                           */
+  /*                                                                       */
+  /*   y  :: The y-coordinate of the arc's end point (its start point is   */
+  /*         stored in `LastY').                                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */
+  /*   profile.                                                            */
+  /*                                                                       */
+  static
+  Bool  Conic_To( RAS_ARGS Long  cx,
+                           Long  cy,
+                           Long  x,
+                           Long  y )
+  {
+    Long     y1, y2, y3, x3, ymin, ymax;
+    TStates  state_bez;
+
+
+    ras.arc      = ras.arcs;
+    ras.arc[2].x = ras.lastX;
+    ras.arc[2].y = ras.lastY;
+    ras.arc[1].x = cx; ras.arc[1].y = cy;
+    ras.arc[0].x = x;  ras.arc[0].y = y;
+
+    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_VARS state_bez ) )
+            goto Fail;
+        }
+
+        /* now call the appropriate routine */
+        if ( state_bez == Ascending )
+        {
+          if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
+            goto Fail;
+        }
+        else
+          if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
+            goto Fail;
+      }
+
+    } while ( ras.arc >= ras.arcs );
+
+    ras.lastX = x3;
+    ras.lastY = y3;
+
+    return SUCCESS;
+
+  Fail:
+    return FAILURE;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Cubic_To                                                           */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Injects a new cubic arc and adjusts the profile list.              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*   cx1 :: The x-coordinate of the arc's first new control point.       */
+  /*                                                                       */
+  /*   cy1 :: The y-coordinate of the arc's first new control point.       */
+  /*                                                                       */
+  /*   cx2 :: The x-coordinate of the arc's second new control point.      */
+  /*                                                                       */
+  /*   cy2 :: The y-coordinate of the arc's second new control point.      */
+  /*                                                                       */
+  /*   x   :: The x-coordinate of the arc's end point (its start point is  */
+  /*          stored in `LastX').                                          */
+  /*                                                                       */
+  /*   y   :: The y-coordinate of the arc's end point (its start point is  */
+  /*          stored in `LastY').                                          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */
+  /*   profile.                                                            */
+  /*                                                                       */
+  static
+  Bool  Cubic_To( RAS_ARGS Long  cx1,
+                           Long  cy1,
+                           Long  cx2,
+                           Long  cy2,
+                           Long  x,
+                           Long  y )
+  {
+    Long     y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
+    TStates  state_bez;
+
+
+    ras.arc      = ras.arcs;
+    ras.arc[3].x = ras.lastX;
+    ras.arc[3].y = ras.lastY;
+    ras.arc[2].x = cx1; ras.arc[2].y = cy1;
+    ras.arc[1].x = cx2; ras.arc[1].y = cy2;
+    ras.arc[0].x = x;   ras.arc[0].y = y;
+
+    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_VARS state_bez ) )
+            goto Fail;
+        }
+
+        /* compute intersections */
+        if ( state_bez == Ascending )
+        {
+          if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
+            goto Fail;
+        }
+        else
+          if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
+            goto Fail;
+      }
+
+    } while ( ras.arc >= ras.arcs );
+
+    ras.lastX = x4;
+    ras.lastY = y4;
+
+    return SUCCESS;
+
+  Fail:
+    return FAILURE;
+  }
+
+
+#undef  SWAP_
+#define SWAP_( x, y )  do                \
+                       {                 \
+                         Long  swap = x; \
+                                         \
+                                         \
+                         x = y;          \
+                         y = swap;       \
+                       } while ( 0 )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Decompose_Curve                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Scans the outline arays in order to emit individual segments and   */
+  /*    Beziers by calling Line_To() and Bezier_To().  It handles all      */
+  /*    weird cases, like when the first point is off the curve, or when   */
+  /*    there are simply no `on' points in the contour!                    */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    first   :: The index of the first point in the contour.            */
+  /*                                                                       */
+  /*    last    :: The index of the last point in the contour.             */
+  /*                                                                       */
+  /*    flipped :: If set, flip the direction of the curve.                */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS on success, FAILURE on error.                              */
+  /*                                                                       */
+  static
+  Bool  Decompose_Curve( RAS_ARGS UShort  first,
+                                  UShort  last,
+                                  int     flipped )
+  {
+    FT_Vector   v_last;
+    FT_Vector   v_control;
+    FT_Vector   v_start;
+
+    FT_Vector*  points;
+    FT_Vector*  point;
+    FT_Vector*  limit;
+    char*       tags;
+
+    char        tag;       /* current point's state           */
+
+
+    points = ras.outline.points;
+    limit  = points + last;
+
+    v_start.x = SCALED( points[first].x );
+    v_start.y = SCALED( points[first].y );
+    v_last.x  = SCALED( points[last].x );
+    v_last.y  = SCALED( points[last].y );
+
+    if ( flipped )
+    {
+      SWAP_( v_start.x, v_start.y );
+      SWAP_( v_last.x, v_last.y );
+    }
+
+    v_control = v_start;
+
+    point = points + first;
+    tags  = ras.outline.tags  + first;
+    tag   = FT_CURVE_TAG( tags[0] );
+
+    /* A contour cannot start with a cubic control point! */
+    if ( tag == FT_Curve_Tag_Cubic )
+      goto 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( ras.outline.tags[last] ) == FT_Curve_Tag_On )
+      {
+        /* start at last point if it is on the curve */
+        v_start = v_last;
+        limit--;
+      }
+      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;
+      }
+      point--;
+      tags--;
+    }
+
+    ras.lastX = v_start.x;
+    ras.lastY = v_start.y;
+
+    while ( point < limit )
+    {
+      point++;
+      tags++;
+
+      tag = FT_CURVE_TAG( tags[0] );
+
+      switch ( tag )
+      {
+      case FT_Curve_Tag_On:  /* emit a single line_to */
+        {
+          Long  x, y;
+
+
+          x = SCALED( point->x );
+          y = SCALED( point->y );
+          if ( flipped )
+            SWAP_( x, y );
+
+          if ( Line_To( RAS_VARS x, y ) )
+            goto Fail;
+          continue;
+        }
+
+      case FT_Curve_Tag_Conic:  /* consume conic arcs */
+        {
+          v_control.x = SCALED( point[0].x );
+          v_control.y = SCALED( point[0].y );
+
+          if ( flipped )
+            SWAP_( v_control.x, v_control.y );
+
+        Do_Conic:
+          if ( point < limit )
+          {
+            FT_Vector  v_middle;
+            Long       x, y;
+
+
+            point++;
+            tags++;
+            tag = FT_CURVE_TAG( tags[0] );
+
+            x = SCALED( point[0].x );
+            y = SCALED( point[0].y );
+
+            if ( flipped )
+              SWAP_( x, y );
+
+            if ( tag == FT_Curve_Tag_On )
+            {
+              if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) )
+                goto Fail;
+              continue;
+            }
+
+            if ( tag != FT_Curve_Tag_Conic )
+              goto Invalid_Outline;
+
+            v_middle.x = ( v_control.x + x ) / 2;
+            v_middle.y = ( v_control.y + y ) / 2;
+
+            if ( Conic_To( RAS_VARS v_control.x, v_control.y,
+                                    v_middle.x,  v_middle.y ) )
+              goto Fail;
+
+            v_control.x = x;
+            v_control.y = y;
+
+            goto Do_Conic;
+          }
+
+          if ( Conic_To( RAS_VARS v_control.x, v_control.y,
+                                  v_start.x,   v_start.y ) )
+            goto Fail;
+
+          goto Close;
+        }
+
+      default:  /* FT_Curve_Tag_Cubic */
+        {
+          Long  x1, y1, x2, y2, x3, y3;
+
+
+          if ( point + 1 > limit                             ||
+               FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic )
+            goto Invalid_Outline;
+
+          point += 2;
+          tags  += 2;
+
+          x1 = SCALED( point[-2].x );
+          y1 = SCALED( point[-2].y );
+          x2 = SCALED( point[-1].x );
+          y2 = SCALED( point[-1].y );
+          x3 = SCALED( point[ 0].x );
+          y3 = SCALED( point[ 0].y );
+
+          if ( flipped )
+          {
+            SWAP_( x1, y1 );
+            SWAP_( x2, y2 );
+            SWAP_( x3, y3 );
+          }
+
+          if ( point <= limit )
+          {
+            if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) )
+              goto Fail;
+            continue;
+          }
+
+          if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) )
+            goto Fail;
+          goto Close;
+        }
+      }
+    }
+
+    /* close the contour with a line segment */
+    if ( Line_To( RAS_VARS v_start.x, v_start.y ) )
+      goto Fail;
+
+  Close:
+    return SUCCESS;
+
+  Invalid_Outline:
+    ras.error = Raster_Err_Invalid;
+
+  Fail:
+    return FAILURE;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Convert_Glyph                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Converts a glyph into a series of segments and arcs and makes a    */
+  /*    profiles list with them.                                           */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    flipped :: If set, flip the direction of curve.                    */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    SUCCESS on success, FAILURE if any error was encountered during    */
+  /*    rendering.                                                         */
+  /*                                                                       */
+  static
+  Bool  Convert_Glyph( RAS_ARGS int  flipped )
+  {
+    Short     i;
+    UShort    start;
+
+    PProfile  lastProfile;
+
+
+    ras.fProfile = NULL;
+    ras.joint    = FALSE;
+    ras.fresh    = FALSE;
+
+    ras.maxBuff  = ras.sizeBuff - AlignProfileSize;
+
+    ras.numTurns = 0;
+
+    ras.cProfile         = (PProfile)ras.top;
+    ras.cProfile->offset = ras.top;
+    ras.num_Profs        = 0;
+
+    start = 0;
+
+    for ( i = 0; i < ras.outline.n_contours; i++ )
+    {
+      ras.state    = Unknown;
+      ras.gProfile = NULL;
+
+      if ( Decompose_Curve( RAS_VARS start, ras.outline.contours[i], flipped ) )
+        return FAILURE;
+
+      start = ras.outline.contours[i] + 1;
+
+      /* We must now see whether the extreme arcs join or not */
+      if ( FRAC( ras.lastY ) == 0 &&
+           ras.lastY >= ras.minY  &&
+           ras.lastY <= ras.maxY  )
+        if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow )
+          ras.top--;
+        /* Note that ras.gProfile can be nil if the contour was too small */
+        /* to be drawn.                                                   */
+
+      lastProfile = ras.cProfile;
+      if ( End_Profile( RAS_VAR ) )
+        return FAILURE;
+
+      /* close the `next profile in contour' linked list */
+      if ( ras.gProfile )
+        lastProfile->next = ras.gProfile;
+    }
+
+    if ( Finalize_Profile_Table( RAS_VAR ) )
+      return FAILURE;
+
+    return ( ras.top < ras.maxBuff ? SUCCESS : FAILURE );
+  }
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /**                                                                     **/
+  /**  SCAN-LINE SWEEPS AND DRAWING                                       **/
+  /**                                                                     **/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  Init_Linked                                                          */
+  /*                                                                       */
+  /*    Initializes 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;
+    Long       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 get there, unless the profile was not part of */
+    /* the list.                                                     */
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  Update                                                               */
+  /*                                                                       */
+  /*    Update 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.                                                        */
+  /*                                                                       */
+  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 Sweep Procedure Set                                         */
+  /*                                                                       */
+  /*  These four routines are used during the vertical black/white         */
+  /*  sweep phase by the generic Draw_Sweep() function.                    */
+  /*                                                                       */
+  /*************************************************************************/
+
+  static
+  void  Vertical_Sweep_Init( RAS_ARGS Short*  min,
+                                      Short*  max )
+  {
+    Long  pitch = ras.target.pitch;
+
+    UNUSED( max );
+
+
+    ras.traceIncr = (Short)-pitch;
+    ras.traceOfs  = -*min * pitch;
+    if ( pitch > 0 )
+      ras.traceOfs += ( ras.target.rows - 1 ) * pitch;
+
+    ras.gray_min_x = 0;
+    ras.gray_max_x = 0;
+  }
+
+
+  static
+  void  Vertical_Sweep_Span( RAS_ARGS Short       y,
+                                      FT_F26Dot6  x1,
+                                      FT_F26Dot6  x2,
+                                      PProfile    left,
+                                      PProfile    right )
+  {
+    Long   e1, e2;
+    Short  c1, c2;
+    Byte   f1, f2;
+    Byte*  target;
+
+    UNUSED( y );
+    UNUSED( left );
+    UNUSED( right );
+
+
+    /* Drop-out control */
+
+    e1 = TRUNC( CEILING( x1 ) );
+
+    if ( x2 - x1 - ras.precision <= ras.precision_jitter )
+      e2 = e1;
+    else
+      e2 = TRUNC( FLOOR( x2 ) );
+
+    if ( e2 >= 0 && e1 < ras.bWidth )
+    {
+      if ( e1 < 0 )           e1 = 0;
+      if ( e2 >= ras.bWidth ) e2 = ras.bWidth - 1;
+
+      c1 = (Short)( e1 >> 3 );
+      c2 = (Short)( e2 >> 3 );
+
+      f1 =   (unsigned char)0xFF >> ( e1 & 7 );
+      f2 = ~((unsigned char)0x7F >> ( e2 & 7 ));
+
+      if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
+      if ( ras.gray_max_x < c2 ) ras.gray_max_x = c2;
+
+      target = ras.bTarget + ras.traceOfs + 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 );
+    }
+  }
+
+
+  static
+  void Vertical_Sweep_Drop( RAS_ARGS Short       y,
+                                     FT_F26Dot6  x1,
+                                     FT_F26Dot6  x2,
+                                     PProfile    left,
+                                     PProfile    right )
+  {
+    Long   e1, e2;
+    Short  c1, f1;
+
+
+    /* Drop-out control */
+
+    e1 = CEILING( x1 );
+    e2 = FLOOR  ( x2 );
+
+    if ( e1 > e2 )
+    {
+      if ( e1 == e2 + ras.precision )
+      {
+        switch ( ras.dropOutControl )
+        {
+        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 if:          */
+          /*                                                        */
+          /*  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                          */
+          /*                                                        */
+
+          /* FIXXXME: uncommenting this line solves the disappearing */
+          /*          bit problem in the `7' of verdana 10pts, but   */
+          /*          makes a new one in the `C' of arial 14pts      */
+
+#if 0
+          if ( x2 - x1 < ras.precision_half )
+#endif
+          {
+            /* upper stub test */
+            if ( left->next == right && left->height <= 0 )
+              return;
+
+            /* lower stub test */
+            if ( right->next == left && left->start == y )
+              return;
+          }
+
+          /* check that the rightmost pixel isn't set */
+
+          e1 = TRUNC( e1 );
+
+          c1 = (Short)( e1 >> 3 );
+          f1 = e1 &  7;
+
+          if ( e1 >= 0 && e1 < ras.bWidth                      &&
+               ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) )
+            return;
+
+          if ( ras.dropOutControl == 2 )
+            e1 = e2;
+          else
+            e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+
+          break;
+
+        default:
+          return;  /* unsupported mode */
+        }
+      }
+      else
+        return;
+    }
+
+    e1 = TRUNC( e1 );
+
+    if ( e1 >= 0 && e1 < ras.bWidth )
+    {
+      c1 = (Short)( e1 >> 3 );
+      f1 = e1 & 7;
+
+      if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
+      if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1;
+
+      ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
+    }
+  }
+
+
+  static
+  void Vertical_Sweep_Step( RAS_ARG )
+  {
+    ras.traceOfs += ras.traceIncr;
+  }
+
+
+  /***********************************************************************/
+  /*                                                                     */
+  /*  Horizontal Sweep Procedure Set                                     */
+  /*                                                                     */
+  /*  These four routines are used during the horizontal black/white     */
+  /*  sweep phase by the generic Draw_Sweep() function.                  */
+  /*                                                                     */
+  /***********************************************************************/
+
+  static
+  void  Horizontal_Sweep_Init( RAS_ARGS Short*  min,
+                                        Short*  max )
+  {
+    /* nothing, really */
+    UNUSED( raster );
+    UNUSED( min );
+    UNUSED( max );
+  }
+
+
+  static
+  void  Horizontal_Sweep_Span( RAS_ARGS Short       y,
+                                        FT_F26Dot6  x1,
+                                        FT_F26Dot6  x2,
+                                        PProfile    left,
+                                        PProfile    right )
+  {
+    Long   e1, e2;
+    PByte  bits;
+    Byte   f1;
+
+    UNUSED( left );
+    UNUSED( right );
+
+
+    if ( x2 - x1 < ras.precision )
+    {
+      e1 = CEILING( x1 );
+      e2 = FLOOR  ( x2 );
+
+      if ( e1 == e2 )
+      {
+        bits = ras.bTarget + ( y >> 3 );
+        f1   = (Byte)( 0x80 >> ( y & 7 ) );
+
+        e1 = TRUNC( e1 );
+
+        if ( e1 >= 0 && e1 < ras.target.rows )
+        {
+          PByte  p;
+
+
+          p = bits - e1*ras.target.pitch;
+          if ( ras.target.pitch > 0 )
+            p += ( ras.target.rows - 1 ) * ras.target.pitch;
+
+          p[0] |= f1;
+        }
+      }
+    }
+  }
+
+
+  static
+  void  Horizontal_Sweep_Drop( RAS_ARGS Short       y,
+                                        FT_F26Dot6  x1,
+                                        FT_F26Dot6  x2,
+                                        PProfile    left,
+                                        PProfile    right )
+  {
+    Long   e1, e2;
+    PByte  bits;
+    Byte   f1;
+
+
+    /* During the horizontal sweep, we only take care of drop-outs */
+
+    e1 = CEILING( x1 );
+    e2 = FLOOR  ( x2 );
+
+    if ( e1 > e2 )
+    {
+      if ( e1 == e2 + ras.precision )
+      {
+        switch ( ras.dropOutControl )
+        {
+        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'.    */
+          /*                                                        */
+
+          /* rightmost stub test */
+          if ( left->next == right && left->height <= 0 )
+            return;
+
+          /* leftmost stub test */
+          if ( right->next == left && left->start == y )
+            return;
+
+          /* check that the rightmost pixel isn't set */
+
+          e1 = TRUNC( e1 );
+
+          bits = ras.bTarget + ( y >> 3 );
+          f1   = (Byte)( 0x80 >> ( y & 7 ) );
+
+          bits -= e1 * ras.target.pitch;
+          if ( ras.target.pitch > 0 )
+            bits += ( ras.target.rows - 1 ) * ras.target.pitch;
+
+          if ( e1 >= 0              &&
+               e1 < ras.target.rows &&
+               *bits & f1 )
+            return;
+
+          if ( ras.dropOutControl == 2 )
+            e1 = e2;
+          else
+            e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+
+          break;
+
+        default:
+          return;  /* unsupported mode */
+        }
+      }
+      else
+        return;
+    }
+
+    bits = ras.bTarget + ( y >> 3 );
+    f1   = (Byte)( 0x80 >> ( y & 7 ) );
+
+    e1 = TRUNC( e1 );
+
+    if ( e1 >= 0 && e1 < ras.target.rows )
+    {
+      bits -= e1 * ras.target.pitch;
+      if ( ras.target.pitch > 0 )
+        bits += ( ras.target.rows - 1 ) * ras.target.pitch;
+
+      bits[0] |= f1;
+    }
+  }
+
+
+  static
+  void Horizontal_Sweep_Step( RAS_ARG )
+  {
+    /* Nothing, really */
+    UNUSED( raster );
+  }
+
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIASING
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  Vertical Gray Sweep Procedure Set                                    */
+  /*                                                                       */
+  /*  These two routines are used during the vertical gray-levels sweep    */
+  /*  phase by the generic Draw_Sweep() function.                          */
+  /*                                                                       */
+  /*  NOTES                                                                */
+  /*                                                                       */
+  /*  - The target pixmap's width *must* be a multiple of 4.               */
+  /*                                                                       */
+  /*  - You have to use the function Vertical_Sweep_Span() for the gray    */
+  /*    span call.                                                         */
+  /*                                                                       */
+  /*************************************************************************/
+
+  static
+  void  Vertical_Gray_Sweep_Init( RAS_ARGS Short*  min,
+                                           Short*  max )
+  {
+    Long  pitch, byte_len;
+
+
+    *min = *min & -2;
+    *max = ( *max + 3 ) & -2;
+
+    ras.traceOfs  = 0;
+    pitch         = ras.target.pitch;
+    byte_len      = -pitch;
+    ras.traceIncr = (Short)byte_len;
+    ras.traceG    = ( *min / 2 ) * byte_len;
+
+    if ( pitch > 0 )
+    {
+      ras.traceG += ( ras.target.rows - 1 ) * pitch;
+      byte_len    = -byte_len;
+    }
+
+    ras.gray_min_x =  (Short)byte_len;
+    ras.gray_max_x = -(Short)byte_len;
+  }
+
+
+  static
+  void  Vertical_Gray_Sweep_Step( RAS_ARG )
+  {
+    Int    c1, c2;
+    PByte  pix, bit, bit2;
+    Int*   count = ras.count_table;
+    Byte*  grays;
+
+
+    ras.traceOfs += ras.gray_width;
+
+    if ( ras.traceOfs > ras.gray_width )
+    {
+      pix   = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
+      grays = ras.grays;
+
+      if ( ras.gray_max_x >= 0 )
+      {
+        Long   last_pixel = ras.target.width - 1;
+        Int    last_cell  = last_pixel >> 2;
+        Int    last_bit   = last_pixel & 3;
+        Bool   over       = 0;
+
+        if ( ras.gray_max_x >= last_cell && last_bit != 3 )
+        {
+          ras.gray_max_x = last_cell - 1;
+          over = 1;
+        }
+
+        if ( ras.gray_min_x < 0 )
+          ras.gray_min_x = 0;
+
+        bit   = ras.bTarget + ras.gray_min_x;
+        bit2  = bit + ras.gray_width;
+
+        c1 = ras.gray_max_x - ras.gray_min_x;
+
+        while ( c1 >= 0 )
+        {
+          c2 = count[*bit] + count[*bit2];
+
+          if ( c2 )
+          {
+            pix[0] = grays[(c2 >> 12) & 0x000F];
+            pix[1] = grays[(c2 >> 8 ) & 0x000F];
+            pix[2] = grays[(c2 >> 4 ) & 0x000F];
+            pix[3] = grays[ c2        & 0x000F];
+
+            *bit  = 0;
+            *bit2 = 0;
+          }
+
+          bit++;
+          bit2++;
+          pix += 4;
+          c1--;
+        }
+
+        if ( over )
+        {
+          c2 = count[*bit] + count[*bit2];
+          if ( c2 )
+          {
+            switch ( last_bit )
+            {
+            case 2:
+              pix[2] = grays[(c2 >> 4 ) & 0x000F];
+            case 1:
+              pix[1] = grays[(c2 >> 8 ) & 0x000F];
+            default:
+              pix[0] = grays[(c2 >> 12) & 0x000F];
+            }
+
+            *bit  = 0;
+            *bit2 = 0;
+          }
+        }
+      }
+
+      ras.traceOfs = 0;
+      ras.traceG  += ras.traceIncr;
+
+      ras.gray_min_x =  32000;
+      ras.gray_max_x = -32000;
+    }
+  }
+
+
+  static
+  void  Horizontal_Gray_Sweep_Span( RAS_ARGS Short       y,
+                                             FT_F26Dot6  x1,
+                                             FT_F26Dot6  x2,
+                                             PProfile    left,
+                                             PProfile    right )
+  {
+    /* nothing, really */
+    UNUSED( raster );
+    UNUSED( y );
+    UNUSED( x1 );
+    UNUSED( x2 );
+    UNUSED( left );
+    UNUSED( right );
+  }
+
+
+  static
+  void  Horizontal_Gray_Sweep_Drop( RAS_ARGS Short       y,
+                                             FT_F26Dot6  x1,
+                                             FT_F26Dot6  x2,
+                                             PProfile    left,
+                                             PProfile    right )
+  {
+    Long   e1, e2;
+    PByte  pixel;
+    Byte   color;
+
+
+    /* During the horizontal sweep, we only take care of drop-outs */
+    e1 = CEILING( x1 );
+    e2 = FLOOR  ( x2 );
+
+    if ( e1 > e2 )
+    {
+      if ( e1 == e2 + ras.precision )
+      {
+        switch ( ras.dropOutControl )
+        {
+        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'.    */
+          /*                                                        */
+
+          /* rightmost stub test */
+          if ( left->next == right && left->height <= 0 )
+            return;
+
+          /* leftmost stub test */
+          if ( right->next == left && left->start == y )
+            return;
+
+          if ( ras.dropOutControl == 2 )
+            e1 = e2;
+          else
+            e1 = CEILING( ( x1 + x2 + 1 ) / 2 );
+
+          break;
+
+        default:
+          return;  /* unsupported mode */
+        }
+      }
+      else
+        return;
+    }
+
+    if ( e1 >= 0 )
+    {
+      if ( x2 - x1 >= ras.precision_half )
+        color = ras.grays[2];
+      else
+        color = ras.grays[1];
+
+      e1 = TRUNC( e1 ) / 2;
+      if ( e1 < ras.target.rows )
+      {
+        pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;
+        if ( ras.target.pitch > 0 )
+          pixel += ( ras.target.rows - 1 ) * ras.target.pitch;
+
+        if ( pixel[0] == ras.grays[0] )
+          pixel[0] = color;
+      }
+    }
+  }
+
+
+#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  Generic Sweep Drawing routine                                        */
+  /*                                                                       */
+  /*************************************************************************/
+
+  static
+  Bool  Draw_Sweep( RAS_ARG )
+  {
+    Short  y, y_change, y_height;
+
+    PProfile  P, Q, P_Left, P_Right;
+
+    Short  min_Y, max_Y, top, bottom, dropouts;
+
+    Long  x1, x2, xs, e1, e2;
+
+    TProfileList  wait;
+    TProfileList  draw_left, draw_right;
+
+
+    /* Init empty linked lists */
+
+    Init_Linked( &wait );
+
+    Init_Linked( &draw_left  );
+    Init_Linked( &draw_right );
+
+    /* first, compute min and max Y */
+
+    P     = ras.fProfile;
+    max_Y = (short)TRUNC( ras.minY );
+    min_Y = (short)TRUNC( ras.maxY );
+
+    while ( P )
+    {
+      Q = P->link;
+
+      bottom = (Short)P->start;
+      top    = (Short)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 Y-turns */
+    if ( ras.numTurns == 0 )
+    {
+      ras.error = Raster_Err_Invalid;
+      return FAILURE;
+    }
+
+    /* Now inits the sweep */
+
+    ras.Proc_Sweep_Init( RAS_VARS &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.numTurns > 0 &&
+         ras.sizeBuff[-ras.numTurns] == min_Y )
+      ras.numTurns--;
+
+    while ( ras.numTurns > 0 )
+    {
+      /* look in the wait list for new activations */
+
+      P = wait;
+
+      while ( P )
+      {
+        Q = P->link;
+        P->countL -= y_height;
+        if ( P->countL == 0 )
+        {
+          DelOld( &wait, P );
+
+          switch ( P->flow )
+          {
+          case Flow_Up:
+            InsNew( &draw_left,  P );
+            break;
+
+          case Flow_Down:
+            InsNew( &draw_right, P );
+            break;
+          }
+        }
+
+        P = Q;
+      }
+
+      /* Sort the drawing lists */
+
+      Sort( &draw_left );
+      Sort( &draw_right );
+
+      y_change = (Short)ras.sizeBuff[-ras.numTurns--];
+      y_height = y_change - y;
+
+      while ( y < y_change )
+      {
+        /* Let's trace */
+
+        dropouts = 0;
+
+        P_Left  = draw_left;
+        P_Right = draw_right;
+
+        while ( P_Left )
+        {
+          x1 = P_Left ->X;
+          x2 = P_Right->X;
+
+          if ( x1 > x2 )
+          {
+            xs = x1;
+            x1 = x2;
+            x2 = xs;
+          }
+
+          if ( x2 - x1 <= ras.precision )
+          {
+            e1 = FLOOR( x1 );
+            e2 = CEILING( x2 );
+
+            if ( ras.dropOutControl != 0                 &&
+                 ( e1 > e2 || e2 == e1 + ras.precision ) )
+            {
+              /* a drop out was detected */
+
+              P_Left ->X = x1;
+              P_Right->X = x2;
+
+              /* mark profile for drop-out processing */
+              P_Left->countL = 1;
+              dropouts++;
+
+              goto Skip_To_Next;
+            }
+          }
+
+          ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right );
+
+        Skip_To_Next:
+
+          P_Left  = P_Left->link;
+          P_Right = P_Right->link;
+        }
+
+        /* 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.Proc_Sweep_Step( RAS_VAR );
+
+        y++;
+
+        if ( y < y_change )
+        {
+          Sort( &draw_left  );
+          Sort( &draw_right );
+        }
+      }
+
+      /* Now finalize the profiles that needs it */
+
+      {
+        PProfile  Q, P;
+
+
+        P = draw_left;
+        while ( P )
+        {
+          Q = P->link;
+          if ( P->height == 0 )
+            DelOld( &draw_left, P );
+          P = Q;
+        }
+      }
+
+      {
+        PProfile  Q, P = draw_right;
+
+
+        while ( P )
+        {
+          Q = P->link;
+          if ( P->height == 0 )
+            DelOld( &draw_right, P );
+          P = Q;
+        }
+      }
+    }
+
+    /* for gray-scaling, flushes the bitmap scanline cache */
+    while ( y <= max_Y )
+    {
+      ras.Proc_Sweep_Step( RAS_VAR );
+      y++;
+    }
+
+    return SUCCESS;
+
+  Scan_DropOuts:
+
+    P_Left  = draw_left;
+    P_Right = draw_right;
+
+    while ( P_Left )
+    {
+      if ( P_Left->countL )
+      {
+        P_Left->countL = 0;
+#if 0
+        dropouts--;  /* -- this is useful when debugging only */
+#endif
+        ras.Proc_Sweep_Drop( RAS_VARS y,
+                                      P_Left->X,
+                                      P_Right->X,
+                                      P_Left,
+                                      P_Right );
+      }
+
+      P_Left  = P_Left->link;
+      P_Right = P_Right->link;
+    }
+
+    goto Next_Line;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Render_Single_Pass                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Performs one sweep with sub-banding.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    flipped :: If set, flip the direction of the outline.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    Renderer error code.                                               */
+  /*                                                                       */
+  static
+  int  Render_Single_Pass( RAS_ARGS Bool  flipped )
+  {
+    Short  i, j, k;
+
+
+    while ( ras.band_top >= 0 )
+    {
+      ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision;
+      ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision;
+
+      ras.top = ras.buff;
+
+      ras.error = Raster_Err_None;
+
+      if ( Convert_Glyph( RAS_VARS flipped ) )
+      {
+        if ( ras.error != Raster_Err_Overflow )
+          return FAILURE;
+
+        ras.error = Raster_Err_None;
+
+        /* sub-banding */
+
+#ifdef DEBUG_RASTER
+        ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) );
+#endif
+
+        i = ras.band_stack[ras.band_top].y_min;
+        j = ras.band_stack[ras.band_top].y_max;
+
+        k = ( i + j ) / 2;
+
+        if ( ras.band_top >= 7 || k < i )
+        {
+          ras.band_top = 0;
+          ras.error    = Raster_Err_Invalid;
+
+          return ras.error;
+        }
+
+        ras.band_stack[ras.band_top + 1].y_min = k;
+        ras.band_stack[ras.band_top + 1].y_max = j;
+
+        ras.band_stack[ras.band_top].y_max = k - 1;
+
+        ras.band_top++;
+      }
+      else
+      {
+        if ( ras.fProfile )
+          if ( Draw_Sweep( RAS_VAR ) )
+             return ras.error;
+        ras.band_top--;
+      }
+    }
+
+    return SUCCESS;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Render_Glyph                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Renders a glyph in a bitmap.  Sub-banding if needed.               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  /* XXX Fixme: ftraster's error codes don't harmonize with FT2's ones!    */
+  /*                                                                       */
+  LOCAL_FUNC
+  FT_Error  Render_Glyph( RAS_ARG )
+  {
+    FT_Error  error;
+
+
+    Set_High_Precision( RAS_VARS ras.outline.flags &
+                        ft_outline_high_precision );
+    ras.scale_shift    = ras.precision_shift;
+    ras.dropOutControl = 2;
+    ras.second_pass    = !( ras.outline.flags & ft_outline_single_pass );
+
+    /* Vertical Sweep */
+    ras.Proc_Sweep_Init = Vertical_Sweep_Init;
+    ras.Proc_Sweep_Span = Vertical_Sweep_Span;
+    ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
+    ras.Proc_Sweep_Step = Vertical_Sweep_Step;
+
+    ras.band_top            = 0;
+    ras.band_stack[0].y_min = 0;
+    ras.band_stack[0].y_max = ras.target.rows - 1;
+
+    ras.bWidth  = ras.target.width;
+    ras.bTarget = (Byte*)ras.target.buffer;
+
+    if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 )
+      return error;
+
+    /* Horizontal Sweep */
+    if ( ras.second_pass && ras.dropOutControl != 0 )
+    {
+      ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
+      ras.Proc_Sweep_Span = Horizontal_Sweep_Span;
+      ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop;
+      ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
+
+      ras.band_top            = 0;
+      ras.band_stack[0].y_min = 0;
+      ras.band_stack[0].y_max = ras.target.width - 1;
+
+      if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 )
+        return error;
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+#ifdef FT_RASTER_OPTION_ANTI_ALIASING
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    Render_Gray_Glyph                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Renders a glyph with grayscaling.  Sub-banding if needed.          */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  LOCAL_FUNC
+  FT_Error  Render_Gray_Glyph( RAS_ARG )
+  {
+    Long      pixel_width;
+    FT_Error  error;
+
+
+    Set_High_Precision( RAS_VARS ras.outline.flags &
+                        ft_outline_high_precision );
+    ras.scale_shift    = ras.precision_shift + 1;
+    ras.dropOutControl = 2;
+    ras.second_pass    = !( ras.outline.flags & ft_outline_single_pass );
+
+
+    /* Vertical Sweep */
+
+    ras.band_top            = 0;
+    ras.band_stack[0].y_min = 0;
+    ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
+
+    ras.bWidth  = ras.gray_width;
+    pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );
+
+    if ( ras.bWidth > pixel_width )
+      ras.bWidth = pixel_width;
+
+    ras.bWidth  = ras.bWidth * 8;
+    ras.bTarget = (Byte*)ras.gray_lines;
+    ras.gTarget = (Byte*)ras.target.buffer;
+
+    ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;
+    ras.Proc_Sweep_Span = Vertical_Sweep_Span;
+    ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
+    ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;
+
+    error = Render_Single_Pass( RAS_VARS 0 );
+    if (error)
+      return error;
+
+    /* Horizontal Sweep */
+    if ( ras.second_pass && ras.dropOutControl != 0 )
+    {
+      ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
+      ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
+      ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;
+      ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
+
+      ras.band_top            = 0;
+      ras.band_stack[0].y_min = 0;
+      ras.band_stack[0].y_max = ras.target.width * 2 - 1;
+
+      error = Render_Single_Pass( RAS_VARS 1 );
+      if (error)
+        return error;
+    }
+
+    return FT_Err_Ok;
+  }
+
+#else /* FT_RASTER_OPTION_ANTI_ALIASING */
+
+  LOCAL_FUNC
+  FT_Error  Render_Gray_Glyph( RAS_ARG )
+  {
+    UNUSED_RASTER;
+    return Raster_Err_Unsupported;
+  }
+
+#endif
+
+
+  static
+  void  ft_black_init( TRaster_Instance*  raster )
+  {
+    FT_UInt  n;
+    FT_ULong c;
+
+    /* setup count table */
+    for ( n = 0; n < 256; n++ )
+    {
+      c = ( n & 0x55 ) + ( ( n & 0xAA ) >> 1 );
+
+      c = ( ( c << 6 ) & 0x3000 ) |
+          ( ( c << 4 ) & 0x0300 ) |
+          ( ( c << 2 ) & 0x0030 ) |
+                   (c  & 0x0003 );
+
+      raster->count_table[n] = c;
+    }
+
+    /* set default 5-levels gray palette */
+    for ( n = 0; n < 5; n++ )
+      raster->grays[n] = n * 255 / 4;
+
+    raster->gray_width = RASTER_GRAY_LINES / 2;
+  }
+
+  /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/
+  /****                         a static object.                  *****/
+
+#ifdef _STANDALONE_
+
+
+  static
+  int  ft_black_new( void*  memory,
+                     FT_Raster *araster )
+  {
+     static FT_RasterRec_  the_raster;
+
+
+     *araster = &the_raster;
+     memset( &the_raster, sizeof ( the_raster ), 0 );
+     ft_black_init( &the_raster );
+
+     return 0;
+  }
+
+
+  static
+  void  ft_black_done( FT_Raster  raster )
+  {
+    /* nothing */
+    raster->init = 0;
+  }
+
+
+#else /* _STANDALONE_ */
+
+
+  static
+  int  ft_black_new( FT_Memory           memory,
+                     TRaster_Instance**  araster )
+  {
+    FT_Error           error;
+    TRaster_Instance*  raster;
+
+
+    *araster = 0;
+    if ( !ALLOC( raster, sizeof ( *raster ) ) )
+    {
+      raster->memory = memory;
+      ft_black_init( raster );
+
+      *araster = raster;
+    }
+
+    return error;
+  }
+
+
+  static
+  void ft_black_done( TRaster_Instance*  raster )
+  {
+    FT_Memory  memory = (FT_Memory)raster->memory;
+    FREE( raster );
+  }
+
+
+#endif /* _STANDALONE_ */
+
+
+  static
+  void ft_black_reset( TRaster_Instance* raster,
+                       const char*       pool_base,
+                       long              pool_size )
+  {
+    if ( raster && pool_base && pool_size >= 4096 )
+    {
+      /* save the pool */
+      raster->buff     = (PLong)pool_base;
+      raster->sizeBuff = raster->buff + pool_size / sizeof ( Long );
+    }
+  }
+
+
+  static
+  void ft_black_set_mode( TRaster_Instance* raster,
+                          unsigned long     mode,
+                          const char*       palette )
+  {
+    if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
+    {
+      /* set 5-levels gray palette */
+      raster->grays[0] = palette[0];
+      raster->grays[1] = palette[1];
+      raster->grays[2] = palette[2];
+      raster->grays[3] = palette[3];
+      raster->grays[4] = palette[4];
+    }
+  }
+
+
+  static
+  int  ft_black_render( TRaster_Instance*  raster,
+                        FT_Raster_Params*  params )
+  {
+    FT_Outline*  outline    = (FT_Outline*)params->source;
+    FT_Bitmap*   target_map = params->target;
+
+
+    if ( !raster || !raster->buff || !raster->sizeBuff )
+      return Raster_Err_Not_Ini;
+
+    if ( !outline || !outline->contours || !outline->points )
+      return Raster_Err_Invalid;
+
+    /* return immediately if the outline is empty */
+    if ( outline->n_points == 0 || outline->n_contours <= 0 )
+      return Raster_Err_None;
+
+    if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 )
+      return Raster_Err_Invalid;
+
+    if ( !target_map || !target_map->buffer )
+      return Raster_Err_Invalid;
+
+    /* this version of the raster does not support direct rendering, sorry */
+    if ( params->flags & ft_raster_flag_direct )
+      return Raster_Err_Unsupported;
+
+    ras.outline  = *outline;
+    ras.target   = *target_map;
+
+    return ( params->flags & ft_raster_flag_aa
+               ? Render_Gray_Glyph( raster )
+               : Render_Glyph( raster ) );
+  }
+
+
+  FT_Raster_Funcs  ft_standard_raster =
+  {
+    ft_glyph_format_outline,
+    (FT_Raster_New_Func)     ft_black_new,
+    (FT_Raster_Reset_Func)   ft_black_reset,
+    (FT_Raster_Set_Mode_Func)ft_black_set_mode,
+    (FT_Raster_Render_Func)  ft_black_render,
+    (FT_Raster_Done_Func)    ft_black_done
+  };
+
+
+/* END */
--- /dev/null
+++ b/src/renderer/ftraster.h
@@ -1,0 +1,48 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftraster.h                                                             */
+/*                                                                         */
+/*    The FreeType glyph rasterizer (specification).                       */
+/*                                                                         */
+/*  Copyright 1996-2000 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used        */
+/*  modified and distributed under the terms of the FreeType project       */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef FTRASTER_H
+#define FTRASTER_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+#include <freetype/ftimage.h>
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Uncomment the following line if you are using ftraster.c as a         */
+  /* standalone module, fully independent of FreeType.                     */
+  /*                                                                       */
+/* #define _STANDALONE_ */
+
+#ifndef FT_EXPORT_VAR
+#define FT_EXPORT_VAR(x)  extern x
+#endif
+
+  FT_EXPORT_VAR(FT_Raster_Funcs)  ft_standard_raster;
+
+#ifdef __cplusplus
+  }
+#endif
+
+#endif /* FTRASTER_H */
+
+
+/* END */
--- /dev/null
+++ b/src/renderer/ftrender.c
@@ -1,0 +1,161 @@
+#include <freetype/internal/ftobjs.h>
+
+ /* sets render-specific mode */
+  static  FT_Error  ft_renderer_set_mode( FT_Renderer  render,
+                                          FT_ULong     mode_tag,
+                                          FT_Pointer   data )
+  {
+    /* we simply pass it to the raster */
+    return render->clazz->raster_class->raster_set_mode(
+                    render->raster, mode_tag, data );
+  }                                          
+
+
+ /* convert a slot's glyph image into a bitmap */
+  static  FT_Error  ft_renderer_render( FT_Renderer  render,
+                                        FT_GlyphSlot slot,
+                                        FT_UInt      mode )
+  {
+    FT_Error     error;
+    FT_Outline*  outline;
+    FT_BBox      cbox;
+    FT_UInt      width, height, pitch;
+    FT_Bitmap*   bitmap;
+    FT_Memory    memory;
+    
+    FT_Raster_Params  params;
+    
+    /* first of all, transform the outline */
+    if (slot->format != ft_glyph_format_outline)
+    {
+      error = FT_Err_Invalid_Argument;
+      goto Exit;
+    }
+    
+    outline = &slot->outline;
+    
+    FT_Outline_Transform( outline, &slot->transform_matrix );
+    FT_Outline_Translate( outline, slot->transform_delta.x,
+                                   slot->transform_delta.y );
+    
+    /* compute the control box, and grid fit it */
+    FT_Outline_Get_CBox( outline, &cbox );
+    
+    cbox.xMin &= -64;
+    cbox.yMin &= -64;
+    cbox.xMax  = (cbox.xMax+63) & -64;
+    cbox.yMax  = (cbox.yMax+63) & -64;
+
+    width  = (cbox.xMax - cbox.xMin) >> 6;
+    height = (cbox.yMax - cbox.yMin) >> 6;
+    bitmap = &slot->bitmap;
+    memory = slot->face->memory;
+    
+    /* release old bitmap buffer */
+    if ((slot->flags & ft_glyph_own_bitmap))
+      FREE(bitmap->buffer);
+      
+    /* allocate new one, depends on pixel format */
+    if ( mode & ft_render_mode_antialias )
+    {
+      pitch = width;
+      bitmap->pixel_mode = ft_pixel_mode_grays;
+      bitmap->num_grays  = 256;
+    }
+    else
+    {
+      pitch  = (width+7) >> 3;
+      bitmap->pixel_mode = ft_pixel_mode_mono;
+    }
+
+    bitmap->width = width;
+    bitmap->rows  = height;
+    bitmap->pitch = pitch;
+    
+    if (ALLOC( bitmap->buffer, (FT_ULong)pitch * height ))
+      goto Exit;
+
+    /* translate outline to render it into the bitmap */
+    FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin );
+
+    /* set up parameters */
+    params.target = bitmap;
+    params.source = outline;
+    params.flags  = 0;
+
+    if ( bitmap->pixel_mode == ft_pixel_mode_grays )
+      params.flags |= ft_raster_flag_aa;
+
+    /* render outline into the bitmap */
+    error = render->render( render->raster, &params );
+    if (error) goto Exit;
+    
+    slot->format = ft_glyph_format_bitmap;
+    slot->bitmap_left = cbox.xMin >> 6;
+    slot->bitmap_top  = cbox.yMax >> 6;
+    
+  Exit:
+    return error;
+  }
+
+#ifndef  FT_CONFIG_OPTION_NO_STD_RASTER
+
+#include <freetype/ftraster.h>
+
+  const FT_Renderer_Class   ft_standard_renderer_class =
+  {
+    {
+      ft_module_renderer,
+      sizeof( FT_RendererRec ),
+      
+      "standard renderer",
+      0x10000,
+      0x20000,
+      
+      0,    /* module specific interface */
+      
+      (FT_Module_Constructor)  0,
+      (FT_Module_Destructor)   0,
+      (FT_Module_Requester)    0
+    },
+    
+    ft_glyph_format_outline,
+    
+    (FTRenderer_render)       ft_renderer_render,
+    (FTRenderer_setMode)      ft_renderer_set_mode,
+    
+    (FT_Raster_Funcs*)        &ft_standard_raster
+  };
+  
+#endif /* !FT_CONFIG_OPTION_NO_STD_RASTER */
+
+#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER
+
+#include <freetype/ftgrays.h>
+
+  const FT_Renderer_Class  ft_smooth_renderer_class =
+  {
+    {
+      ft_module_renderer,
+      sizeof( FT_RendererRec ),
+      
+      "smooth renderer",
+      0x10000,
+      0x20000,
+      
+      0,    /* module specific interface */
+      
+      (FT_Module_Constructor)  0,
+      (FT_Module_Destructor)   0,
+      (FT_Module_Requester)    0
+    },
+
+    ft_glyph_format_outline,
+    
+    (FTRenderer_render)       ft_renderer_render,
+    (FTRenderer_setMode)      ft_renderer_set_mode,
+    
+    (FT_Raster_Funcs*)        &ft_grays_raster
+  };
+
+#endif /* !FT_CONFIG_OPTION_NO_SMOOTH_RASTER */
--- /dev/null
+++ b/src/renderer/module.mk
@@ -1,0 +1,11 @@
+make_module_list: add_renderer_module
+
+# XXX: important, the standard renderer *MUST* be first on this list..
+#
+add_renderer_module:
+	$(OPEN_DRIVER)ft_standard_renderer_class$(CLOSE_DRIVER)
+	$(ECHO_DRIVER)standard  $(ECHO_DRIVER_DESC)standard outline renderer module$(ECHO_DRIVER_DONE)
+	$(OPEN_DRIVER)ft_smooth_renderer_class$(CLOSE_DRIVER)
+	$(ECHO_DRIVER)smooth    $(ECHO_DRIVER_DESC)smooth outline renderer module$(ECHO_DRIVER_DONE)
+
+# EOF
--- /dev/null
+++ b/src/renderer/renderer.c
@@ -1,0 +1,219 @@
+#include <freetype/internal/ftobjs.h>
+
+ /* initialise renderer - init its raster */
+  static FT_Error ft_renderer_init( FT_Renderer  render )
+  {
+    FT_Library  library = FT_MODULE_LIBRARY(render);
+    
+    render->clazz->raster_class->raster_reset( render->raster,
+        library->raster_pool, library->raster_pool_size );
+
+    return 0;
+  }
+  
+
+
+ /* sets render-specific mode */
+  static  FT_Error  ft_renderer_set_mode( FT_Renderer  render,
+                                          FT_ULong     mode_tag,
+                                          FT_Pointer   data )
+  {
+    /* we simply pass it to the raster */
+    return render->clazz->raster_class->raster_set_mode(
+                    render->raster, mode_tag, data );
+  }                                          
+
+ /* transform a given glyph image */
+  static  FT_Error  ft_renderer_transform( FT_Renderer   render,
+                                           FT_GlyphSlot  slot,
+                                           FT_Matrix*    matrix,
+                                           FT_Vector*    delta )
+  {
+    FT_Error error = FT_Err_Ok;
+    
+    if (slot->format != render->glyph_format)
+    {
+      error = FT_Err_Invalid_Argument;
+      goto Exit;
+    }
+    
+    if (matrix)
+      FT_Outline_Transform( &slot->outline, matrix );
+      
+    if (delta)
+      FT_Outline_Translate( &slot->outline, delta->x, delta->y );
+    
+  Exit:
+    return error;
+  }
+
+ /* return the glyph's control box */
+  static  void  ft_renderer_get_cbox( FT_Renderer   render,
+                                      FT_GlyphSlot  slot,
+                                      FT_BBox      *cbox )
+  {
+    MEM_Set( cbox, 0, sizeof(*cbox) );
+
+    if (slot->format == render->glyph_format)
+      FT_Outline_Get_CBox( &slot->outline, cbox );
+  }                                      
+  
+
+ /* convert a slot's glyph image into a bitmap */
+  static  FT_Error  ft_renderer_render( FT_Renderer  render,
+                                        FT_GlyphSlot slot,
+                                        FT_UInt      mode,
+                                        FT_Vector*   origin )
+  {
+    FT_Error     error;
+    FT_Outline*  outline;
+    FT_BBox      cbox;
+    FT_UInt      width, height, pitch;
+    FT_Bitmap*   bitmap;
+    FT_Memory    memory;
+    
+    FT_Raster_Params  params;
+    
+    /* check glyph image format */
+    if (slot->format != render->glyph_format)
+    {
+      error = FT_Err_Invalid_Argument;
+      goto Exit;
+    }
+    
+    outline = &slot->outline;
+    
+    /* translate the outline to the new origin if needed */
+    if (origin)
+      FT_Outline_Translate( outline, origin->x, origin->y );
+    
+    /* compute the control box, and grid fit it */
+    FT_Outline_Get_CBox( outline, &cbox );
+    
+    cbox.xMin &= -64;
+    cbox.yMin &= -64;
+    cbox.xMax  = (cbox.xMax+63) & -64;
+    cbox.yMax  = (cbox.yMax+63) & -64;
+
+    width  = (cbox.xMax - cbox.xMin) >> 6;
+    height = (cbox.yMax - cbox.yMin) >> 6;
+    bitmap = &slot->bitmap;
+    memory = slot->face->memory;
+    
+    /* release old bitmap buffer */
+    if ((slot->flags & ft_glyph_own_bitmap))
+    {
+      FREE(bitmap->buffer);
+      slot->flags &= ~ft_glyph_own_bitmap;
+    }
+      
+    /* allocate new one, depends on pixel format */
+    if ( mode & ft_render_mode_antialias )
+    {
+      pitch = width;
+      bitmap->pixel_mode = ft_pixel_mode_grays;
+      bitmap->num_grays  = 256;
+    }
+    else
+    {
+      pitch  = (width+7) >> 3;
+      bitmap->pixel_mode = ft_pixel_mode_mono;
+    }
+
+    bitmap->width = width;
+    bitmap->rows  = height;
+    bitmap->pitch = pitch;
+    
+    if (ALLOC( bitmap->buffer, (FT_ULong)pitch * height ))
+      goto Exit;
+
+    slot->flags |= ft_glyph_own_bitmap;
+    
+    /* translate outline to render it into the bitmap */
+    FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin );
+
+    /* set up parameters */
+    params.target = bitmap;
+    params.source = outline;
+    params.flags  = 0;
+
+    if ( bitmap->pixel_mode == ft_pixel_mode_grays )
+      params.flags |= ft_raster_flag_aa;
+
+    /* render outline into the bitmap */
+    error = render->raster_render( render->raster, &params );
+    if (error) goto Exit;
+    
+    slot->format = ft_glyph_format_bitmap;
+    slot->bitmap_left = cbox.xMin >> 6;
+    slot->bitmap_top  = cbox.yMax >> 6;
+    
+  Exit:
+    return error;
+  }
+
+#ifndef  FT_CONFIG_OPTION_NO_STD_RASTER
+
+#include <freetype/ftraster.h>
+
+  const FT_Renderer_Class   ft_standard_renderer_class =
+  {
+    {
+      ft_module_renderer,
+      sizeof( FT_RendererRec ),
+      
+      "standard renderer",
+      0x10000,
+      0x20000,
+      
+      0,    /* module specific interface */
+      
+      (FT_Module_Constructor)  ft_renderer_init,
+      (FT_Module_Destructor)   0,
+      (FT_Module_Requester)    0
+    },
+    
+    ft_glyph_format_outline,
+    
+    (FTRenderer_render)       ft_renderer_render,
+    (FTRenderer_transform)    ft_renderer_transform,
+    (FTRenderer_getCBox)      ft_renderer_get_cbox,
+    (FTRenderer_setMode)      ft_renderer_set_mode,
+    
+    (FT_Raster_Funcs*)        &ft_standard_raster
+  };
+  
+#endif /* !FT_CONFIG_OPTION_NO_STD_RASTER */
+
+#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER
+
+#include <freetype/ftgrays.h>
+
+  const FT_Renderer_Class  ft_smooth_renderer_class =
+  {
+    {
+      ft_module_renderer,
+      sizeof( FT_RendererRec ),
+      
+      "smooth renderer",
+      0x10000,
+      0x20000,
+      
+      0,    /* module specific interface */
+      
+      (FT_Module_Constructor)  ft_renderer_init,
+      (FT_Module_Destructor)   0,
+      (FT_Module_Requester)    0
+    },
+
+    ft_glyph_format_outline,
+    
+    (FTRenderer_render)       ft_renderer_render,
+    (FTRenderer_transform)    ft_renderer_transform,
+    (FTRenderer_getCBox)      ft_renderer_get_cbox,
+    (FTRenderer_setMode)      ft_renderer_set_mode,
+    
+    (FT_Raster_Funcs*)        &ft_grays_raster
+  };
+
+#endif /* !FT_CONFIG_OPTION_NO_SMOOTH_RASTER */
--- /dev/null
+++ b/src/renderer/renderer.h
@@ -1,0 +1,14 @@
+#ifndef RENDERER_H
+#define RENDERER_H
+
+#include <freetype/ftrender.h>
+
+#ifndef FT_CONFIG_OPTION_NO_STD_RASTER
+  FT_EXPORT_VAR(const FT_Renderer_Class)   ft_std_renderer_class;
+#endif
+
+#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER
+  FT_EXPORT_VAR(const FT_Renderer_Class)   ft_smooth_renderer_class;
+#endif
+
+#endif /* RENDERER_H */
--- /dev/null
+++ b/src/renderer/rules.mk
@@ -1,0 +1,75 @@
+#
+# FreeType 2 renderer module build rules
+#
+
+
+# Copyright 1996-2000 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+
+# renderer driver directory
+#
+REND_DIR  := $(SRC_)renderer
+REND_DIR_ := $(REND_DIR)$(SEP)
+
+
+# additional include flags used when compiling the driver
+#
+REND_INCLUDE := $(REND_DIR)
+
+# compilation flags for the driver
+#
+REND_CFLAGS  := $(REND_INCLUDE:%=$I%)
+REND_COMPILE := $(FT_COMPILE) $(REND_CFLAGS)
+
+
+# REND driver sources (i.e., C files)
+#
+REND_DRV_SRC := $(REND_DIR_)ftraster.c  \
+                $(REND_DIR_)ftgrays.c   \
+                $(REND_DIR_)renderer.c
+
+# REND driver headers
+#
+REND_DRV_H := $(REND_DRV_SRC:%c=%h)
+
+
+# REND driver object(s)
+#
+#   REND_DRV_OBJ_M is used during `multi' builds.
+#   REND_DRV_OBJ_S is used during `single' builds.
+#
+REND_DRV_OBJ_M := $(REND_DRV_SRC:$(REND_DIR_)%.c=$(OBJ_)%.$O)
+REND_DRV_OBJ_S := $(REND_DRV_OBJ_M)
+
+# REND driver source file for single build
+#
+#REND_DRV_SRC_S := $(REND_DIR_)renderer.c
+
+
+# REND driver - single object
+#
+#$(REND_DRV_OBJ_S): $(REND_DRV_SRC_S) $(REND_DRV_SRC) \
+#                   $(FREETYPE_H) $(REND_DRV_H)
+#	$(REND_COMPILE) $T$@ $(REND_DRV_SRC_S)
+
+
+# REND driver - multiple objects
+#
+$(OBJ_)%.$O: $(REND_DIR_)%.c $(FREETYPE_H) $(REND_DRV_H)
+	$(REND_COMPILE) $T$@ $<
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(REND_DRV_OBJ_M)
+DRV_OBJS_M += $(REND_DRV_OBJ_M)
+
+
+# EOF
--- a/src/sfnt/module.mk
+++ b/src/sfnt/module.mk
@@ -1,7 +1,7 @@
-make_module_list: add_sfnt_driver
+make_module_list: add_sfnt_module
 
-add_sfnt_driver:
-	$(OPEN_DRIVER)sfnt_driver_interface$(CLOSE_DRIVER)
-	$(ECHO_DRIVER)sfnt      $(ECHO_DRIVER_DESC)pseudo-driver for TrueType & OpenType formats$(ECHO_DRIVER_DONE)
+add_sfnt_module:
+	$(OPEN_DRIVER)sfnt_module_class$(CLOSE_DRIVER)
+	$(ECHO_DRIVER)sfnt      $(ECHO_DRIVER_DESC)helper module for TrueType & OpenType formats$(ECHO_DRIVER_DONE)
 
 # EOF
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -25,7 +25,6 @@
 #include <ttcmap.h>
 #include <sfobjs.h>
 
-
   static
   void*  get_sfnt_table( TT_Face      face,
                          FT_Sfnt_Tag  tag )
@@ -72,13 +71,13 @@
 
 
   static
-  FTDriver_Interface  SFNT_Get_Interface( FT_Driver    driver,
-                                          const char*  interface )
+  FT_Module_Interface  SFNT_Get_Interface( FT_Module    module,
+                                           const char*  interface )
   {
-    UNUSED( driver );
+    UNUSED( module );
 
     if ( strcmp( interface, "get_sfnt" ) == 0 )
-      return (FTDriver_Interface)get_sfnt_table;
+      return (FT_Module_Interface)get_sfnt_table;
 
     return 0;
   }
@@ -140,22 +139,22 @@
   };
 
 
-  const FT_DriverInterface  sfnt_driver_interface =
+  const FT_Module_Class  sfnt_module_class =
   {
-    sizeof ( FT_DriverRec ), 0, 0, 0,
-
-    "sfnt",     /* driver name                          */
-    1,          /* driver version                       */
-    2,          /* driver requires FreeType 2 or higher */
-
-    (void*)&sfnt_interface,
-
-    0, 0, 0,
-    0, 0, 0,
-    0, 0, 0, 0,
-    0, 0, 0,
-    0,
+    0,  /* not a font driver or renderer */
+    sizeof( FT_ModuleRec ),
+    
+    "sfnt",     /* driver name                            */
+    0x10000,    /* driver version 1.0                     */
+    0x20000,    /* driver requires FreeType 2.0 or higher */
+    
+    (const void*)&sfnt_interface,  /* module specific interface */
+    
+    (FT_Module_Constructor)    0,
+    (FT_Module_Destructor)     0,
+    (FT_Module_Requester)      SFNT_Get_Interface
   };
+  
 
 
 /* END */
--- a/src/sfnt/sfdriver.h
+++ b/src/sfnt/sfdriver.h
@@ -19,10 +19,9 @@
 #ifndef SFDRIVER_H
 #define SFDRIVER_H
 
-#include <freetype/internal/ftdriver.h>
-#include <freetype/internal/ftobjs.h>
+#include <freetype/ftmodule.h>
 
-  FT_EXPORT_VAR(const FT_DriverInterface)  sfnt_driver_interface;
+  FT_EXPORT_VAR(const FT_Module_Class)  sfnt_module_class;
 
 #endif /* SFDRIVER_H */
 
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -180,8 +180,8 @@
                             FT_Parameter*  params )
   {
     FT_Error            error;
+    FT_Library          library = face->root.driver->root.library;
     SFNT_Interface*     sfnt;
-    PSNames_Interface*  psnames;
     SFNT_Header         sfnt_header;
 
     /* for now, parameters are unused */
@@ -188,22 +188,10 @@
     UNUSED( num_params );
     UNUSED( params );
 
-
     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 )
-      {
-        error = FT_Err_Invalid_File_Format;
-        goto Exit;
-      }
-
-      sfnt = (SFNT_Interface*)( sfnt_driver->interface.format_interface );
+      sfnt = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" );
       if ( !sfnt )
       {
         error = FT_Err_Invalid_File_Format;
@@ -214,17 +202,10 @@
       face->goto_table = sfnt->goto_table;
     }
 
-    psnames = (PSNames_Interface*)face->psnames;
-    if ( !psnames )
+    if ( !face->psnames )
     {
-      /* look-up the PSNames driver */
-      FT_Driver  psnames_driver;
-
-
-      psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" );
-      if ( psnames_driver )
-        face->psnames = (PSNames_Interface*)
-                          ( psnames_driver->interface.format_interface );
+      face->psnames = (PSNames_Interface*)
+                       FT_Get_Module_Interface( library, "psnames" );
     }
 
     /* check that we have a valid TrueType file */
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -59,7 +59,7 @@
   /*    table  :: A pointer to a cmap object.                              */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The function assumes that the stream is already in use (i.e.,      */
@@ -281,7 +281,7 @@
   /*    cmap :: A handle to a cmap object.                                 */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_CharMap_Free( TT_Face        face,
@@ -293,7 +293,7 @@
     if ( !cmap )
       return TT_Err_Ok;
 
-    memory = face->root.driver->memory;
+    memory = face->root.driver->root.memory;
 
     switch ( cmap->format )
     {
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -96,7 +96,7 @@
   /*    length :: The length of the table if found, undefined otherwise.   */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Goto_Table( TT_Face    face,
@@ -141,7 +141,7 @@
   /*    sfnt       :: The SFNT header.                                     */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The stream cursor must be at the font file's origin.               */
@@ -275,7 +275,7 @@
   /*    sfnt   :: The SFNT directory header.                               */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The stream cursor must be at the font file's origin.               */
@@ -373,7 +373,7 @@
   /*    buffer :: The address of target buffer.                            */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_Any( TT_Face   face,
@@ -436,7 +436,7 @@
   /*    stream :: The input stream.                                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_Header( TT_Face    face,
@@ -507,7 +507,7 @@
   /*    stream :: The input stream.                                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_MaxProfile( TT_Face    face,
@@ -597,7 +597,7 @@
   /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  TT_Load_Metrics( TT_Face    face,
@@ -733,7 +733,7 @@
   /*    vertical :: A boolean flag.  If set, load vertical metrics.        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_Metrics_Header( TT_Face    face,
@@ -829,7 +829,7 @@
   /*    stream :: The input stream.                                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_Names( TT_Face    face,
@@ -990,7 +990,7 @@
   LOCAL_FUNC
   void  TT_Free_Names( TT_Face  face )
   {
-    FT_Memory      memory = face->root.driver->memory;
+    FT_Memory      memory = face->root.driver->root.memory;
     TT_NameTable*  names  = &face->name_table;
 
 
@@ -1020,7 +1020,7 @@
   /*    stream :: A handle to the input stream.                            */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*     TrueType error code.  0 means success.                            */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_CMap( TT_Face    face,
@@ -1129,7 +1129,7 @@
   /*    stream :: A handle to the input stream.                            */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_OS2( TT_Face    face,
@@ -1263,7 +1263,7 @@
   /*    stream :: A handle to the input stream.                            */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_PostScript( TT_Face    face,
@@ -1318,7 +1318,7 @@
   /*    stream :: A handle to the input stream.                            */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_PCLT( TT_Face    face,
@@ -1389,7 +1389,7 @@
   /*    stream :: The input stream.                                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_Gasp( TT_Face    face,
@@ -1461,7 +1461,7 @@
   /*    stream :: The input stream.                                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_Kern( TT_Face    face,
@@ -1566,7 +1566,7 @@
   /*    stream :: A handle to the input stream.                            */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_Hdmx( TT_Face    face,
@@ -1652,7 +1652,7 @@
     if ( face )
     {
       FT_Int     n;
-      FT_Memory  memory = face->root.driver->memory;
+      FT_Memory  memory = face->root.driver->root.memory;
 
 
       for ( n = 0; n < face->hdmx.num_records; n++ )
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -427,7 +427,7 @@
   /*              You must not modify the returned string!                 */
   /*                                                                       */
   /* <Output>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Get_PS_Name( TT_Face      face,
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -211,7 +211,7 @@
   /*    stream :: The input stream.                                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  Load_SBit_Const_Metrics( TT_SBit_Range*  range,
@@ -243,7 +243,7 @@
   /*    load_offsets :: A flag whether to load the glyph offset table.     */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  Load_SBit_Range_Codes( TT_SBit_Range*  range,
@@ -306,7 +306,7 @@
   /*    stream :: The input stream.                                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  Load_SBit_Range( TT_SBit_Range*  range,
@@ -381,7 +381,7 @@
   /*    stream :: The input stream.                                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_SBit_Strikes( TT_Face    face,
@@ -631,7 +631,7 @@
   /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means the glyph index was found.           */
+  /*    TrueType error code.  0 means the glyph index was found.           */
   /*                                                                       */
   static
   FT_Error  Find_SBit_Range( FT_UInt          glyph_index,
@@ -735,7 +735,7 @@
   /*    aglyph_offset :: The offset of the glyph data in `EBDT' table.     */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.  Returns                    */
+  /*    TrueType error code.  0 means success.  Returns                    */
   /*    TT_Err_Invalid_Argument if no sbit exists for the requested glyph. */
   /*                                                                       */
   static
@@ -800,7 +800,7 @@
   /*    big_metrics :: A big SBit metrics structure for the glyph.         */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The stream cursor must be positioned at the glyph's offset within  */
@@ -1349,7 +1349,7 @@
   /*    metrics     :: A big sbit metrics structure for the glyph image.   */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.  Returns an error if no     */
+  /*    TrueType error code.  0 means success.  Returns an error if no     */
   /*    glyph sbit exists for the index.                                   */
   /*                                                                       */
   /*  <Note>                                                               */
--- a/src/truetype/module.mk
+++ b/src/truetype/module.mk
@@ -1,7 +1,7 @@
 make_module_list: add_truetype_driver
 
 add_truetype_driver:
-	$(OPEN_DRIVER)tt_driver_interface$(CLOSE_DRIVER)
+	$(OPEN_DRIVER)tt_driver_class$(CLOSE_DRIVER)
 	$(ECHO_DRIVER)truetype  $(ECHO_DRIVER_DESC)Windows/Mac font files with extension *.ttf or *.ttc$(ECHO_DRIVER_DONE)
 
 # EOF
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -75,7 +75,7 @@
   /*                   formats.                                            */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Only horizontal layouts (left-to-right & right-to-left) are        */
@@ -178,7 +178,7 @@
   /*    size            :: A handle to the target size object.             */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  Set_Char_Sizes( TT_Size     size,
@@ -238,7 +238,7 @@
   /*    size         :: A handle to the target size object.                */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  Set_Pixel_Sizes( TT_Size  size,
@@ -280,7 +280,7 @@
   /*                   whether to hint the outline, etc).                  */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  Load_Glyph( TT_GlyphSlot  slot,
@@ -398,19 +398,18 @@
 
 
   static
-  FTDriver_Interface  tt_get_interface( TT_Driver    driver,
-                                        const char*  interface )
+  FT_Module_Interface   tt_get_interface( TT_Driver    driver,
+                                          const char*  interface )
   {
-    FT_Driver        sfntd = FT_Get_Driver( driver->root.library, "sfnt" );
+    FT_Module        sfntd = FT_Get_Module( driver->root.root.library, "sfnt" );
     SFNT_Interface*  sfnt;
 
-    
     /* only return the default interface from the SFNT module */
     if ( sfntd )
     {
-      sfnt = (SFNT_Interface*)(sfntd->interface.format_interface);
+      sfnt = (SFNT_Interface*)(sfntd->clazz->module_interface);
       if ( sfnt )
-        return sfnt->get_interface( (FT_Driver)driver, interface );
+        return sfnt->get_interface( FT_MODULE(driver), interface );
     }
 
     return 0;
@@ -419,37 +418,45 @@
 
   /* The FT_DriverInterface structure is defined in ftdriver.h. */
 
-  const FT_DriverInterface  tt_driver_interface =
+  const FT_Driver_Class  tt_driver_class =
   {
-    sizeof ( TT_DriverRec ),
+    {
+      ft_module_font_driver | ft_module_driver_scalable,
+      sizeof ( TT_DriverRec ),
+    
+      "truetype",      /* driver name                           */
+      0x10000,         /* driver version == 1.0                 */
+      0x20000,         /* driver requires FreeType 2.0 or above */
+  
+      (void*)0,        /* driver specific interface */
+  
+      (FT_Module_Constructor)   TT_Init_Driver,
+      (FT_Module_Destructor)    TT_Done_Driver,
+      (FT_Module_Requester)     tt_get_interface,
+    },
+    
     sizeof ( TT_FaceRec ),
     sizeof ( TT_SizeRec ),
     sizeof ( FT_GlyphSlotRec ),
 
-    "truetype",      /* driver name                           */
-    100,             /* driver version == 1.0                 */
-    200,             /* driver requires FreeType 2.0 or above */
 
-    (void*)0,
-
-    (FTDriver_initDriver)     TT_Init_Driver,
-    (FTDriver_doneDriver)     TT_Done_Driver,
-    (FTDriver_getInterface)   tt_get_interface,
-
     (FTDriver_initFace)       TT_Init_Face,
     (FTDriver_doneFace)       TT_Done_Face,
-    (FTDriver_getKerning)     Get_Kerning,
-
     (FTDriver_initSize)       TT_Init_Size,
     (FTDriver_doneSize)       TT_Done_Size,
+    (FTDriver_initGlyphSlot)  0,
+    (FTDriver_doneGlyphSlot)  0,
+
     (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,
+    
+    (FTDriver_getKerning)     Get_Kerning,
+    (FTDriver_attachFile)     0,
+    (FTDriver_getAdvances)    0
+
+
   };
 
 
@@ -475,9 +482,9 @@
   /*    format-specific interface can then be retrieved through the method */
   /*    interface->get_format_interface.                                   */
   /*                                                                       */
-  EXPORT_FUNC( FT_DriverInterface* )  getDriverInterface( void )
+  EXPORT_FUNC( const FT_Driver_Class* )  getDriverClass( void )
   {
-    return &tt_driver_interface;
+    return &tt_driver_class;
   }
 
 
--- a/src/truetype/ttdriver.h
+++ b/src/truetype/ttdriver.h
@@ -25,7 +25,7 @@
 #include <freetype/internal/tterrors.h>
 
 
-  FT_EXPORT_VAR( const FT_DriverInterface )  tt_driver_interface;
+  FT_EXPORT_VAR( const FT_Driver_Class )  tt_driver_class;
 
 
 #endif /* TTDRIVER_H */
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -174,32 +174,20 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /*    Mounts one glyph zone on top of another.  This is needed to        */
-  /*    assemble composite glyphs.                                         */
-  /*                                                                       */
-  static
-  void  mount_zone( TT_GlyphZone*  source,
-                    TT_GlyphZone*  target )
+  static  void  tt_prepare_zone( TT_GlyphZone*  zone,
+                                 FT_GlyphLoad*  load,
+                                 FT_UInt        start_point,
+                                 FT_UInt        start_contour )
   {
-    FT_UInt  np;
-    FT_Int   nc;
+    zone->n_points   = load->outline.n_points - start_point;
+    zone->n_contours = load->outline.n_contours - start_contour;
+    zone->org        = load->extra_points + start_point;
+    zone->cur        = load->outline.points + start_point;
+    zone->tags       = (FT_Byte*)load->outline.tags + start_point;
+    zone->contours   = (FT_UShort*)load->outline.contours + start_contour;
+  }                                 
 
-    np = source->n_points;
-    nc = source->n_contours;
 
-    target->org  = source->org + np;
-    target->cur  = source->cur + np;
-    target->tags = source->tags + np;
-
-    target->contours = source->contours + nc;
-
-    target->n_points   = 0;
-    target->n_contours = 0;
-  }
-
-
 #undef  IS_HINTED
 #define IS_HINTED( flags )  ( ( flags & FT_LOAD_NO_HINTING ) == 0 )
 
@@ -220,54 +208,43 @@
                          FT_Int      n_contours,
                          FT_Bool     debug )
   {
-    FT_Error       error;
-    FT_Stream      stream = load->stream;
-    TT_GlyphZone*  zone   = &load->zone;
-    TT_Face        face = load->face;
+    FT_Error         error;
+    FT_Stream        stream  = load->stream;
+    FT_GlyphLoader*  gloader = load->gloader;
+    FT_Outline*      outline;
+    TT_GlyphZone*    zone    = &load->zone;
+    TT_Face          face    = load->face;
 
-    FT_UShort      n_ins;
-    FT_Int         n, n_points;
+    FT_UShort        n_ins;
+    FT_Int           n, n_points;
 
 
-    /* simple check */
-
-    if ( n_contours > load->left_contours )
-    {
-      FT_TRACE0(( "ERROR: Glyph index %ld has %d contours > left %d\n",
-                   load->glyph_index,
-                   n_contours,
-                   load->left_contours ));
-      return TT_Err_Too_Many_Contours;
-    }
-
-    /* preparing the execution context */
-    mount_zone( &load->base, zone );
-
-    /* reading the contours endpoints */
-
     if ( ACCESS_Frame( byte_count ) )
       return error;
 
-    for ( n = 0; n < n_contours; n++ )
-      zone->contours[n] = GET_UShort();
+    /* reading the contours endpoints & number of points */
+    {
+      short*  cur   = gloader->current.outline.contours;
+      short*  limit = cur + n_contours;
+      
+      for ( ; cur < limit; cur++ )
+        cur[0] = GET_UShort();
+        
+      n_points = 0;
+      if (n_contours > 0)
+        n_points = cur[-1]+1;
 
-    n_points = 0;
-    if ( n_contours > 0 )
-      n_points = zone->contours[n_contours - 1] + 1;
+      error = FT_GlyphLoader_Check_Points( gloader, n_points+2, 0 );
+      if (error) goto Fail;
+      
+      outline = &gloader->current.outline;
+    }
 
-    /* reading the bytecode instructions */
 
+    /* reading the bytecode instructions */
     n_ins = GET_UShort();
     load->face->root.glyph->control_len = n_ins;
 
-    if ( n_points > load->left_points )
-    {
-      FT_TRACE0(( "ERROR: Too many points in glyph %ld\n",
-                  load->glyph_index ));
-      error = TT_Err_Too_Many_Points;
-      goto Fail;
-    }
-
     FT_TRACE5(( "  Instructions size: %d\n", n_ins ));
 
     if ( n_ins > face->max_profile.maxSizeOfInstructions )
@@ -302,11 +279,10 @@
     /* reading the point tags */
 
     {
-      FT_Byte*  flag  = load->zone.tags;
+      FT_Byte*  flag  = (FT_Byte*)outline->tags;
       FT_Byte*  limit = flag + n_points;
       FT_Byte   c, count;
 
-
       for ( ; flag < limit; flag++ )
       {
         *flag = c = GET_Byte();
@@ -321,9 +297,9 @@
     /* reading the X coordinates */
 
     {
-      FT_Vector*  vec   = zone->org;
+      FT_Vector*  vec   = outline->points;
       FT_Vector*  limit = vec + n_points;
-      FT_Byte*    flag  = zone->tags;
+      FT_Byte*    flag  = (FT_Byte*)outline->tags;
       FT_Pos      x     = 0;
 
 
@@ -349,9 +325,9 @@
     /* reading the Y coordinates */
 
     {
-      FT_Vector*  vec   = zone->org;
+      FT_Vector*  vec   = gloader->current.outline.points;
       FT_Vector*  limit = vec + n_points;
-      FT_Byte*    flag  = zone->tags;
+      FT_Byte*    flag  = (FT_Byte*)outline->tags;
       FT_Pos      x     = 0;
 
 
@@ -387,7 +363,7 @@
 
 
       /* pp1 = xMin - lsb */
-      pp1    = zone->org + n_points;
+      pp1    = outline->points + n_points;
       pp1->x = load->bbox.xMin - load->left_bearing;
       pp1->y = 0;
 
@@ -398,34 +374,30 @@
 
       /* clear the touch tags */
       for ( n = 0; n < n_points; n++ )
-        zone->tags[n] &= FT_Curve_Tag_On;
+        outline->tags[n] &= FT_Curve_Tag_On;
 
-      zone->tags[n_points    ] = 0;
-      zone->tags[n_points + 1] = 0;
+      outline->tags[n_points    ] = 0;
+      outline->tags[n_points + 1] = 0;
     }
 
     /* Note that we return two more points that are not */
     /* part of the glyph outline.                       */
 
-    zone->n_points   = n_points;
-    zone->n_contours = n_contours;
-    n_points        += 2;
+    outline->n_points   = n_points;
+    outline->n_contours = n_contours;
+    n_points           += 2;
 
-    /* now eventually scale and hint the glyph */
+    /* set up zone for hinting */
+    tt_prepare_zone( zone, &gloader->current, 0, 0 );
 
-    if ( load->load_flags & FT_LOAD_NO_SCALE )
+    /* eventually scale the glyph */
+    if (!(load->load_flags & FT_LOAD_NO_SCALE))
     {
-      /* no scaling, just copy the orig arrays into the cur ones */
-      org_to_cur( n_points, zone );
-    }
-    else
-    {
-      FT_Vector*  vec = zone->org;
-      FT_Vector*  limit = vec + n_points;
+      FT_Vector*  vec     = zone->cur;
+      FT_Vector*  limit   = vec + n_points;
       FT_Fixed    x_scale = load->size->root.metrics.x_scale;
       FT_Fixed    y_scale = load->size->root.metrics.y_scale;
 
-
       /* first scale the glyph points */
       for ( ; vec < limit; vec++ )
       {
@@ -432,40 +404,37 @@
         vec->x = FT_MulFix( vec->x, x_scale );
         vec->y = FT_MulFix( vec->y, y_scale );
       }
+    }
 
-      /* if hinting, round pp1, and shift the glyph accordingly */
-      if ( !IS_HINTED( load->load_flags ) )
-      {
-        org_to_cur( n_points, zone );
-      }
-      else
-      {
-        FT_Pos  x = zone->org[n_points-2].x;
+    cur_to_org( n_points, zone );
 
+    /* eventually hint the glyph */
+    if ( IS_HINTED(load->load_flags) )
+    {
+      FT_Pos  x = zone->org[n_points-2].x;
 
-        x = ( ( x + 32 ) & -64 ) - x;
-        translate_array( n_points, zone->org, x, 0 );
+      x = ( ( x + 32 ) & -64 ) - x;
+      translate_array( n_points, zone->org, x, 0 );
 
-        org_to_cur( n_points, zone );
+      org_to_cur( n_points, zone );
 
-        zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64;
+      zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64;
 
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-        /* now consider hinting */
-        if ( n_ins > 0 )
-        {
-          load->exec->is_composite     = FALSE;
-          load->exec->pedantic_hinting = (FT_Bool)(load->load_flags &
-                                                   FT_LOAD_PEDANTIC);
-          load->exec->pts              = *zone;
-          load->exec->pts.n_points    += 2;
+      /* now consider hinting */
+      if ( n_ins > 0 )
+      {
+        load->exec->is_composite     = FALSE;
+        load->exec->pedantic_hinting = (FT_Bool)(load->load_flags &
+                                                 FT_LOAD_PEDANTIC);
+        load->exec->pts              = *zone;
+        load->exec->pts.n_points    += 2;
 
-          error = TT_Run_Context( load->exec, debug );
-          if ( error && load->exec->pedantic_hinting )
-            return error;
-        }
-#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
+        error = TT_Run_Context( load->exec, debug );
+        if ( error && load->exec->pedantic_hinting )
+          return error;
       }
+#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
     }
 
     /* save glyph phantom points */
@@ -475,7 +444,7 @@
       load->pp2 = zone->cur[n_points - 1];
     }
 
-    return TT_Err_Ok;
+    return FT_Err_Ok;
 
   Fail:
     FORGET_Frame();
@@ -496,14 +465,15 @@
   FT_Error  load_truetype_glyph( TT_Loader*  loader,
                                  FT_UInt     glyph_index )
   {
-    FT_Stream    stream = loader->stream;
-    FT_Error     error;
-    TT_Face      face   = loader->face;
-    FT_ULong     offset;
-    FT_Int       num_subglyphs = 0, contours_count;
-    FT_UInt      index, num_points, num_contours, count;
-    FT_Fixed     x_scale, y_scale;
-    FT_ULong     ins_offset;
+    FT_Stream        stream = loader->stream;
+    FT_Error         error;
+    TT_Face          face   = loader->face;
+    FT_ULong         offset;
+    FT_Int           num_subglyphs = 0, contours_count;
+    FT_UInt          index, num_points, num_contours, count;
+    FT_Fixed         x_scale, y_scale;
+    FT_ULong         ins_offset;
+    FT_GlyphLoader*  gloader = loader->gloader;
 
 
     /* check glyph index */
@@ -596,13 +566,6 @@
 
     count -= 10;
 
-    if ( contours_count > loader->left_contours )
-    {
-      FT_TRACE0(( "ERROR: Too many contours for glyph %ld\n", index ));
-      error = TT_Err_Too_Many_Contours;
-      goto Fail;
-    }
-
     loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
     loader->pp1.y = 0;
     loader->pp2.x = loader->pp1.x + loader->advance;
@@ -622,9 +585,10 @@
 
     if ( contours_count >= 0 )
     {
-      FT_UInt  num_base_points;
+      /* check that we can add the contours to the glyph */
+      error = FT_GlyphLoader_Check_Points( gloader, 0, contours_count );
+      if (error) goto Fail;
 
-
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
       error = Load_Simple( loader,
                            count,
@@ -634,31 +598,12 @@
 #else
       error = Load_Simple( loader, count, contours_count, 0 );
 #endif
-      if ( error )
-        goto Fail;
+      if ( error ) goto Fail;
 
+      FT_GlyphLoader_Add( gloader );
+
       /* Note: We could have put the simple loader source there */
       /*       but the code is fat enough already :-)           */
-      num_points   = loader->zone.n_points;
-      num_contours = loader->zone.n_contours;
-
-      num_base_points = loader->base.n_points;
-      {
-        FT_UInt  k;
-
-
-        for ( k = 0; k < num_contours; k++ )
-          loader->zone.contours[k] += num_base_points;
-      }
-
-      loader->base.n_points   += num_points;
-      loader->base.n_contours += num_contours;
-
-      loader->zone.n_points    = 0;
-      loader->zone.n_contours  = 0;
-
-      loader->left_points   -= num_points;
-      loader->left_contours -= num_contours;
     }
 
     /***********************************************************************/
@@ -669,9 +614,14 @@
     else
     {
       /* for each subglyph, read composite header */
-      TT_GlyphSlot  glyph    = loader->glyph;
-      FT_SubGlyph*  subglyph = glyph->subglyphs + glyph->num_subglyphs;
+      TT_GlyphSlot     glyph     = loader->glyph;
+      FT_SubGlyph*     subglyph;
+      FT_UInt          num_base_subgs;
+      FT_UInt          start_point, start_contour;
 
+      start_point   = gloader->base.outline.n_points;
+      start_contour = gloader->base.outline.n_contours;
+      
       if ( ACCESS_Frame( count ) )
         goto Fail;
 
@@ -679,29 +629,13 @@
       do
       {
         FT_Fixed  xx, xy, yy, yx;
-        FT_UInt   total_subglyphs;
 
+        /* check that we can load a new subglyph */
+        error = FT_GlyphLoader_Check_Subglyphs( gloader, num_subglyphs+1 );
+        if (error) goto Fail;
+        
+        subglyph = gloader->current.subglyphs + num_subglyphs;
 
-        /* grow the `glyph->subglyphs' table if necessary */
-        total_subglyphs = glyph->num_subglyphs + num_subglyphs;
-
-        if ( total_subglyphs >= glyph->max_subglyphs )
-        {
-          FT_UInt    new_max = glyph->max_subglyphs;
-          FT_Memory  memory = loader->face->root.memory;
-
-
-          while ( new_max <= total_subglyphs )
-            new_max += 4;
-
-          if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs,
-                              new_max, FT_SubGlyph ) )
-            goto Fail;
-
-          glyph->max_subglyphs = new_max;
-          subglyph = glyph->subglyphs + glyph->num_subglyphs + num_subglyphs;
-        }
-
         subglyph->arg1 = subglyph->arg2 = 0;
 
         subglyph->flags = GET_UShort();
@@ -746,11 +680,12 @@
         subglyph->transform.yx = yx;
         subglyph->transform.yy = yy;
 
-        subglyph++;
         num_subglyphs++;
       }
-      while (subglyph[-1].flags & MORE_COMPONENTS);
+      while (subglyph->flags & MORE_COMPONENTS);
 
+      gloader->current.num_subglyphs = num_subglyphs;
+      
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
       {
         /* we must undo the ACCESS_Frame in order to point to the */
@@ -769,8 +704,12 @@
       if ( loader->load_flags & FT_LOAD_NO_RECURSE )
       {
         /* set up remaining glyph fields */
-        glyph->num_subglyphs += num_subglyphs;
+        FT_GlyphLoader_Add( gloader );
+        
+        glyph->num_subglyphs  = gloader->base.num_subglyphs;
         glyph->format         = ft_glyph_format_composite;
+        glyph->subglyphs      = gloader->base.subglyphs;
+        
         goto Load_End;
       }
 
@@ -784,25 +723,32 @@
       {
         FT_Int  n, num_base_points, num_new_points;
 
-        subglyph = glyph->subglyphs + glyph->num_subglyphs;
-        glyph->num_subglyphs += num_subglyphs;
-
-
-        for ( n = 0; n < num_subglyphs; n++, subglyph++ )
+        num_base_subgs = gloader->base.num_subglyphs;
+        
+        FT_GlyphLoader_Add( gloader );
+        
+        for ( n = 0; n < num_subglyphs; n++ )
         {
           FT_Vector  pp1, pp2;
           FT_Pos     x, y;
 
+          /* each time we call load_truetype_glyph in this loop, the   */
+          /* value of 'gloader.base.subglyphs' can change due to table */
+          /* reallocations. We thus need to recompute the subglyph     */
+          /* pointer on each iteration..                               */
+          subglyph = gloader->base.subglyphs + num_base_subgs + n;
 
           pp1 = loader->pp1;
           pp2 = loader->pp2;
 
-          num_base_points = loader->base.n_points;
+          num_base_points = gloader->base.outline.n_points;
 
           error = load_truetype_glyph( loader, subglyph->index );
           if ( error )
             goto Fail;
 
+          subglyph = gloader->base.subglyphs + num_base_subgs + n;
+
           if ( subglyph->flags & USE_MY_METRICS )
           {
             pp1 = loader->pp1;
@@ -814,8 +760,7 @@
             loader->pp2 = pp2;
           }
 
-          num_points   = loader->base.n_points;
-          num_contours = loader->base.n_contours;
+          num_points   = gloader->base.outline.n_points;
 
           num_new_points = num_points - num_base_points;
 
@@ -825,33 +770,14 @@
                                    WE_HAVE_AN_XY_SCALE |
                                    WE_HAVE_A_2X2       ) )
           {
-            FT_Vector*  cur = loader->zone.cur;
-            FT_Vector*  org = loader->zone.org;
+            FT_Vector*  cur   = gloader->base.outline.points + num_base_points;
+            FT_Vector*  org   = gloader->base.extra_points   + num_base_points;
             FT_Vector*  limit = cur + num_new_points;
 
-
             for ( ; cur < limit; cur++, org++ )
             {
-              FT_Pos  nx, ny;
-
-
-              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;
+              FT_Vector_Transform( cur, &subglyph->transform );
+              FT_Vector_Transform( org, &subglyph->transform );
             }
           }
 
@@ -859,12 +785,13 @@
 
           if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
           {
-            FT_Int   k = subglyph->arg1;
-            FT_UInt  l = subglyph->arg2;
+            FT_Int      k = subglyph->arg1;
+            FT_UInt     l = subglyph->arg2;
+            FT_Vector*  p1;
+            FT_Vector*  p2;
 
-
-            if ( k >= num_base_points ||
-                 l >= (FT_UInt)num_new_points  )
+            if ( start_point + k >= num_base_points          ||
+                               l >= (FT_UInt)num_new_points  )
             {
               error = TT_Err_Invalid_Composite;
               goto Fail;
@@ -872,8 +799,11 @@
 
             l += num_base_points;
 
-            x = loader->base.cur[k].x - loader->base.cur[l].x;
-            y = loader->base.cur[k].y - loader->base.cur[l].y;
+            p1 = gloader->base.outline.points + start_point + k;
+            p2 = gloader->base.outline.points + start_point + l;
+            
+            x = p1->x - p2->x;
+            y = p1->y - p2->y;
           }
           else
           {
@@ -906,7 +836,6 @@
 
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 
-        subglyph--;
         if ( num_subglyphs > 0               &&
              loader->exec                    &&
              subglyph->flags & WE_HAVE_INSTR )
@@ -949,8 +878,8 @@
             goto Fail;
 
           /* prepare the execution context */
-          exec->pts = loader->base;
-          pts       = &exec->pts;
+          tt_prepare_zone( &exec->pts, &gloader->base, start_point, start_contour );
+          pts = &exec->pts;
 
           pts->n_points   = num_points + 2;
           pts->n_contours = num_contours;
@@ -1007,7 +936,7 @@
     /***********************************************************************/
 
   Load_End:
-    error = TT_Err_Ok;
+    error = FT_Err_Ok;
 
   Fail:
     return error;
@@ -1018,8 +947,6 @@
   void  compute_glyph_metrics( TT_Loader*  loader,
                                FT_UInt     glyph_index )
   {
-    FT_UInt       num_points   = loader->base.n_points;
-    FT_UInt       num_contours = loader->base.n_contours;
     FT_BBox       bbox;
     TT_Face       face = loader->face;
     FT_Fixed      x_scale, y_scale;
@@ -1026,16 +953,6 @@
     TT_GlyphSlot  glyph = loader->glyph;
     TT_Size       size = loader->size;
 
-
-    /* when a simple glyph was loaded, the value of        */
-    /* `base.n_points' and `base.n_contours' is 0, we will */
-    /* take those in the `zone' instead.                   */
-    if ( num_points == 0 && num_contours == 0 )
-    {
-      num_points   = loader->zone.n_points;
-      num_contours = loader->zone.n_contours;
-    }
-
     x_scale = 0x10000L;
     y_scale = 0x10000L;
     if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
@@ -1046,27 +963,14 @@
 
     if ( glyph->format != ft_glyph_format_composite )
     {
-      FT_UInt  u;
+      glyph->outline.flags &= ~ft_outline_single_pass;
 
-
-      for ( u = 0; u < num_points + 2; u++ )
-      {
-        glyph->outline.points[u] = loader->base.cur[u];
-        glyph->outline.tags  [u] = loader->base.tags[u];
-      }
-
-      for ( u = 0; u < num_contours; u++ )
-        glyph->outline.contours[u] = loader->base.contours[u];
-
-      glyph->outline.flags      &= ~ft_outline_single_pass;
-      glyph->outline.n_points    = num_points;
-      glyph->outline.n_contours  = num_contours;
-
+      /* copy outline to our glyph slot */
+      FT_GlyphLoader_Copy_Points( glyph->loader, loader->gloader );
+      glyph->outline = glyph->loader->base.outline;
+      
       /* translate array so that (0,0) is the glyph's origin */
-      translate_array( (FT_UShort)( num_points + 2 ),
-                       glyph->outline.points,
-                       -loader->pp1.x,
-                       0 );
+      FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 );
 
       FT_Outline_Get_CBox( &glyph->outline, &bbox );
 
@@ -1082,18 +986,11 @@
     else
       bbox = loader->bbox;
 
-    /* get the device-independent scaled horizontal metrics; */
-    /* take care of fixed-pitch fonts...                     */
+    /* get the device-independent horizontal advance. It is scaled later */
+    /* by the base layer..                                               */
     {
-      FT_Pos  left_bearing;
-      FT_Pos  advance;
+      FT_Pos  advance = loader->advance;
 
-      FT_Pos  lsb2, adv2;
-
-
-      left_bearing = loader->left_bearing;
-      advance      = loader->advance;
-
       /* the flag FT_LOAD_NO_ADVANCE_CHECK was introduced to      */
       /* correctly support DynaLab fonts, which have an incorrect */
       /* `advance_Width_Max' field!  It is used, to my knowledge, */
@@ -1103,23 +1000,9 @@
            ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 )
         advance = face->horizontal.advance_Width_Max;
 
-      lsb2 = left_bearing;
-      adv2 = advance;
-
-      /* if necessary, scale the horizontal left bearing and advance */
-      /* to get their values in 16.16 format..                       */
-      if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) &&
-              loader->load_flags & FT_LOAD_LINEAR     )
-      {
-        FT_Pos  em_size    = face->root.units_per_EM;
-        FT_Pos  pixel_size = (FT_Pos)face->root.size->metrics.x_ppem << 16;
-
-
-        lsb2 = FT_MulDiv( lsb2, pixel_size, em_size );
-        adv2 = FT_MulDiv( adv2, pixel_size, em_size );
-      }
-      glyph->metrics2.horiBearingX = lsb2;
-      glyph->metrics2.horiAdvance  = adv2;
+      /* we need to return the advance in font units in linearHoriAdvance, */
+      /* it will be scaled later by the base layer..                       */
+      glyph->linearHoriAdvance = advance;
     }
 
     glyph->metrics.horiBearingX = bbox.xMin;
@@ -1184,7 +1067,7 @@
 
       /* We must adjust the top_bearing value from the bounding box given */
       /* in the glyph header to te bounding box calculated with           */
-      /* TT_Get_Outline_BBox().                                           */
+      /* FT_Get_Outline_CBox().                                           */
 
       /* scale the metrics */
       if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
@@ -1201,28 +1084,10 @@
         advance = advance_height;
       }
 
-      /* compute metrics2 fields */
-      {
-        FT_Pos  vtb2 = top_bearing;
-        FT_Pos  adv2 = advance_height;
+      /* set the advance height in design units. It is scaled later by the */
+      /* base layer..                                                      */
+      glyph->linearVertAdvance = advance_height;
 
-
-        /* scale to 16.16 format if required */
-        if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) &&
-                loader->load_flags & FT_LOAD_LINEAR     )
-        {
-          FT_Pos  em_size    = face->root.units_per_EM;
-          FT_Pos  pixel_size = face->root.size->metrics.y_ppem;
-
-
-          vtb2 = FT_MulDiv( vtb2, pixel_size, em_size );
-          adv2 = FT_MulDiv( adv2, pixel_size, em_size );
-        }
-
-        glyph->metrics2.vertBearingY = vtb2;
-        glyph->metrics2.vertAdvance  = adv2;
-      }
-
       /* XXX: for now, we have no better algorithm for the lsb, but it    */
       /*      should work fine.                                           */
       /*                                                                  */
@@ -1251,16 +1116,6 @@
         glyph->metrics.horiAdvance = widths[glyph_index] << 6;
     }
 
-/* drop-out mode is irrelevant, we always use mode 2 */
-#if 0
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-    if ( loader->exec )
-      glyph->outline.dropout_mode = (FT_Char)loader->exec->GS.scan_type;
-#else
-    glyph->outline.dropout_mode = 2;
-#endif
-#endif
-
     /* set glyph dimensions */
     glyph->metrics.width  = bbox.xMax - bbox.xMin;
     glyph->metrics.height = bbox.yMax - bbox.yMin;
@@ -1293,7 +1148,7 @@
   /*                   whether to hint the outline, etc).                  */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Load_Glyph( TT_Size       size,
@@ -1307,7 +1162,6 @@
     FT_Memory        memory;
     FT_Error         error;
     TT_Loader        loader;
-    TT_GlyphZone*    zone;
 
 
     face   = (TT_Face)glyph->face;
@@ -1362,6 +1216,16 @@
         glyph->metrics.vertAdvance  = (FT_Pos)metrics.vertAdvance  << 6;
 
         glyph->format = ft_glyph_format_bitmap;
+        if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
+        {
+          glyph->bitmap_left = metrics.horiBearingX;
+          glyph->bitmap_top  = metrics.horiBearingY;
+        }
+        else
+        {
+          glyph->bitmap_left = metrics.vertBearingX;
+          glyph->bitmap_top  = metrics.vertBearingY;
+        }
         return error;
       }
     }
@@ -1368,9 +1232,6 @@
 
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
-    if ( load_flags & FT_LOAD_NO_OUTLINE )
-      return ( error ? error : TT_Err_Unavailable_Bitmap );
-
     /* seek to the beginning of the glyph table.  For Type 43 fonts      */
     /* the table might be accessed from a Postscript stream or something */
     /* else...                                                           */
@@ -1385,20 +1246,17 @@
     MEM_Set( &loader, 0, sizeof ( loader ) );
 
     /* update the glyph zone bounds */
-    zone  = &((TT_Driver)face->root.driver)->zone;
-    error = TT_Update_GlyphZone( zone,
-                                 face->root.max_points,
-                                 face->root.max_contours );
-    if ( error )
     {
-      FT_ERROR(( "TT_Load_Glyph: Could not update loader glyph zone\n" ));
-      goto Exit;
+      FT_GlyphLoader*  gloader = FT_FACE_DRIVER(face)->glyph_loader;
+      
+      loader.gloader = gloader;
+      
+      FT_GlyphLoader_Rewind( gloader );
+      
+      tt_prepare_zone( &loader.zone, &gloader->base, 0, 0 );
+      tt_prepare_zone( &loader.base, &gloader->base, 0, 0 );
     }
-    loader.base = *zone;
 
-    loader.zone.n_points   = 0;
-    loader.zone.n_contours = 0;
-
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 
     if ( size )
@@ -1425,8 +1283,6 @@
 
     /* let's initialize the rest of our loader now */
 
-    loader.left_points   = face->root.max_points;
-    loader.left_contours = face->root.max_contours;
     loader.load_flags    = load_flags;
 
     loader.face   = face;
--- a/src/truetype/ttgload.h
+++ b/src/truetype/ttgload.h
@@ -34,6 +34,7 @@
     TT_Face         face;
     TT_Size         size;
     TT_GlyphSlot    glyph;
+    FT_GlyphLoader* gloader;
 
     FT_ULong        load_flags;
     FT_UInt         glyph_index;
@@ -40,8 +41,6 @@
 
     FT_Stream       stream;
     FT_Int          byte_len;
-    FT_Int          left_points;
-    FT_Int          left_contours;
 
     FT_BBox         bbox;
     FT_Int          left_bearing;
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -257,7 +257,7 @@
   /*    exec  :: The target execution context.                             */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*   TrueType error code.  0 means success.                              */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Goto_CodeRange( TT_ExecContext  exec,
@@ -307,7 +307,7 @@
   /*    exec   :: The target execution context.                            */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*   TrueType error code.  0 means success.                              */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Set_CodeRange( TT_ExecContext  exec,
@@ -339,7 +339,7 @@
   /*    exec  :: The target execution context.                             */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*   TrueType error code.  0 means success.                              */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Does not set the Error variable.                                   */
@@ -378,7 +378,7 @@
   /*    memory :: A handle to the parent memory object.                    */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Only the glyph loader and debugger should call this function.      */
@@ -433,7 +433,7 @@
   /*    exec   :: A handle to the target execution context.                */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  Init_Context( TT_ExecContext  exec,
@@ -504,7 +504,7 @@
   /*    buff       :: The address of the buffer base pointer.              */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   static
   FT_Error  Update_Max( FT_Memory  memory,
@@ -546,7 +546,7 @@
   /*    exec :: A handle to the target execution context.                  */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Only the glyph loader and debugger should call this function.      */
@@ -649,7 +649,7 @@
   /*    size :: A handle to the target size object.                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Only the glyph loader and debugger should call this function.      */
@@ -696,7 +696,7 @@
   /*    exec  :: A handle to the target execution context.                 */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueTyoe error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Only the glyph loader and debugger should call this function.      */
@@ -791,7 +791,7 @@
 
     driver = (TT_Driver)face->root.driver;
 
-    memory = driver->root.memory;
+    memory = driver->root.root.memory;
     exec   = driver->context;
 
     if ( !driver->context )
@@ -834,7 +834,7 @@
   /*    exec :: A handle to the target execution context.                  */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Only the glyph loader and debugger should call this function.      */
@@ -6781,7 +6781,7 @@
   /*    exec :: A handle to the target execution context.                  */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Only the object manager and debugger should call this function.    */
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -124,65 +124,6 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    TT_Update_GlyphZone                                                */
-  /*                                                                       */
-  /* <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.                     */
-  /*                                                                       */
-  LOCAL_FUNC FT_Error   TT_Update_GlyphZone( TT_GlyphZone*  zone,
-                                             FT_UShort      newPoints,
-                                             FT_Short       newContours )
-  {
-    FT_Error      error  = FT_Err_Ok;
-    FT_Memory     memory = zone->memory;
-
-
-    newPoints += 2;
-
-    if ( zone->max_points < newPoints )
-    {
-      /* reallocate the points arrays */
-      if ( REALLOC_ARRAY( zone->org,  zone->max_points * 2,
-                                      newPoints * 2, FT_F26Dot6 ) ||
-           REALLOC_ARRAY( zone->cur,  zone->max_points * 2,
-                                      newPoints * 2, FT_F26Dot6 ) ||
-           REALLOC_ARRAY( zone->tags, zone->max_points * 2,
-                                      newPoints,     FT_Byte    ) )
-        goto Exit;
-
-      zone->max_points = newPoints;
-    }
-
-    if ( zone->max_contours < newContours )
-    {
-      /* reallocate the contours array */
-      if ( REALLOC_ARRAY( zone->contours, zone->max_contours,
-                                          newContours, FT_UShort ) )
-        goto Exit;
-
-      zone->max_contours = newContours;
-    }
-
-  Exit:
-    return error;
-  }
-
-
-
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
   /*    TT_Init_Face                                                       */
   /*                                                                       */
   /* <Description>                                                         */
@@ -201,7 +142,7 @@
   /*    face       :: The newly built face object.                         */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_DEF
   FT_Error  TT_Init_Face( FT_Stream      stream,
@@ -211,18 +152,13 @@
                           FT_Parameter*  params )
   {
     FT_Error         error;
-    FT_Driver        sfnt_driver;
+    FT_Library       library;
     SFNT_Interface*  sfnt;
 
+    library = face->root.driver->root.library;
+    sfnt    = (SFNT_Interface*)FT_Get_Module_Interface( library, "sfnt" );
+    if (!sfnt) goto Bad_Format;
 
-    sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" );
-    if ( !sfnt_driver )
-      goto Bad_Format;
-
-    sfnt = (SFNT_Interface*)(sfnt_driver->interface.format_interface);
-    if ( !sfnt )
-      goto Bad_Format;
-
     /* create input stream from resource */
     if ( FILE_Seek( 0 ) )
       goto Exit;
@@ -320,7 +256,7 @@
   /*    size :: A handle to the size object.                               */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_DEF
   FT_Error  TT_Init_Size( TT_Size  size )
@@ -396,7 +332,7 @@
 
     /* set `face->interpreter' according to the debug hook present */
     {
-      FT_Library  library = face->root.driver->library;
+      FT_Library  library = face->root.driver->root.library;
 
 
       face->interpreter = (TT_Interpreter)
@@ -697,67 +633,10 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    TT_Init_GlyphSlot                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    The TrueType glyph slot initializer.                               */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    slot :: The glyph record to build.                                 */
-  /*                                                                       */
-  /* <Output>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  LOCAL_FUNC
-  FT_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_Outline_New( 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_Memory   memory  = library->memory;
-
-
-    if ( slot->flags & ft_glyph_own_bitmap )
-      FREE( slot->bitmap.buffer );
-
-    FT_Outline_Done( library, &slot->outline );
-    return;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
   /*    TT_Init_Driver                                                     */
   /*                                                                       */
   /* <Description>                                                         */
@@ -767,25 +646,24 @@
   /*    driver :: A handle to the target driver object.                    */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
+  /*    TrueType error code.  0 means success.                             */
   /*                                                                       */
   LOCAL_FUNC
   FT_Error  TT_Init_Driver( TT_Driver  driver )
   {
-    FT_Memory  memory = driver->root.memory;
     FT_Error   error;
 
-    error = TT_New_GlyphZone( memory, 0, 0, &driver->zone );
-    if ( error )
-      return error;
-
+    /* set 'extra' in glyph loader */
+    error = FT_GlyphLoader_Create_Extra( FT_DRIVER(driver)->glyph_loader );
+    
     /* init extension registry if needed */
 
 #ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
-    return TT_Init_Extensions( driver );
-#else
-    return TT_Err_Ok;
+    if (!error)
+      return TT_Init_Extensions( driver );
 #endif
+
+    return error;
   }
 
 
@@ -809,15 +687,12 @@
     TT_Done_Extensions( driver );
 #endif
 
-    /* remove the loading glyph zone */
-    TT_Done_GlyphZone( &driver->zone );
-
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 
     /* destroy the execution context */
     if ( driver->context )
     {
-      TT_Destroy_Context( driver->context, driver->root.memory );
+      TT_Destroy_Context( driver->context, driver->root.root.memory );
       driver->context = NULL;
     }
 
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -151,10 +151,6 @@
                                        FT_Short       maxContours,
                                        TT_GlyphZone*  zone );
 
-  LOCAL_DEF FT_Error TT_Update_GlyphZone( TT_GlyphZone*  zone,
-                                          FT_UShort      newPoints,
-                                          FT_Short       newContours );
-
   /*************************************************************************/
   /*                                                                       */
   /*  EXECUTION SUBTABLES                                                  */
@@ -440,17 +436,6 @@
 
   LOCAL_DEF
   FT_Error  TT_Reset_Size( TT_Size  size );
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* GlyphSlot functions                                                   */
-  /*                                                                       */
-  LOCAL_DEF
-  FT_Error  TT_Init_GlyphSlot( TT_GlyphSlot  slot );
-
-  LOCAL_DEF
-  void  TT_Done_GlyphSlot( TT_GlyphSlot  slot );
 
 
   /*************************************************************************/
--- a/src/type1/module.mk
+++ b/src/type1/module.mk
@@ -1,6 +1,6 @@
 make_module_list: add_type1_driver
 
 add_type1_driver:
-	$(OPEN_DRIVER)t1_driver_interface$(CLOSE_DRIVER)
+	$(OPEN_DRIVER)t1_driver_class$(CLOSE_DRIVER)
 	$(ECHO_DRIVER)type1     $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE)
 
--- a/src/type1/t1afm.h
+++ b/src/type1/t1afm.h
@@ -1,59 +1,47 @@
-/***************************************************************************/
-/*                                                                         */
-/*  t1afm.h                                                                */
-/*                                                                         */
-/*    AFM support for Type 1 fonts (specification).                        */
-/*                                                                         */
-/*  Copyright 1996-2000 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
+/***************************************************************************
+ *
+ * t1afm.h  - support for reading Type 1 AFM files
+ *
+ *
+ ***************************************************************************/
 
-
 #ifndef T1AFM_H
 #define T1AFM_H
 
 #include <freetype/internal/ftobjs.h>
 
+/* In this version, we only read the kerning table from the */
+/* AFM file. We may add support for ligatures a bit later.. */
 
-  typedef struct  T1_Kern_Pair_
-  {
-    FT_UInt    glyph1;
-    FT_UInt    glyph2;
-    FT_Vector  kerning;
+typedef struct T1_Kern_Pair_
+{
+  FT_UInt   glyph1;
+  FT_UInt   glyph2;
+  FT_Vector kerning;
 
-  } T1_Kern_Pair;
+} T1_Kern_Pair;
 
-  typedef struct  T1_AFM_
-  {
-    FT_Int         num_pairs;
-    T1_Kern_Pair*  kern_pairs;
 
-  } T1_AFM;
+typedef struct T1_AFM_
+{
+  FT_Int        num_pairs;
+  T1_Kern_Pair* kern_pairs;
 
+} T1_AFM;
 
-  LOCAL_DEF
-  FT_Error  T1_Read_AFM( FT_Face    face,
-                         FT_Stream  stream );
 
-  LOCAL_DEF
-  void  T1_Done_AFM( FT_Memory  memory,
-                     T1_AFM*    afm );
+LOCAL_DEF
+FT_Error  T1_Read_AFM( FT_Face   face,
+                       FT_Stream stream );
 
-  LOCAL_DEF
-  void  T1_Get_Kerning( T1_AFM*     afm,
-                        FT_UInt     glyph1,
-                        FT_UInt     glyph2,
-                        FT_Vector*  kerning );
+LOCAL_DEF
+void      T1_Done_AFM( FT_Memory  memory,
+                       T1_AFM*    afm );
 
+LOCAL_DEF
+void  T1_Get_Kerning( T1_AFM*     afm,
+                      FT_UInt     glyph1,
+                      FT_UInt     glyph2,
+                      FT_Vector*  kerning );
 
 #endif /* T1AFM_H */
-
-
-/* END */
--- a/src/type1/t1driver.c
+++ b/src/type1/t1driver.c
@@ -1,21 +1,20 @@
-/***************************************************************************/
-/*                                                                         */
-/*  t1driver.c                                                             */
-/*                                                                         */
-/*    Type 1 driver interface (body).                                      */
-/*                                                                         */
-/*  Copyright 1996-2000 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
+/*******************************************************************
+ *
+ *  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 <t1afm.h>
@@ -24,64 +23,14 @@
 #include <freetype/internal/ftstream.h>
 #include <freetype/internal/psnames.h>
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
-  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
-  /* messages during execution.                                            */
-  /*                                                                       */
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_t1driver
 
-
 #ifndef T1_CONFIG_OPTION_NO_AFM
 
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    Get_Interface                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Each driver can provide one or more extensions to the base         */
-  /*    FreeType API.  These can be used to access format specific         */
-  /*    features (e.g., all TrueType/OpenType resources share a common     */
-  /*    file structure and common tables which can be accessed through the */
-  /*    `sfnt' interface), or more simply generic ones (e.g., the          */
-  /*    `postscript names' interface which can be used to retrieve the     */
-  /*     PostScript name of a given glyph index).                          */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    driver    :: A handle to a driver object.                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    interface :: A string designing the interface.  Examples are       */
-  /*                 `sfnt', `post_names', `charmaps', etc.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    A typeless pointer to the extension's interface (normally a table  */
-  /*    of function pointers).  Returns NULL if the requested extension    */
-  /*    isn't available (i.e., wasn't compiled in the driver at build      */
-  /*    time).                                                             */
-  /*                                                                       */
-  static
-  FTDriver_Interface  Get_Interface( FT_Driver         driver,
-                                     const FT_String*  interface )
-  {
-    UNUSED( driver );
-
-    if ( strcmp( (const char*)interface, "attach_file" ) == 0 )
-      return (FTDriver_Interface)T1_Read_AFM;
-
-    return 0;
-  }
-
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
   /*    Get_Kerning                                                        */
   /*                                                                       */
   /* <Description>                                                         */
@@ -119,58 +68,44 @@
   {
     T1_AFM*  afm;
 
-
     kerning->x = 0;
     kerning->y = 0;
 
     afm = (T1_AFM*)face->afm_data;
-    if ( afm )
+    if (afm)
       T1_Get_Kerning( afm, left_glyph, right_glyph, kerning );
 
     return T1_Err_Ok;
   }
+#endif
 
-
-#endif /* !T1_CONFIG_OPTION_NO_AFM */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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.                              */
-  /*                                                                       */
-  /*    horz_resolution :: The horizontal resolution of the output device. */
-  /*                                                                       */
-  /*    vert_resolution :: The vertical resolution of the output device.   */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size            :: A handle to the target size object.             */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
+  /******************************************************************/
+  /*                                                                */
+  /* <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
-  FT_Error  Set_Char_Sizes( T1_Size     size,
-                            FT_F26Dot6  char_width,
-                            FT_F26Dot6  char_height,
-                            FT_UInt     horz_resolution,
-                            FT_UInt     vert_resolution )
+  FT_Error  Set_Char_Sizes( T1_Size      size,
+                            FT_F26Dot6   char_width,
+                            FT_F26Dot6   char_height,
+                            FT_UInt      horz_resolution,
+                            FT_UInt      vert_resolution )
   {
-    UNUSED( char_width );
-    UNUSED( char_height );
-    UNUSED( horz_resolution );
-    UNUSED( vert_resolution );
+    UNUSED(char_width);
+    UNUSED(char_height);
+    UNUSED(horz_resolution);
+    UNUSED(vert_resolution);
 
     size->valid = FALSE;
     return T1_Reset_Size( size );
@@ -177,39 +112,43 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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.                             */
-  /*                                                                       */
+  /******************************************************************/
+  /*                                                                */
+  /* <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
-  FT_Error  Set_Pixel_Sizes( T1_Size  size,
-                             FT_Int   pixel_width,
-                             FT_Int   pixel_height )
+  FT_Error  Set_Pixel_Sizes( T1_Size     size,
+                             FT_Int      pixel_width,
+                             FT_Int      pixel_height )
   {
-    UNUSED( pixel_width );
-    UNUSED( pixel_height );
+    UNUSED(pixel_width);
+    UNUSED(pixel_height);
 
     size->valid = FALSE;
-    return T1_Reset_Size( size );
+    return T1_Reset_Size(size);
   }
 
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -233,155 +172,155 @@
     FT_UInt             result = 0;
     PSNames_Interface*  psnames;
 
-
     face = (T1_Face)charmap->face;
     psnames = (PSNames_Interface*)face->psnames;
-    if ( psnames )
-      switch ( charmap->encoding )
+    if (psnames)
+      switch (charmap->encoding)
       {
-        /*******************************************************************/
-        /*                                                                 */
-        /* Unicode encoding support                                        */
-        /*                                                                 */
-      case ft_encoding_unicode:
-        /* use the `PSNames' module to synthetize the Unicode charmap */
-        result = psnames->lookup_unicode( &face->unicode_map,
-                                          (FT_ULong)charcode );
+       /********************************************************************/
+       /*                                                                  */
+       /* Unicode encoding support                                         */
+       /*                                                                  */
+        case ft_encoding_unicode:
+          {
+            /* use the "psnames" module to synthetize the Unicode charmap */
+            result = psnames->lookup_unicode( &face->unicode_map,
+                                              (FT_ULong)charcode );
 
-        /* the function returns 0xFFFF if the Unicode charcode has */
-        /* no corresponding glyph.                                 */
-        if ( result == 0xFFFF )
-          result = 0;
-        goto Exit;
+            /* the function returns 0xFFFF when the Unicode charcode has */
+            /* no corresponding glyph..                                  */
+            if (result == 0xFFFF)
+              result = 0;
+            goto Exit;
+          }
 
-        /*******************************************************************/
-        /*                                                                 */
-        /* Custom Type 1 encoding                                          */
-        /*                                                                 */
-      case ft_encoding_adobe_custom:
-        {
-          T1_Encoding*  encoding = &face->type1.encoding;
+       /********************************************************************/
+       /*                                                                  */
+       /* Custom Type 1 encoding                                           */
+       /*                                                                  */
+        case ft_encoding_adobe_custom:
+          {
+            T1_Encoding*  encoding = &face->type1.encoding;
+            if (charcode >= encoding->code_first &&
+                charcode <= encoding->code_last)
+            {
+              result = encoding->char_index[charcode];
+            }
+            goto Exit;
+          }
 
+       /********************************************************************/
+       /*                                                                  */
+       /* Adobe Standard & Expert encoding support                         */
+       /*                                                                  */
+       default:
+         if (charcode < 256)
+         {
+           FT_UInt      code;
+           FT_Int       n;
+           const char*  glyph_name;
 
-          if ( charcode >= encoding->code_first &&
-               charcode <= encoding->code_last  )
-            result = encoding->char_index[charcode];
-          goto Exit;
-        }
+           code = psnames->adobe_std_encoding[charcode];
+           if (charmap->encoding == ft_encoding_adobe_expert)
+             code = psnames->adobe_expert_encoding[charcode];
 
-        /*******************************************************************/
-        /*                                                                 */
-        /* Adobe Standard & Expert encoding support                        */
-        /*                                                                 */
-      default:
-        if ( charcode < 256 )
-        {
-          FT_UInt      code;
-          FT_Int       n;
-          const char*  glyph_name;
+           glyph_name = psnames->adobe_std_strings(code);
+           if (!glyph_name) break;
 
+           for ( n = 0; n < face->type1.num_glyphs; n++ )
+           {
+             const char*  gname = face->type1.glyph_names[n];
 
-          code = psnames->adobe_std_encoding[charcode];
-          if ( charmap->encoding == ft_encoding_adobe_expert )
-            code = psnames->adobe_expert_encoding[charcode];
-
-          glyph_name = psnames->adobe_std_strings( code );
-          if ( !glyph_name )
-            break;
-
-          for ( n = 0; n < face->type1.num_glyphs; n++ )
-          {
-            const char*  gname = face->type1.glyph_names[n];
-
-
-            if ( gname && gname[0] == glyph_name[0] &&
-                 strcmp( gname, glyph_name ) == 0   )
-            {
-              result = n;
-              break;
-            }
-          }
-        }
+             if ( gname && gname[0] == glyph_name[0] &&
+                  strcmp( gname, glyph_name ) == 0 )
+             {
+               result = n;
+               break;
+             }
+           }
+         }
       }
-
   Exit:
     return result;
   }
 
 
-  const  FT_DriverInterface  t1_driver_interface =
+
+
+  const  FT_Driver_Class  t1_driver_class =
   {
-    sizeof( FT_DriverRec ),
+    {
+      ft_module_font_driver | ft_module_driver_scalable,
+      sizeof( FT_DriverRec ),
+      
+      "type1",   /* driver name        */
+      0x10000,   /* driver version 1.0 */
+      0x20000,   /* driver requires FreeType 2.0 or above */
+  
+      0,   /* module specific interface */
+  
+      (FT_Module_Constructor)  0,
+      (FT_Module_Destructor)   0,
+#ifdef T1_CONFIG_OPTION_NO_AFM
+      (FT_Module_Requester)    Get_Interface
+#else
+      (FT_Module_Requester)    0
+#endif
+    },
+
     sizeof( T1_FaceRec ),
     sizeof( T1_SizeRec ),
     sizeof( T1_GlyphSlotRec ),
 
-    "type1",
-    100,
-    200,
+    (FTDriver_initFace)             T1_Init_Face,
+    (FTDriver_doneFace)             T1_Done_Face,
+    (FTDriver_initSize)             T1_Init_Size,
+    (FTDriver_doneSize)             T1_Done_Size,
+    (FTDriver_initGlyphSlot)        T1_Init_GlyphSlot,
+    (FTDriver_doneGlyphSlot)        T1_Done_GlyphSlot,
 
-    0,   /* format interface */
+    (FTDriver_setCharSizes)         Set_Char_Sizes,
+    (FTDriver_setPixelSizes)        Set_Pixel_Sizes,
+    (FTDriver_loadGlyph)            T1_Load_Glyph,
+    (FTDriver_getCharIndex)         Get_Char_Index,
 
-    (FTDriver_initDriver)   T1_Init_Driver,
-    (FTDriver_doneDriver)   T1_Done_Driver,
-
 #ifdef T1_CONFIG_OPTION_NO_AFM
-    (FTDriver_getInterface) 0,
+    (FTDriver_getKerning)           0,
+    (FTDriver_getAdvances)          0
 #else
-    (FTDriver_getInterface) Get_Interface,
+    (FTDriver_getKerning)           Get_Kerning,
+    (FTDriver_attachFile)           T1_Read_AFM
 #endif
-
-    (FTDriver_initFace)     T1_Init_Face,
-    (FTDriver_doneFace)     T1_Done_Face,
-
-#ifdef T1_CONFIG_OPTION_NO_AFM
-    (FTDriver_getKerning)   0,
-#else
-    (FTDriver_getKerning)   Get_Kerning,
-#endif
-
-    (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) Get_Char_Index,
   };
 
 
+  /******************************************************************/
+  /*                                                                */
+  /*  <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
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    getDriverInterface                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This function is used when compiling the CID 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 CID's driver generic interface.  The            */
-  /*    format-specific interface can then be retrieved through the method */
-  /*    interface->get_format_interface.                                   */
-  /*                                                                       */
-  EXPORT_FUNC( FT_DriverInterface* )  getDriverInterface( void )
+  EXPORT_FUNC(const FT_Driver_Class*)  getDriverClass( void )
   {
-    return &t1_driver_interface;
+    return &t1_driver_class;
   }
 
-
 #endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
 
 
-/* END */
--- a/src/type1/t1driver.h
+++ b/src/type1/t1driver.h
@@ -1,30 +1,26 @@
-/***************************************************************************/
-/*                                                                         */
-/*  t1driver.h                                                             */
-/*                                                                         */
-/*    High-level Type 1 driver interface (specification).                  */
-/*                                                                         */
-/*  Copyright 1996-2000 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
+/*******************************************************************
+ *
+ *  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 <freetype/internal/t1errors.h>
+#include <freetype/internal/ftdriver.h>
 
-  FT_EXPORT_VAR( const  FT_DriverInterface )  t1_driver_interface;
+  FT_EXPORT_VAR(const  FT_Driver_Class)  t1_driver_class;
 
 #endif /* T1DRIVER_H */
 
-
-/* END */
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -1,21 +1,20 @@
-/***************************************************************************/
-/*                                                                         */
-/*  t1gload.c                                                              */
-/*                                                                         */
-/*    Type 1 Glyph Loader (body).                                          */
-/*                                                                         */
-/*  Copyright 1996-2000 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
+/*******************************************************************
+ *
+ *  t1gload.c                                                   1.0
+ *
+ *    Type1 Glyph Loader.
+ *
+ *  Copyright 1996-1999 by
+ *  David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ *  This file is part of the FreeType project, and may only be used
+ *  modified and distributed under the terms of the FreeType project
+ *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ *  this file you indicate that you have read the license and
+ *  understand and accept it fully.
+ *
+ ******************************************************************/
 
-
 #include <t1gload.h>
 #include <freetype/internal/ftdebug.h>
 #include <freetype/internal/ftstream.h>
@@ -24,33 +23,37 @@
 #include <t1hinter.h>
 #endif
 
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********           GENERIC CHARSTRINGS PARSING             *********/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
-  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
-  /* messages during execution.                                            */
-  /*                                                                       */
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1gload
+/*********************************************************************
+ *
+ * <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").
+ *
+ *********************************************************************/
 
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /**********                                                      *********/
-  /**********                                                      *********/
-  /**********             GENERIC CHARSTRING PARSING               *********/
-  /**********                                                      *********/
-  /**********                                                      *********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
   static
-  void  T1_Reset_Builder( T1_Builder*  builder,
-                          FT_Bool      reset_base )
+  void  T1_Reset_Builder( T1_Builder*  builder, FT_Bool  reset_base )
   {
     builder->pos_x = 0;
     builder->pos_y = 0;
@@ -63,52 +66,22 @@
     builder->pass       = 0;
     builder->hint_point = 0;
 
-    if ( reset_base )
+    if (builder->loader)
     {
-      builder->base.n_points   = 0;
-      builder->base.n_contours = 0;
-    }
+      if (reset_base)
+        FT_GlyphLoader_Rewind( builder->loader );
     
-    {
-      FT_Outline*  base = &builder->base;
-      FT_Outline*  cur  = &builder->current;
-
-      
-      cur->n_points   = 0;
-      cur->n_contours = 0;
-      cur->points     = base->points   + base->n_points;
-      cur->tags       = base->tags     + base->n_points;
-      cur->contours   = base->contours + base->n_contours;
+      FT_GlyphLoader_Prepare( builder->loader );
     }
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T1_Init_Builder                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes a given glyph builder.                                 */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    builder :: A pointer to the glyph builder to initialize.           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face    :: The current face object.                                */
-  /*                                                                       */
-  /*    size    :: The current size object.                                */
-  /*                                                                       */
-  /*    glyph   :: The current glyph object.                               */
-  /*                                                                       */
-  /*    funcs   :: Glyph builder functions (or `methods').                 */
-  /*                                                                       */
   LOCAL_FUNC
-  void  T1_Init_Builder( T1_Builder*              builder,
-                         T1_Face                  face,
-                         T1_Size                  size,
-                         T1_GlyphSlot             glyph,
-                         const T1_Builder_Funcs*  funcs )
+  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;
@@ -119,14 +92,16 @@
     builder->glyph  = glyph;
     builder->memory = face->root.memory;
 
-    if ( glyph )
+    if (glyph)
     {
-      builder->base         = glyph->root.outline;
-      builder->max_points   = glyph->max_points;
-      builder->max_contours = glyph->max_contours;
+      FT_GlyphLoader*  loader = FT_SLOT(glyph)->loader;
+      
+      builder->loader  = loader;
+      builder->base    = &loader->base.outline;
+      builder->current = &loader->current.outline;
     }
 
-    if ( size )
+    if (size)
     {
       builder->scale_x = size->root.metrics.x_scale;
       builder->scale_y = size->root.metrics.y_scale;
@@ -136,47 +111,47 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T1_Done_Builder                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Finalizes a given glyph builder.  Its contents can still be used   */
-  /*    after the call, but the function saves important information       */
-  /*    within the corresponding glyph slot.                               */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    builder :: A pointer to the glyph builder to finalize.             */
-  /*                                                                       */
+/*********************************************************************
+ *
+ * <Function>
+ *    T1_Done_Builder
+ *
+ * <Description>
+ *    Finalise a given glyph builder. Its content can still be
+ *    used after the call, but the function saves important information
+ *    within the corresponding glyph slot.
+ *
+ * <Input>
+ *    builder :: glyph builder to initialise
+ *
+ *********************************************************************/
+
   LOCAL_FUNC
-  void  T1_Done_Builder( T1_Builder*  builder )
+  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;
-    }
+    if (glyph)
+      glyph->root.outline = *builder->base;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T1_Init_Decoder                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes a given glyph decoder.                                 */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    decoder :: A pointer to the glyph builder to initialize.           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    funcs   :: The hinting functions interface.                        */
+
+/*********************************************************************
+ *
+ * <Function>
+ *    T1_Init_Decoder
+ *
+ * <Description>
+ *    Initialise a given Type 1 decoder for parsing
+ *
+ * <Input>
+ *    decoder :: Type 1 decoder to initialise
+ *    funcs   :: hinter functions interface
+ *
+ *********************************************************************/
+
+
   LOCAL_FUNC
   void  T1_Init_Decoder( T1_Decoder*             decoder,
                          const T1_Hinter_Funcs*  funcs )
@@ -189,50 +164,49 @@
     decoder->num_flex_vectors = 0;
 
     /* Clear loader */
-    MEM_Set( &decoder->builder, 0, sizeof ( decoder->builder ) );
+    MEM_Set( &decoder->builder, 0, sizeof(decoder->builder) );
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    lookup_glyph_by_stdcharcode                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Looks up a given glyph by its StandardEncoding charcode.  Used     */
-  /*    to implement the SEAC Type 1 operator.                             */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face     :: The current face object.                               */
-  /*                                                                       */
-  /*    charcode :: The character code to look for.                        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    A glyph index in the font face.  Returns -1 if the corresponding   */
-  /*    glyph wasn't found.                                                */
-  /*                                                                       */
+/*********************************************************************
+ *
+ * <Function>
+ *    lookup_glyph_by_stdcharcode
+ *
+ * <Description>
+ *    Lookup a given glyph by its StandardEncoding charcode. Used
+ *    to implement the SEAC Type 1 operator.
+ *
+ * <Input>
+ *    face     :: current face object
+ *    charcode :: charcode to look for
+ *
+ * <Return>
+ *    glyph index in font face. Returns -1 if the corresponding
+ *    glyph wasn't found.
+ *
+ *********************************************************************/
+
   static
-  FT_Int  lookup_glyph_by_stdcharcode( T1_Face  face,
-                                       FT_Int   charcode )
+  FT_Int    lookup_glyph_by_stdcharcode( T1_Face  face,
+                                         FT_Int   charcode )
   {
     FT_Int              n;
     const FT_String*    glyph_name;
     PSNames_Interface*  psnames = (PSNames_Interface*)face->psnames;
 
-
     /* check range of standard char code */
-    if ( charcode < 0 || charcode > 255 )
+    if (charcode < 0 || charcode > 255)
       return -1;
 
     glyph_name = psnames->adobe_std_strings(
-                   psnames->adobe_std_encoding[charcode]);
+                    psnames->adobe_std_encoding[charcode]);
 
     for ( n = 0; n < face->type1.num_glyphs; n++ )
     {
       FT_String*  name = (FT_String*)face->type1.glyph_names[n];
 
-
-      if ( name && strcmp( name, glyph_name ) == 0 )
+      if ( name && strcmp(name,glyph_name) == 0 )
         return n;
     }
 
@@ -240,30 +214,27 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    t1operator_seac                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Implements the `seac' Type 1 operator for a Type 1 decoder.        */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    decoder  :: The current CID decoder.                               */
-  /*                                                                       */
-  /*    asb      :: The accent's side bearing.                             */
-  /*                                                                       */
-  /*    adx      :: The horizontal offset of the accent.                   */
-  /*                                                                       */
-  /*    ady      :: The vertical offset of the accent.                     */
-  /*                                                                       */
-  /*    bchar    :: The base character's StandardEncoding charcode.        */
-  /*                                                                       */
-  /*    achar    :: The accent character's StandardEncoding charcode.      */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
+/*********************************************************************
+ *
+ * <Function>
+ *    t1operator_seac
+ *
+ * <Description>
+ *    Implements the "seac" Type 1 operator for a Type 1 decoder
+ *
+ * <Input>
+ *    decoder  :: current Type 1 decoder
+ *    asb      :: accent's side bearing
+ *    adx      :: horizontal position of accent
+ *    ady      :: vertical position of accent
+ *    bchar    :: base character's StandardEncoding charcode
+ *    achar    :: accent character's StandardEncoding charcode
+ *
+ * <Return>
+ *    Error code. 0 means success.
+ *
+ *********************************************************************/
+
   static
   FT_Error  t1operator_seac( T1_Decoder*  decoder,
                              FT_Pos       asb,
@@ -273,14 +244,13 @@
                              FT_Int       achar )
   {
     FT_Error     error;
-    T1_Face      face = decoder->builder.face;
     FT_Int       bchar_index, achar_index, n_base_points;
-    FT_Outline*  cur  = &decoder->builder.current;
-    FT_Outline*  base = &decoder->builder.base;
+    FT_Outline*  cur  = decoder->builder.current;
+    FT_Outline*  base = decoder->builder.base;
     FT_Vector    left_bearing, advance;
+    T1_Face      face  = decoder->builder.face;
     T1_Font*     type1 = &face->type1;
 
-
     bchar_index = lookup_glyph_by_stdcharcode( face, bchar );
     achar_index = lookup_glyph_by_stdcharcode( face, achar );
 
@@ -290,30 +260,21 @@
       return T1_Err_Syntax_Error;
     }
 
+    /* if we are trying to load a composite glyph, do not load the */
+    /* accent character and return the array of subglyphs.         */
     if ( decoder->builder.no_recurse )
     {
-      /* if we are trying to load a composite glyph, do not load the */
-      /* accent character and return the array of subglyphs.         */
 
-      FT_GlyphSlot  glyph = (FT_GlyphSlot)decoder->builder.glyph;
-      FT_SubGlyph*  subg;
+      FT_GlyphSlot     glyph = (FT_GlyphSlot)decoder->builder.glyph;
+      FT_GlyphLoader*  loader = glyph->loader;
+      FT_SubGlyph*     subg;
 
-
       /* reallocate subglyph array if necessary */
-      if ( glyph->max_subglyphs < 2 )
-      {
-        FT_Memory  memory = decoder->builder.face->root.memory;
+      error = FT_GlyphLoader_Check_Subglyphs( loader, 2 );
+      if (error) goto Exit;
+      
+      subg = loader->current.subglyphs;
 
-
-        if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs,
-                            2, FT_SubGlyph ) )
-          return error;
-
-        glyph->max_subglyphs = 2;
-      }
-
-      subg = glyph->subglyphs;
-
       /* subglyph 0 = base character */
       subg->index = bchar_index;
       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
@@ -331,29 +292,27 @@
       /* set up remaining glyph fields */
       glyph->num_subglyphs = 2;
       glyph->format        = ft_glyph_format_composite;
+      
+      loader->current.num_subglyphs = 2;
     }
-    else
-    {
-      /* 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->tags       = base->tags     + base->n_points;
-      cur->contours   = base->contours + base->n_contours;
-  
-      error = T1_Parse_CharStrings( decoder,
-                                    type1->charstrings    [bchar_index],
-                                    type1->charstrings_len[bchar_index],
-                                    type1->num_subrs,
-                                    type1->subrs,
-                                    type1->subrs_len );
-      if ( error )
-        return error;
-  
-      n_base_points   = cur->n_points;
+    /* First load `bchar' in builder */
+    /* now load the unscaled outline */
+    
+    if (decoder->builder.loader)
+      FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
 
+    error = T1_Parse_CharStrings( decoder,
+                                  type1->charstrings    [bchar_index],
+                                  type1->charstrings_len[bchar_index],
+                                  type1->num_subrs,
+                                  type1->subrs,
+                                  type1->subrs_len );
+    if ( error ) goto Exit;
+
+    n_base_points = cur->n_points;
+
+    {
       /* save the left bearing and width of the base character */
       /* as they will be erased by the next load.              */
 
@@ -365,13 +324,6 @@
 
       /* 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->tags       = base->tags     + base->n_points;
-      cur->contours   = base->contours + base->n_contours;
-
       error = T1_Parse_CharStrings( decoder,
                                     type1->charstrings    [achar_index],
                                     type1->charstrings_len[achar_index],
@@ -378,17 +330,8 @@
                                     type1->num_subrs,
                                     type1->subrs,
                                     type1->subrs_len );
-      if ( error )
-        return error;
+      if ( error ) return error;
 
-      /* adjust contours in accented character outline */
-      {
-        FT_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 */
 
@@ -396,30 +339,38 @@
       decoder->builder.advance      = advance;
 
       /* Finally, move the accent */
-      FT_Outline_Translate( cur, adx - asb, ady );
+      if ( decoder->builder.load_points )
+      {
+        FT_Outline  dummy;
+        
+        dummy.n_points = base->n_points - n_base_points;
+        dummy.points   = base->points   + n_base_points;
+        FT_Outline_Translate( &dummy, adx - asb, ady );
+      }
     }
-
-    return T1_Err_Ok;
+  Exit:
+    return error;
   }
 
+/*********************************************************************
+ *
+ * <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.
+ *
+ *********************************************************************/
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    t1operator_flex                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Implements the `flex' Type 1 operator for a Type 1 decoder.        */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    decoder   :: The current Type 1 decoder.                           */
-  /*    threshold :: The threshold.                                        */
-  /*    end_x     :: The horizontal position of the final flex point.      */
-  /*    end_y     :: The vertical position of the final flex point.        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
   static
   FT_Error  t1operator_flex( T1_Decoder*  decoder,
                              FT_Pos       threshold,
@@ -430,15 +381,10 @@
     FT_Vector*   flex  = decoder->flex_vectors;
     FT_Int       n;
 
-    UNUSED( threshold );
-    UNUSED( end_x );
-    UNUSED( end_y );
-
-
-    /* we don't even try to test the threshold in the non-hinting   */
+    /* 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.                                          */
+    /* construction statement in the specification. This is better */
+    /* left to the hinter..                                        */
 
     flex = decoder->flex_vectors;
     vec  = *flex++;
@@ -451,6 +397,11 @@
       vec = *flex++;
     }
 
+
+    UNUSED(threshold);
+    UNUSED(end_x);
+    UNUSED(end_y);
+
     flex  = decoder->flex_vectors;
 
     return  decoder->builder.funcs.rcurve_to( &decoder->builder,
@@ -465,37 +416,34 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T1_Parse_CharStrings                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Parses a given Type 1 charstrings program.                         */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    decoder          :: The current Type 1 decoder.                    */
-  /*                                                                       */
-  /*    charstring_base  :: The base address of the charstring stream.     */
-  /*                                                                       */
-  /*    charstring_len   :: The length in bytes of the charstring stream.  */
-  /*                                                                       */
-  /*    num_subrs        :: The number of sub-routines.                    */
-  /*                                                                       */
-  /*    subrs_base       :: An array of sub-routines addresses.            */
-  /*                                                                       */
-  /*    subrs_len        :: An array of sub-routines lengths.              */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Free error code.  0 means success.                                 */
-  /*                                                                       */
+/*********************************************************************
+ *
+ * <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.
+ *
+ *********************************************************************/
+
   LOCAL_FUNC
-  FT_Error  T1_Parse_CharStrings( T1_Decoder*  decoder,
-                                  FT_Byte*     charstring_base,
-                                  FT_Int       charstring_len,
-                                  FT_Int       num_subrs,
-                                  FT_Byte**    subrs_base,
-                                  FT_Int*      subrs_len )
+  FT_Error   T1_Parse_CharStrings( T1_Decoder*  decoder,
+                                   FT_Byte*     charstring_base,
+                                   FT_Int       charstring_len,
+                                   FT_Int       num_subrs,
+                                   FT_Byte**    subrs_base,
+                                   FT_Int*      subrs_len )
   {
     FT_Error            error;
     T1_Decoder_Zone*    zone;
@@ -505,7 +453,7 @@
     T1_Builder_Funcs*   builds  = &builder->funcs;
     T1_Hinter_Funcs*    hints   = &decoder->hinter;
 
-    static const FT_Int  args_count[op_max] =
+    static const FT_Int  args_count[ op_max ] =
     {
       0, /* none */
       0, /* endchar */
@@ -535,8 +483,7 @@
       2  /* setcurrentpoint */
     };
 
-
-    /* First of all, initialize the decoder */
+    /* First of all, initialise the decoder */
     decoder->top  = decoder->stack;
     decoder->zone = decoder->zones;
     zone          = decoder->zones;
@@ -556,146 +503,99 @@
       T1_Operator  op       = op_none;
       FT_Long      value    = 0;
 
-
-      /* Start with the decompression of operator or value */
-      switch ( *ip++ )
+      /* First of all, decompress operator or value */
+      switch (*ip++)
       {
-      case 1:
-        op = op_hstem;
-        break;
+        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 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 13: op = op_hsbw;      break;
+        case 14: op = op_endchar;   break;
 
-      case 21:
-        op = op_rmoveto;
-        break;
-      case 22:
-        op = op_hmoveto;
-        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 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;
+          {
+            if (ip > limit)
+            {
+              FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+EOF)\n" ));
+              goto Syntax_Error;
+            }
 
-        default:
-          FT_ERROR(( "T1_Parse_CharStrings: invalid escape (12+%d)\n",
-                     ip[-1] ));
-          goto Syntax_Error;
-        }
-        break;
+            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;
 
-      case 255:    /* four bytes integer */
-        if ( ip + 4 > limit )
-        {
-          FT_ERROR(( "T1_Parse_CharStrings: unexpected EOF in integer\n" ));
-          goto Syntax_Error;
-        }
+              default:
+                FT_ERROR(( "T1.Parse_CharStrings : invalid escape (12+%d)\n",
+                         ip[-1] ));
+                goto Syntax_Error;
+            }
+          }
+          break;
 
-        value = ( (FT_Long)ip[0] << 24 ) |
-                ( (FT_Long)ip[1] << 16 ) |
-                ( (FT_Long)ip[2] << 8  ) |
-                           ip[3];
-          ip += 4;
-        break;
-
-      default:
-        if ( ip[-1] >= 32 )
-        {
-          if ( ip[-1] < 247 )
-            value = (FT_Long)ip[-1] - 139;
-          else
+        case 255:    /* four bytes integer */
           {
-            if ( ++ip > limit )
+            if (ip+4 > limit)
             {
-              FT_ERROR(( "T1_Parse_CharStrings: unexpected EOF in integer\n" ));
+              FT_ERROR(( "T1.Parse_CharStrings : unexpected EOF in integer\n" ));
               goto Syntax_Error;
             }
 
-            if ( ip[-2] < 251 )
-              value = ( (FT_Long)( ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
+            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
-              value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
+            {
+              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",
+          else
+          {
+            FT_ERROR(( "T1.Parse_CharStrings : invalid byte (%d)\n",
                      ip[-1] ));
-          goto Syntax_Error;
-        }
+            goto Syntax_Error;
+          }
       }
 
       /* push value if needed */
@@ -703,7 +603,7 @@
       {
         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
         {
-          FT_ERROR(( "T1_Parse_CharStrings: Stack overflow!\n" ));
+          FT_ERROR(( "T1.Parse_CharStrings : Stack overflow !!\n" ));
           goto Syntax_Error;
         }
 
@@ -710,113 +610,116 @@
         *top++       = value;
         decoder->top = top;
       }
+
       else if ( op == op_callothersubr ) /* check arguments differently */
       {
-        if ( top - decoder->stack < 2 )
+        if ( top - decoder->stack < 2)
           goto Stack_Underflow;
 
         top -= 2;
 
-        switch ( top[1] )
+        switch (top[1])
         {
-        case 1:   /* start flex feature ----------------------------- */
-          if ( top[0] != 0 )
-            goto Unexpected_OtherSubr;
+          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;
+              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 ------------------------------- */
-          {
-            FT_Int      index;
-            FT_Vector*  flex;
+          case 2:   /* add flex vector ------------------------------- */
+            {
+              FT_Int      index;
+              FT_Vector*  flex;
 
+              if (top[0] != 0) goto Unexpected_OtherSubr;
 
-            if ( top[0] != 0 )
-              goto Unexpected_OtherSubr;
+              top -= 2;
+              if (top < decoder->stack) goto Stack_Underflow;
 
-            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;
+              }
 
-            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;
 
-            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;
-          }
+          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;
+              if (top[0] != 3) goto Unexpected_OtherSubr;
 
-          top -= 3;
-          if ( top < decoder->stack )
-            goto Stack_Underflow;
+              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;
-          }
+              /* 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;
+              decoder->flex_state = 0;
+              decoder->top        = top;
 
-          error = t1operator_flex( decoder, top[0], top[1], top[2] );
-          break;
+              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;
-          }
+          case 3:  /* change hints ------------------------------------ */
+            {
+              if (top[0] != 1) goto Unexpected_OtherSubr;
 
-          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;
-          }
+              /* eat the following "pop" */
+              if (ip+2 > limit)
+              {
+                FT_ERROR(( "T1.Parse_CharStrings: invalid escape (12+%d)\n",
+                         ip[-1] ));
+                goto Syntax_Error;
+              }
 
-          ip += 2;
+              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;
+              }
 
-          error = hints->change_hints( builder );
-          break;
+              ip    += 2;
+              error  = hints->change_hints(builder);
+            }
+            break;
 
-        default:
-          /* invalid OtherSubrs call */
-        Unexpected_OtherSubr:
-          FT_ERROR(( "T1_Parse_CharStrings: unexpected OtherSubrs [%d %d]\n",
+
+          default:
+            /* invalid OtherSubrs call */
+          Unexpected_OtherSubr:
+            FT_ERROR(( "T1.Parse_CharStrings: unexpected OtherSubrs [%d %d]\n",
                      top[0], top[1] ));
-          goto Syntax_Error;
+            goto Syntax_Error;
         }
         decoder->top = top;
       }
@@ -824,176 +727,177 @@
       {
         FT_Int  num_args = args_count[op];
 
-
         if ( top - decoder->stack < num_args )
           goto Stack_Underflow;
 
         top -= num_args;
 
-        switch ( op )
+        switch (op)
         {
-        case op_endchar:
-          error = builds->end_char( builder );
-          break;
+          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_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_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_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_closepath:
+            error = builds->close_path( builder );
+            break;
 
-        case op_hlineto:
-          error = builds->rline_to( builder, top[0], 0 );
-          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_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_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_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_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_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_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_vlineto:
+            error = builds->rline_to( builder, 0, top[0] );
+            break;
 
-        case op_vmoveto:
-          error = builds->rmove_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_dotsection:
+            error = hints->dot_section( builder );
+            break;
 
-        case op_hstem:
-          error = hints->stem( builder, top[0], top[1], 0 );
-          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_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_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_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:
-          {
-            FT_Int  index = top[0];
-
-
-            if ( index < 0 || index >= num_subrs )
+          case op_div:
+            if (top[1])
+              *top++ = top[0] / top[1];
+            else
             {
-              FT_ERROR(( "T1_Parse_CharStrings: invalid subrs index\n" ));
+              FT_ERROR(( "T1.Parse_CHarStrings : division by 0\n" ));
               goto Syntax_Error;
             }
+            break;
 
-            if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
+          case op_callsubr:
             {
-              FT_ERROR(( "T1_Parse_CharStrings: too many nested subrs\n" ));
-              goto Syntax_Error;
+              FT_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;
 
-            zone->cursor = ip;  /* save current instruction pointer */
+          case op_pop:
+            FT_ERROR(( "T1.Parse_CharStrings : unexpected POP\n" ));
+            goto Syntax_Error;
 
-            zone++;
-            zone->base   = subrs_base[index];
-            zone->limit  = zone->base + subrs_len[index];
-            zone->cursor = zone->base;
 
-            if ( !zone->base )
+          case op_return:
+            if ( zone <= decoder->zones )
             {
-              FT_ERROR(( "T1_Parse_CharStrings: invoking empty subrs!\n" ));
+              FT_ERROR(( "T1.Parse_CharStrings : unexpected return\n" ));
               goto Syntax_Error;
             }
 
-            decoder->zone = zone;
-            ip            = zone->base;
+            zone--;
+            ip            = zone->cursor;
             limit         = zone->limit;
-          }
-          break;
+            decoder->zone = zone;
+            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" ));
+          case op_setcurrentpoint:
+            FT_ERROR(( "T1.Parse_CharStrings : unexpected SETCURRENTPOINT\n" ));
             goto Syntax_Error;
-          }
+            break;
 
-          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;
+          default:
+            FT_ERROR(( "T1.Parse_CharStrings : unhandled opcode %d\n", op ));
+            goto Syntax_Error;
         }
 
         decoder->top = top;
@@ -1010,140 +914,83 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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    :: A pointer to the glyph builder object.               */
-  /*                                                                       */
-  /*    num_points :: The number of points that will be added later.       */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType 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 has been invoked.                                         */
-  /*                                                                       */
+
+/*************************************************************************/
+/*                                                                       */
+/* <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
   FT_Error  T1_Add_Points( T1_Builder*  builder,
                            FT_Int       num_points )
   {
-    FT_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;
-      FT_Error   error;
-      FT_Int     increment = builder->current.points - builder->base.points;
-      FT_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, FT_Vector )  ||
-
-           REALLOC_ARRAY( builder->base.tags,
-                          current, builder->max_points, FT_Byte )    )
-        return error;
-
-      builder->current.points = builder->base.points + increment;
-      builder->current.tags   = builder->base.tags   + increment;
-    }
-
-    return T1_Err_Ok;
+    return FT_GlyphLoader_Check_Points( builder->loader, num_points, 0 );
   }
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <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        */
-  /*    function grows the load outline's arrays accordingly.              */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    builder      :: A pointer to the glyph builder object.             */
-  /*                                                                       */
-  /*    num_contours :: The number of contours that will be added later.   */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType 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.                                                           */
-  /*                                                                       */
+/*************************************************************************/
+/*                                                                       */
+/* <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
   FT_Error  T1_Add_Contours( T1_Builder*  builder,
                              FT_Int       num_contours )
   {
-    FT_Int    new_contours;
-
-
-    new_contours = builder->base.n_contours +
-                   builder->current.n_contours +
-                   num_contours;
-
-    if ( new_contours > builder->max_contours && builder->load_points )
-    {
-      FT_Error  error;
-      FT_Memory memory = builder->memory;
-      FT_Int    increment = builder->current.contours -
-                              builder->base.contours;
-      FT_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, FT_Short ) )
-        return error;
-
-      builder->current.contours = builder->base.contours + increment;
-    }
-
-    return T1_Err_Ok;
+    return FT_GlyphLoader_Check_Points( builder->loader, 0, num_contours );
   }
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /**********                                                      *********/
-  /**********            COMPUTE THE MAXIMUM ADVANCE WIDTH         *********/
-  /**********                                                      *********/
-  /**********    The following code is in charge of computing      *********/
-  /**********    the maximum advance width of the font.  It        *********/
-  /**********    quickly processes each glyph charstring to        *********/
-  /**********    extract the value from either a `sbw' or `seac'   *********/
-  /**********    operator.                                         *********/
-  /**********                                                      *********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********           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
   FT_Error  maxadv_sbw( T1_Decoder*  decoder,
                         FT_Pos       sbx,
@@ -1151,13 +998,12 @@
                         FT_Pos       wx,
                         FT_Pos       wy )
   {
-    UNUSED( sbx );
-    UNUSED( sby );
-    UNUSED( wy );
-
-    if ( wx > decoder->builder.advance.x )
+    if (wx > decoder->builder.advance.x)
       decoder->builder.advance.x = wx;
 
+    UNUSED(sbx);
+    UNUSED(sby);
+    UNUSED(wy);
     return -1;    /* return an error code to exit the Type 1 parser */
                   /* immediately.                                   */
   }
@@ -1170,39 +1016,40 @@
     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.          */
+  /* 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.                  */
+  /* 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
+    (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_hinter_interface always return an 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,
+    (T1_Hinter_DotSection)   maxadv_error,
+    (T1_Hinter_ChangeHints)  maxadv_error,
+    (T1_Hinter_Stem)         maxadv_error,
+    (T1_Hinter_Stem3)        maxadv_error,
   };
 
 
+
   LOCAL_FUNC
   FT_Error  T1_Compute_Max_Advance( T1_Face  face,
-                                    FT_Int*  max_advance )
+                                    FT_Int  *max_advance )
   {
     FT_Error    error;
     T1_Decoder  decoder;
@@ -1209,10 +1056,9 @@
     FT_Int      glyph_index;
     T1_Font*    type1 = &face->type1;
 
-
     *max_advance = 0;
 
-    /* Initialize load decoder */
+    /* Initialise load decoder */
     T1_Init_Decoder( &decoder, &maxadv_hinter_interface );
 
     T1_Init_Builder( &decoder.builder, face, 0, 0,
@@ -1219,8 +1065,7 @@
                      &maxadv_builder_interface );
 
     /* For each glyph, parse the glyph charstring and extract */
-    /* the advance width.                                     */
-
+    /* the advance width..                                    */
     for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
     {
       /* now get load the unscaled outline */
@@ -1230,49 +1075,49 @@
                                     type1->num_subrs,
                                     type1->subrs,
                                     type1->subrs_len );
-      /* ignore error if one occured - skip to next glyph */
+      /* ignore the error if one occured - skip to next glyph */
     }
 
     *max_advance = decoder.builder.advance.x;
-
     return T1_Err_Ok;
   }
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /**********                                                      *********/
-  /**********               UNHINTED GLYPH LOADER                  *********/
-  /**********                                                      *********/
-  /**********    The following code is in charge of loading a      *********/
-  /**********    single outline.  It completely ignores hinting    *********/
-  /**********    and is used when FT_LOAD_NO_HINTING is set.       *********/
-  /**********                                                      *********/
-  /**********      The Type 1 hinter is located in `t1hint.c'      *********/
-  /**********                                                      *********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********              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
   FT_Error  close_open_path( T1_Builder*  builder )
   {
     FT_Error     error;
-    FT_Outline*  cur = &builder->current;
+    FT_Outline*  cur = builder->current;
     FT_Int       num_points;
     FT_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                 */
 
-    /* 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;
+    /* 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;
 
@@ -1284,16 +1129,14 @@
       FT_Vector*  point;
       char*       tags;
 
-
       error = T1_Add_Points( builder, num_points );
-      if ( error )
-        return error;
+      if (error) return error;
 
       point = cur->points + cur->n_points;
-      tags  = cur->tags   + cur->n_points;
+      tags  = cur->tags  + cur->n_points;
 
-      source_point = point - 2;
-      source_tags  = tags  - 2;
+      source_point   = point - 2;
+      source_tags   = tags - 2;
 
       cur->n_points += num_points;
 
@@ -1301,14 +1144,13 @@
         do
         {
           *point++ = *source_point--;
-          *tags++  = *source_tags--;
+          *tags++ = *source_tags--;
           num_points--;
         }
-        while ( num_points > 0 );
+        while (num_points > 0);
     }
 
     builder->path_begun = 0;
-
     return T1_Err_Ok;
   }
 
@@ -1316,52 +1158,46 @@
   static
   FT_Error  gload_closepath( T1_Builder*  builder )
   {
-    FT_Outline*  cur = &builder->current;
+    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;
+      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
 
-#endif /* T1_CONFIG_OPTION_DISABLE_HINTER */
-
     builder->path_begun = 0;
-
     return T1_Err_Ok;
   }
 
 
+
   static
   FT_Error  gload_endchar( T1_Builder*  builder )
   {
-    FT_Outline*  cur = &builder->current;
     FT_Error     error;
 
-
     /* close path if needed */
-    if ( builder->path_begun )
+    if (builder->path_begun)
     {
       error = close_open_path( builder );
-      if ( error )
-        return error;
+      if (error) return error;
     }
 
     error = gload_closepath( builder );
 
-    builder->base.n_points   += cur->n_points;
-    builder->base.n_contours += cur->n_contours;
+    FT_GlyphLoader_Add( builder->loader );
 
     return error;
   }
 
 
+
   static
   FT_Error  gload_sbw( T1_Builder*  builder,
                        FT_Pos       sbx,
@@ -1376,11 +1212,12 @@
 
     builder->last.x = sbx;
     builder->last.y = sby;
-
     return 0;
   }
 
 
+
+
   static
   FT_Error  gload_rlineto( T1_Builder*  builder,
                            FT_Pos       dx,
@@ -1387,14 +1224,12 @@
                            FT_Pos       dy )
   {
     FT_Error     error;
-    FT_Outline*  cur = &builder->current;
+    FT_Outline*  cur = builder->current;
     FT_Vector    vec;
 
-
     /* grow buffer if necessary */
-    error = T1_Add_Points( builder, 1 );
-    if ( error )
-      return error;
+    error = T1_Add_Points  ( builder, 1 );
+    if (error) return error;
 
     if ( builder->load_points )
     {
@@ -1403,14 +1238,13 @@
       vec.y = builder->last.y + dy;
 
       cur->points[cur->n_points] = vec;
-      cur->tags  [cur->n_points] = FT_Curve_Tag_On;
+      cur->tags [cur->n_points] = FT_Curve_Tag_On;
 
       builder->last = vec;
     }
     cur->n_points++;
 
-    builder->path_begun = 1;
-
+    builder->path_begun  = 1;
     return T1_Err_Ok;
   }
 
@@ -1421,23 +1255,20 @@
                            FT_Pos       dy )
   {
     FT_Error     error;
-    FT_Outline*  cur = &builder->current;
+    FT_Outline*  cur = builder->current;
     FT_Vector    vec;
 
-
-    /* in the case where `path_begun' is set, we have an `rmoveto' */
-    /* after some normal path definition. If 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 paths, so we'll close it explicitely there.          */
-
+    /* 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->type1.paint_type == 1 )
     {
       if ( builder->face->type1.paint_type == 1 )
       {
         error = close_open_path( builder );
-        if ( error )
-          return error;
+        if (error) return error;
       }
     }
 
@@ -1444,12 +1275,11 @@
     /* grow buffer if necessary */
     error = T1_Add_Contours( builder, 1 ) ||
             T1_Add_Points  ( builder, 1 );
-    if ( error )
-      return error;
+    if (error) return error;
 
     /* save current contour, if any */
     if ( cur->n_contours > 0 )
-      cur->contours[cur->n_contours - 1] = cur->n_points - 1;
+      cur->contours[cur->n_contours-1] = cur->n_points-1;
 
     if ( builder->load_points )
     {
@@ -1457,7 +1287,7 @@
       vec.x = builder->last.x + dx;
       vec.y = builder->last.y + dy;
       cur->points[cur->n_points] = vec;
-      cur->tags  [cur->n_points] = FT_Curve_Tag_On;
+      cur->tags [cur->n_points] = FT_Curve_Tag_On;
 
       builder->last = vec;
     }
@@ -1479,36 +1309,32 @@
                              FT_Pos       dy3 )
   {
     FT_Error     error;
-    FT_Outline*  cur = &builder->current;
+    FT_Outline*  cur = builder->current;
     FT_Vector    vec;
     FT_Vector*   points;
     char*        tags;
 
     /* grow buffer if necessary */
-    error = T1_Add_Points( builder, 3 );
-    if ( error )
-      return error;
+    error = T1_Add_Points  ( builder, 3 );
+    if (error) return error;
 
     if ( builder->load_points )
     {
       /* save point */
       points = cur->points + cur->n_points;
-      tags   = cur->tags   + cur->n_points;
+      tags  = cur->tags  + cur->n_points;
 
       vec.x = builder->last.x + dx1;
       vec.y = builder->last.y + dy1;
-      points[0] = vec;
-      tags[0]   = FT_Curve_Tag_Cubic;
+      points[0] = vec;  tags[0] = FT_Curve_Tag_Cubic;
 
       vec.x += dx2;
       vec.y += dy2;
-      points[1] = vec;
-      tags[1]   = FT_Curve_Tag_Cubic;
+      points[1] = vec;  tags[1] = FT_Curve_Tag_Cubic;
 
       vec.x += dx3;
       vec.y += dy3;
-      points[2] = vec;
-      tags[2]   = FT_Curve_Tag_On;
+      points[2] = vec;  tags[2] = FT_Curve_Tag_On;
 
       builder->last = vec;
     }
@@ -1519,6 +1345,8 @@
   }
 
 
+
+
   static
   FT_Error  gload_ignore( void )
   {
@@ -1541,12 +1369,12 @@
   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
+    (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
   };
 
 
@@ -1553,18 +1381,19 @@
   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   */
+    (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   */
   };
 
 
+
   /*****************************************************************/
   /*                                                               */
   /*  Hinter overview :                                            */
   /*                                                               */
-  /*    This is a two-pass hinter.  On the first pass, the hints   */
+  /*    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.                                            */
   /*                                                               */
@@ -1582,15 +1411,19 @@
                                   FT_UInt      glyph_index,
                                   FT_Bool      recurse )
   {
-    T1_Builder*   builder = &decoder->builder;
-    T1_GlyphSlot  glyph   = builder->glyph;
-    T1_Font*      type1   = &builder->face->type1;
-    FT_Outline    old_base;
-    FT_Error      error;
+    T1_Builder*      builder = &decoder->builder;
+    T1_GlyphSlot     glyph   = builder->glyph;
+    T1_Font*         type1   = &builder->face->type1;
+    FT_UInt          old_points, old_contours;
+    FT_GlyphLoader*  loader = decoder->builder.loader;
+    FT_Error         error;
     
-
     /* Pass 1 - try to load first glyph, simply recording points */
-    old_base = builder->base;
+    old_points   = loader->base.outline.n_points;
+    old_contours = loader->base.outline.n_contours;
+    
+    FT_GlyphLoader_Prepare( decoder->builder.loader );
+
     T1_Reset_Builder( builder, 0 );
     
     builder->no_recurse                = recurse;
@@ -1604,61 +1437,51 @@
                                   type1->num_subrs,
                                   type1->subrs,
                                   type1->subrs_len );
-    if ( error )
-      goto Exit;                                  
+    if (error) goto Exit;                                  
 
-    /* check for composite (i.e. `seac' operator) */
+    /* check for composite (i.e. "seac" operator) */
     if ( glyph->root.format == ft_glyph_format_composite )
     {
       /* this is a composite glyph, we must then load the first one, */
       /* then load the second one on top of it and translate it by a */
-      /* fixed amount.                                               */
+      /* fixed amount..                                              */
+      FT_UInt      n_base_points;
+      FT_SubGlyph* subglyph = loader->base.subglyphs;
+      T1_Size      size = builder->size;
+      FT_Pos       dx, dy;
+      FT_Vector    left_bearing, advance;
 
-      FT_Outline*   cur  = &builder->current;
-      FT_UInt       n_base_points;
-      FT_SubGlyph*  subglyph = glyph->root.subglyphs;
-      T1_Size       size = builder->size;
-      FT_Pos        dx, dy;
-      FT_Vector     left_bearing, advance;
-
-
       /* clean glyph format */
       glyph->root.format = ft_glyph_format_none;
 
-      /* First load `bchar' in builder */
+      /* First load "bchar" in builder */
       builder->no_recurse = 0;
       error = t1_load_hinted_glyph( decoder, subglyph->index, 0 );
-      if ( error )
-        goto Exit;
+      if (error) goto Exit;
 
       /* save the left bearing and width of the base character */
-      /* as they will be erased by the next load.              */
+      /* as they will be erased by the next load..             */
       left_bearing = builder->left_bearing;
       advance      = builder->advance;
 
-      /* Then load `achar' in builder */
-      n_base_points = builder->base.n_points;
+      /* Then load "achar" in builder */
+      n_base_points = builder->base->n_points;
       subglyph++;
-
       error = t1_load_hinted_glyph( decoder, subglyph->index, 0 );
-      if ( error )
-        goto Exit;
+      if (error) goto Exit;
       
-      /* adjust contours in accented character outline */
-      {
-        FT_Int  n;
-
-
-        for ( n = 0; n < cur->n_contours; n++ )
-          cur->contours[n] += n_base_points;
-      }
-
       /* Finally, move the accent */
       dx = FT_MulFix( subglyph->arg1, size->root.metrics.x_scale );
       dy = FT_MulFix( subglyph->arg2, size->root.metrics.y_scale );
-      dx = ( dx + 32 ) & -64;
-      dy = ( dy + 32 ) & -64;
-      FT_Outline_Translate( cur, dx, dy );
+      dx = (dx+32) & -64;
+      dy = (dy+32) & -64;
+      {
+        FT_Outline  dummy;
+        
+        dummy.n_points = loader->base.outline.n_points - n_base_points;
+        dummy.points   = loader->base.outline.points   + n_base_points;
+        FT_Outline_Translate( &dummy, dx, dy );
+      }
 
       /* restore the left side bearing and   */
       /* advance width of the base character */
@@ -1671,11 +1494,11 @@
       T1_Hint_Stems( &decoder->builder );
       
       /* undo the end-char */
-      builder->base.n_points   -= builder->current.n_points;
-      builder->base.n_contours -= builder->current.n_contours;
+      builder->base->n_points   = old_points;
+      builder->base->n_contours = old_contours;
 
       /* Pass 2 - record and scale/hint the points */
-      T1_Reset_Builder( &decoder->builder, 0 );
+      T1_Reset_Builder( builder, 0 );
       
       builder->pass            = 1;
       builder->no_recurse      = 0;
@@ -1689,17 +1512,16 @@
     }
     
     /* save new glyph tables */
-    if ( recurse )
+    if (recurse)
       T1_Done_Builder( builder );
     
   Exit:
     return error;
   }                                  
-
-
-#endif /* T1_CONFIG_OPTION_DISABLE_HINTER */
+#endif
   
 
+
   LOCAL_FUNC
   FT_Error  T1_Load_Glyph( T1_GlyphSlot  glyph,
                            T1_Size       size,
@@ -1706,14 +1528,13 @@
                            FT_Int        glyph_index,
                            FT_Int        load_flags )
   {
-    FT_Error    error;
-    T1_Decoder  decoder;
-    T1_Face     face = (T1_Face)glyph->root.face;
-    FT_Bool     hinting;
-    T1_Font*    type1 = &face->type1;
+    FT_Error        error;
+    T1_Decoder      decoder;
+    T1_Face         face = (T1_Face)glyph->root.face;
+    FT_Bool         hinting;
+    T1_Font*        type1 = &face->type1;
 
-
-    if ( load_flags & FT_LOAD_NO_RECURSE )
+    if (load_flags & FT_LOAD_NO_RECURSE)
       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
 
     glyph->x_scale = size->root.metrics.x_scale;
@@ -1728,7 +1549,7 @@
 
 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
 
-    hinting = ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0;
+    hinting = (load_flags & (FT_LOAD_NO_SCALE|FT_LOAD_NO_HINTING)) == 0;
 
     if ( hinting )
     {
@@ -1739,9 +1560,8 @@
       error = t1_load_hinted_glyph( &decoder, glyph_index, 1 );
     }
     else
+#endif
 
-#endif /* T1_CONFIG_OPTION_DISABLE_HINTER */
-
     {
       T1_Init_Decoder( &decoder, &gload_hinter_interface );
 
@@ -1748,7 +1568,7 @@
       T1_Init_Builder( &decoder.builder, face, size, glyph,
                        &gload_builder_interface );
 
-      decoder.builder.no_recurse = ( load_flags & FT_LOAD_NO_RECURSE ) != 0;
+      decoder.builder.no_recurse = !!(load_flags & FT_LOAD_NO_RECURSE);
 
       /* now load the unscaled outline */
       error = T1_Parse_CharStrings( &decoder,
@@ -1762,13 +1582,14 @@
       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 )
+
+    /* Now, set the metrics.. - this is rather simple, as : */
+    /* the left side bearing is the xMin, and the top side  */
+    /* bearing the yMax..                                   */
+    if (!error)
     {
       /* for composite glyphs, return only the left side bearing and the */
-      /* advance width.                                                  */
+      /* advance width..                                                 */
       if ( load_flags & FT_LOAD_NO_RECURSE )
       {
         glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
@@ -1779,20 +1600,18 @@
         FT_BBox           cbox;
         FT_Glyph_Metrics* metrics = &glyph->root.metrics;
 
-
         /* apply the font matrix */
-        FT_Outline_Transform( &glyph->root.outline,
-                              &face->type1.font_matrix );
+        FT_Outline_Transform( &glyph->root.outline, &face->type1.font_matrix );
 
         FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
 
         /* grid fit the bounding box if necessary */
-        if ( hinting )
+        if (hinting)
         {
           cbox.xMin &= -64;
           cbox.yMin &= -64;
-          cbox.xMax  = ( cbox.xMax + 63 ) & -64;
-          cbox.yMax  = ( cbox.yMax + 63 ) & -64;
+          cbox.xMax = ( cbox.xMax+63 ) & -64;
+          cbox.yMax = ( cbox.yMax+63 ) & -64;
         }
 
         metrics->width  = cbox.xMax - cbox.xMin;
@@ -1802,7 +1621,7 @@
         metrics->horiBearingY = cbox.yMax;
 
         /* copy the _unscaled_ advance width */
-        metrics->horiAdvance = decoder.builder.advance.x;
+        metrics->horiAdvance  = decoder.builder.advance.x;
 
         /* make up vertical metrics */
         metrics->vertBearingX = 0;
@@ -1818,29 +1637,28 @@
 
         glyph->root.outline.flags |= ft_outline_reverse_fill;
 
-#if 0
+        /*
         glyph->root.outline.second_pass    = TRUE;
-        glyph->root.outline.high_precision = size->root.metrics.y_ppem < 24;
+        glyph->root.outline.high_precision = ( size->root.metrics.y_ppem < 24 );
         glyph->root.outline.dropout_mode   = 2;
-#endif
+        */
 
         if ( hinting )
         {
-          /* adjust the advance width               */
-          /* XXX TODO: consider stem hints grid-fit */
+          /* 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 )
+        else if ( (load_flags & FT_LOAD_NO_SCALE) == 0 )
         {
           /* scale the outline and the metrics */
           FT_Int       n;
-          FT_Outline*  cur = &decoder.builder.base;
+          FT_Outline*  cur = decoder.builder.base;
           FT_Vector*   vec = cur->points;
           FT_Fixed     x_scale = glyph->x_scale;
           FT_Fixed     y_scale = glyph->y_scale;
 
-
           /* First of all, scale the points */
           for ( n = cur->n_points; n > 0; n--, vec++ )
           {
@@ -1859,6 +1677,7 @@
           metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
           metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
           metrics->vertAdvance  = FT_MulFix( metrics->vertAdvance,  x_scale );
+
         }
       }
     }
@@ -1866,5 +1685,3 @@
     return error;
   }
 
-
-/* END */
--- a/src/type1/t1gload.h
+++ b/src/type1/t1gload.h
@@ -1,21 +1,37 @@
-/***************************************************************************/
-/*                                                                         */
-/*  t1gload.h                                                              */
-/*                                                                         */
-/*    Type 1 Glyph Loader (specification).                                 */
-/*                                                                         */
-/*  Copyright 1996-2000 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
+/*******************************************************************
+ *
+ *  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
 
@@ -26,15 +42,25 @@
 #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 FT_Error  (*T1_Builder_EndChar)( T1_Builder*  loader );
 
-  typedef FT_Error  (*T1_Builder_Sbw)( T1_Builder*  loader,
-                                       FT_Pos       sbx,
-                                       FT_Pos       sby,
-                                       FT_Pos       wx,
-                                       FT_Pos       wy );
+  typedef FT_Error  (*T1_Builder_Sbw)    ( T1_Builder*  loader,
+                                           FT_Pos       sbx,
+                                           FT_Pos       sby,
+                                           FT_Pos       wx,
+                                           FT_Pos       wy );
 
   typedef FT_Error  (*T1_Builder_ClosePath)( T1_Builder*  loader );
 
@@ -54,17 +80,7 @@
                                             FT_Pos       dx3,
                                             FT_Pos       dy3 );
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Structure>                                                           */
-  /*    T1_Builder_Funcs                                                   */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A structure to store the address of various functions used by a    */
-  /*    glyph builder to implement the outline's `path construction'.      */
-  /*                                                                       */
-  typedef struct  T1_Builder_Funcs_
+  typedef struct T1_Builder_Funcs_
   {
     T1_Builder_EndChar    end_char;
     T1_Builder_Sbw        set_bearing_point;
@@ -76,98 +92,94 @@
   } T1_Builder_Funcs;
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Structure>                                                           */
-  /*    T1_Builder                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A structure used during glyph loading to store its outline.        */
-  /*                                                                       */
-  /* <Fields>                                                              */
-  /*    memory       :: The current memory object.                         */
-  /*                                                                       */
-  /*    face         :: The current face object.                           */
-  /*                                                                       */
-  /*    size         :: The current size object.                           */
-  /*                                                                       */
-  /*    glyph        :: The current glyph slot.                            */
-  /*                                                                       */
-  /*    current      :: The current glyph outline.                         */
-  /*                                                                       */
-  /*    base         :: The base glyph outline.                            */
-  /*                                                                       */
-  /*    max_points   :: The maximum number of points in builder outline.   */
-  /*                                                                       */
-  /*    max_contours :: The maximum number of contours in builder outline. */
-  /*                                                                       */
-  /*    last         :: The last point position.                           */
-  /*                                                                       */
-  /*    scale_x      :: The horizontal scale (FUnits to sub-pixels).       */
-  /*                                                                       */
-  /*    scale_y      :: The vertical scale (FUnits to sub-pixels).         */
-  /*                                                                       */
-  /*    pos_x        :: The horizontal translation (for composite glyphs). */
-  /*                                                                       */
-  /*    pos_y        :: The vertical translation (for composite glyphs).   */
-  /*                                                                       */
-  /*    left_bearing :: The left side bearing point.                       */
-  /*                                                                       */
-  /*    advance      :: The horizontal advance vector.                     */
-  /*                                                                       */
-  /*    no_recurse   ::                                                    */
-  /*                                                                       */
-  /*    bbox         :: The glyph's bounding box.                          */
-  /*                                                                       */
-  /*    path_begun   :: A flag which indicates that a new path has begun.  */
-  /*                                                                       */
-  /*    load_points  :: A flag which indicates, if not set, that no points */
-  /*                    are loaded.                                        */
-  /*                                                                       */
-  /*    pass         :: The pass number for multi-pass hinters.            */
-  /*                                                                       */
-  /*    hint_point   :: The index of the next point to hint.               */
-  /*                                                                       */
-  /*    funcs        :: A table of builder functions used to perform the   */
-  /*                    outline's path construction.                       */
-  /*                                                                       */
-  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 */
+/*************************************************************************/
+/*                                                                       */
+/* <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..                        */
+/*                                                                       */
+/*                                                                       */
+/*                                                                       */
+/*                                                                       */
 
-    FT_Int        max_points;    /* capacity of base outline in points   */
-    FT_Int        max_contours;  /* capacity of base outline in contours */
+  struct T1_Builder_
+  {
+    FT_Memory        memory;
+    T1_Face          face;
+    T1_Size          size;
+    T1_GlyphSlot     glyph;
+    FT_GlyphLoader*  loader;
 
-    FT_Vector     last;
+    FT_Outline*      current;       /* the current glyph outline   */
+    FT_Outline*      base;          /* the composite glyph outline */
 
-    FT_Fixed      scale_x;
-    FT_Fixed      scale_y;
+    FT_Vector        last;
 
-    FT_Pos        pos_x;
-    FT_Pos        pos_y;
+    FT_Fixed         scale_x;
+    FT_Fixed         scale_y;
 
-    FT_Vector     left_bearing;
-    FT_Vector     advance;
-    FT_Bool       no_recurse;
+    FT_Pos           pos_x;
+    FT_Pos           pos_y;
 
-    FT_BBox       bbox;          /* bounding box */
-    FT_Bool       path_begun;
-    FT_Bool       load_points;
+    FT_Vector        left_bearing;
+    FT_Vector        advance;
+    FT_Bool          no_recurse;
 
-    FT_Int        pass;
-    FT_Int        hint_point;
+    FT_BBox          bbox;          /* bounding box */
+    FT_Bool          path_begun;
+    FT_Bool          load_points;
 
+    FT_Int           pass;
+    FT_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 FT_Error  (*T1_Hinter_ChangeHints)( T1_Builder*  builder );
 
   typedef FT_Error  (*T1_Hinter_DotSection)( T1_Builder*  builder );
@@ -177,6 +189,7 @@
                                        FT_Pos       width,
                                        FT_Bool      vertical );
 
+
   typedef FT_Error  (*T1_Hinter_Stem3)( T1_Builder*  builder,
                                         FT_Pos       pos0,
                                         FT_Pos       width0,
@@ -186,27 +199,18 @@
                                         FT_Pos       width2,
                                         FT_Bool      vertical );
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Structure>                                                           */
-  /*    T1_Hinter_Funcs                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A structure to store the address of various functions used by a    */
-  /*    Type 1 hinter to perform outline hinting.                          */
-  /*                                                                       */
   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_ChangeHints     change_hints;
+    T1_Hinter_DotSection      dot_section;
+    T1_Hinter_Stem            stem;
+    T1_Hinter_Stem3           stem3;
 
   } T1_Hinter_Funcs;
 
 
-  typedef enum  T1_Operator_
+
+  typedef enum T1_Operator_
   {
     op_none = 0,
     op_endchar,
@@ -240,8 +244,10 @@
   } T1_Operator;
 
 
+
+
   /* execution context charstring zone */
-  typedef struct  T1_Decoder_Zone_
+  typedef struct T1_Decoder_Zone_
   {
     FT_Byte*  base;
     FT_Byte*  limit;
@@ -250,54 +256,166 @@
   } T1_Decoder_Zone;
 
 
-  typedef struct  T1_Decoder_
+  typedef struct T1_Decoder_
   {
-    T1_Builder        builder;
-    T1_Hinter_Funcs   hinter;
+    T1_Builder         builder;
+    T1_Hinter_Funcs    hinter;
 
-    FT_Int            stack[T1_MAX_CHARSTRINGS_OPERANDS];
-    FT_Int*           top;
+    FT_Int             stack[ T1_MAX_CHARSTRINGS_OPERANDS ];
+    FT_Int*            top;
 
-    T1_Decoder_Zone   zones[T1_MAX_SUBRS_CALLS + 1];
-    T1_Decoder_Zone*  zone;
+    T1_Decoder_Zone    zones[ T1_MAX_SUBRS_CALLS+1 ];
+    T1_Decoder_Zone*   zone;
 
-    FT_Int            flex_state;
-    FT_Int            num_flex_vectors;
-    FT_Vector         flex_vectors[7];
+    FT_Int             flex_state;
+    FT_Int             num_flex_vectors;
+    FT_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
+ *
+ *********************************************************************/
+
   LOCAL_DEF
-  void  T1_Init_Builder( T1_Builder*              builder,
-                         T1_Face                  face,
-                         T1_Size                  size,
-                         T1_GlyphSlot             glyph,
-                         const T1_Builder_Funcs*  funcs );
+  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
+ *
+ *********************************************************************/
+
   LOCAL_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
+ *
+ *********************************************************************/
+
   LOCAL_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
   FT_Error  T1_Compute_Max_Advance( T1_Face  face,
-                                    FT_Int*  max_advance );
+                                    FT_Int  *max_advance );
 
+
+  /* This function is exported, because it is used by the T1Dump utility */
   LOCAL_DEF
-  FT_Error  T1_Parse_CharStrings( T1_Decoder*  decoder,
-                                  FT_Byte*     charstring_base,
-                                  FT_Int       charstring_len,
-                                  FT_Int       num_subrs,
-                                  FT_Byte**    subrs_base,
-                                  FT_Int*      subrs_len );
+  FT_Error   T1_Parse_CharStrings( T1_Decoder*  decoder,
+                                   FT_Byte*     charstring_base,
+                                   FT_Int       charstring_len,
+                                   FT_Int       num_subrs,
+                                   FT_Byte**    subrs_base,
+                                   FT_Int*      subrs_len );
 
+
+
+/*************************************************************************/
+/*                                                                       */
+/* <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
   FT_Error  T1_Add_Points( T1_Builder*  builder,
                            FT_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
   FT_Error  T1_Add_Contours( T1_Builder*  builder,
                              FT_Int       num_contours );
@@ -314,8 +432,4 @@
   }
 #endif
 
-
 #endif /* T1GLOAD_H */
-
-
-/* END */
--- a/src/type1/t1hinter.c
+++ b/src/type1/t1hinter.c
@@ -1,42 +1,31 @@
-/***************************************************************************/
-/*                                                                         */
-/*  t1hinter.c                                                             */
-/*                                                                         */
-/*    Type 1 hinter (body).                                                */
-/*                                                                         */
-/*  Copyright 1996-2000 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
+/*******************************************************************
+ *
+ *  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..
+ *
+ ******************************************************************/
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* 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 <freetype/internal/ftdebug.h>
 #include <t1objs.h>
 #include <t1hinter.h>
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
-  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
-  /* messages during execution.                                            */
-  /*                                                                       */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_t1hint
+#define FT_COMPONENT  trace_t1hint    /* for debugging/tracing */
 
 
 #undef  ONE_PIXEL
@@ -43,14 +32,13 @@
 #define ONE_PIXEL  64
 
 #undef  ROUND
-#define ROUND( x )    ( ( x + ONE_PIXEL / 2 ) & -ONE_PIXEL )
+#define ROUND(x)   (( x + ONE_PIXEL/2 ) & -ONE_PIXEL)
 
 #undef  SCALE
-#define SCALE( val )  FT_MulFix( val, 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
@@ -57,92 +45,95 @@
 #define T1_ALIGN_BOTH    3
 
 
-  /* very simple bubble sort (not a lot of elements, mostly */
-  /* pre-sorted, no need for quicksort)                     */
+/************************************************************************
+ *
+ * <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.
+ *
+ ************************************************************************/
 
-  static
-  void  t1_sort_blues( FT_Int*  blues,
-                       FT_Int   count )
-  {
-    FT_Int  i, swap;
-    FT_Int* cur;
-
-
-    for ( i = 2; i < count; i += 2 )
-    {
-      cur = blues + i;
-      do
+      /* ultra simple bubble sort (not a lot of elements, mostly */
+      /* pre-sorted, no need for quicksort)                      */
+      static
+      void  t1_sort_blues( FT_Int*  blues,
+                           FT_Int   count )
       {
-        if ( cur[-1] < cur[0] )
-          break;
+        FT_Int  i, swap;
+        FT_Int* cur;
 
-        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 );
-    }
-  }
+        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 );
+        }
+      }
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    t1_set_blue_zones                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets a size object's blue zones during reset.  This will compute   */
-  /*    the `snap' zone corresponding to each blue zone.                   */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size :: A handle to target size object.                            */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType 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.  */
-  /*                                                                       */
+
   static
   FT_Error  t1_set_blue_zones( T1_Size  size )
   {
-    T1_Face         face = (T1_Face)size->root.face;
-    T1_Private*     priv = &face->type1.private_dict;
-    FT_Int          n;
-    FT_Int          blues[24];
-    FT_Int          num_bottom;
-    FT_Int          num_top;
-    FT_Int          num_blues;
-    T1_Size_Hints*  hints = size->hints;
-    T1_Snap_Zone*   zone;
-    FT_Pos          pix, orus;
-    FT_Pos          min, max, threshold;
-    FT_Fixed        scale;
-    FT_Bool         is_bottom;
+    T1_Face          face = (T1_Face)size->root.face;
+    T1_Private*      priv = &face->type1.private_dict;
+    FT_Int           n;
+    FT_Int           blues[24];
+    FT_Int           num_bottom;
+    FT_Int           num_top;
+    FT_Int           num_blues;
+    T1_Size_Hints*   hints = size->hints;
+    T1_Snap_Zone*    zone;
+    FT_Pos           pix, orus;
+    FT_Pos           min, max, threshold;
+    FT_Fixed         scale;
+    FT_Bool          is_bottom;
 
+    /**********************************************************************/
+    /*                                                                    */
+    /*  COPY BOTTOM AND TOP BLUE ZONES IN LOCAL ARRAYS                    */
+    /*                                                                    */
+    /*                                                                    */
 
-    /***********************************************************************/
-    /*                                                                     */
-    /*  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.      */
+    /* tables. They all must contain an even number of arguments        */
     if ( priv->num_other_blues & 1 ||
          priv->num_blue_values & 1 )
     {
-      FT_ERROR(( "t1_set_blue_zones: odd number of blue values\n" ));
+      FT_ERROR(( "T1.Copy_Blues : odd number of blue values\n" ));
       return T1_Err_Syntax_Error;
     }
 
-    /* copy the bottom blue zones from /OtherBlues */
+    /* copy the bottom blue zones from /OtherBlues           */
     num_top    = 0;
     num_bottom = priv->num_other_blues;
 
@@ -149,12 +140,12 @@
     for ( n = 0; n < num_bottom; n ++ )
       blues[n] = priv->other_blues[n];
 
-    /* add the first blue zone in /BlueValues to the table */
+    /* Add the first blue zone in /BlueValues to the table */
     num_top = priv->num_blue_values - 2;
     if ( num_top >= 0 )
     {
-      blues[num_bottom    ] = priv->blue_values[0];
-      blues[num_bottom + 1] = priv->blue_values[1];
+      blues[ num_bottom ] = priv->blue_values[0];
+      blues[num_bottom+1] = priv->blue_values[1];
 
       num_bottom += 2;
     }
@@ -168,7 +159,7 @@
     if ( num_top > 0 )
     {
       for ( n = 0; n < num_top; n++ )
-        blues[num_bottom + n] = priv->blue_values[n + 2];
+        blues[ num_bottom+n ] = priv->blue_values[n+2];
 
       /* sort the top blue zones */
       t1_sort_blues( blues + num_bottom, num_top );
@@ -179,29 +170,28 @@
     num_blues             = num_top + num_bottom;
     hints->num_blue_zones = ( num_blues ) >> 1;
 
-    /***********************************************************************/
-    /*                                                                     */
-    /* build blue snap zones from the local blues arrays                   */
-    /*                                                                     */
+    /**********************************************************************/
+    /*                                                                    */
+    /*    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 */
+    threshold = ONE_PIXEL/4;   /* 0.25 pixels */
 
     for ( n = 0; n < num_blues; n += 2, zone ++ )
     {
-      is_bottom = n < num_bottom ? 1 : 0;
+      is_bottom = ( n < num_bottom ? 1 : 0 );
 
-      orus = blues[n + is_bottom];  /* get alignement coordinate */
-      pix  = SCALE( orus );         /* scale it                  */
+      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 );
+      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;
+      if ( min > pix - threshold ) min = pix - threshold;
+      if ( max < pix + threshold ) max = pix + threshold;
 
       zone->orus = orus;
       zone->pix  = pix;
@@ -213,22 +203,24 @@
     zone = hints->blue_zones;
     for ( n = 0; n < num_blues-2; n += 2, zone ++ )
     {
-      if ( n != num_bottom - 2       &&
+      if ( n != num_bottom-2         &&
            zone[0].max > zone[1].min )
-        zone[0].max = zone[1].min = ( zone[0].pix + zone[1].pix ) / 2;
+      {
+        zone[0].max = zone[1].min = (zone[0].pix+zone[1].pix)/2;
+      }
     }
 
+
     /* Compare the current pixel size with the BlueScale value */
-    /* to know whether to supress overshoots.                  */
+    /* to know wether to supress overshoots..                  */
 
     hints->supress_overshoots =
-      size->root.metrics.y_ppem < FT_MulFix( 1000, priv->blue_scale );
+      ( 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
 
-    /* Now print the new blue values in tracing mode */
-
-    FT_TRACE2(( "Blue Zones for size object at $%08lx:\n", (long)size ));
+    FT_TRACE2(( "Blue Zones for size object at $%08lx :\n", (long)size ));
     FT_TRACE2(( "   orus    pix    min   max\n" ));
     FT_TRACE2(( "-------------------------------\n" ));
 
@@ -236,14 +228,14 @@
     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->orus,
+                zone->pix/64.0,
+                zone->min/64.0,
+                zone->max/64.0 ));
       zone++;
     }
-    FT_TRACE2(( "\nOvershoots are %s\n\n",
-                hints->supress_overshoots ? "supressed" : "active" ));
+    FT_TRACE2(( "\nOver shoots are %s\n\n",
+              hints->supress_overshoots ? "supressed" : "active" ));
 
 #endif /* DEBUG_LEVEL_TRACE */
 
@@ -251,35 +243,38 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    t1_set_snap_zones                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This function set a size object's stem snap zones.                 */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType 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 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.       */
-  /*                                                                       */
+
+/************************************************************************
+ *
+ * <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
   FT_Error  t1_set_snap_zones( T1_Size  size )
   {
@@ -290,11 +285,10 @@
     FT_Pos         standard_width;
     FT_Fixed       scale;
 
-    T1_Face         face  = (T1_Face)size->root.face;
-    T1_Private*     priv  = &face->type1.private_dict;
+    T1_Face         face = (T1_Face)size->root.face;
+    T1_Private*     priv = &face->type1.private_dict;
     T1_Size_Hints*  hints = size->hints;
 
-
     /* start with horizontal snap zones */
     direction      = 0;
     standard_width = priv->standard_width[0];
@@ -303,18 +297,16 @@
     orgs           = priv->snap_widths;
     scale          = size->root.metrics.x_scale;
 
-    while ( direction < 2 )
+    while (direction < 2)
     {
-      /*********************************************************************/
-      /*                                                                   */
-      /* Read and scale stem snap widths table from the physical font      */
-      /* record.                                                           */
-      /*                                                                   */
-
+      /*****************************************************************/
+      /*                                                               */
+      /*  Read and scale stem snap widths table from the physical      */
+      /*  font record.                                                 */
+      /*                                                               */
       FT_Pos  prev, orus, pix, min, max, threshold;
 
-
-      threshold = ONE_PIXEL / 4;
+      threshold = ONE_PIXEL/4;
       zone      = base_zone;
 
       if ( n_zones > 0 )
@@ -321,8 +313,8 @@
       {
         orus = *orgs++;
         pix  = SCALE( orus );
-        min  = pix - threshold;
-        max  = pix + threshold;
+        min  = pix-threshold;
+        max  = pix+threshold;
 
         zone->orus = orus;
         zone->pix  = pix;
@@ -334,12 +326,12 @@
           orus = *orgs++;
           pix  = SCALE( orus );
 
-          if ( pix - prev < 2 * threshold )
+          if ( pix-prev < 2*threshold )
           {
-            min = max = ( pix + prev ) / 2;
+            min = max = (pix+prev)/2;
           }
           else
-            min = pix - threshold;
+            min = pix-threshold;
 
           zone->max = max;
           zone++;
@@ -347,20 +339,19 @@
           zone->pix  = pix;
           zone->min  = min;
 
-          max  = pix + threshold;
+          max  = pix+threshold;
           prev = pix;
         }
         zone->max = max;
       }
 
+      /* print the scaled stem snap values in tracing modes */
 #ifdef FT_DEBUG_LEVEL_TRACE
 
-      /* print the scaled stem snap values in tracing mode */
+      FT_TRACE2(( "Set_Snap_Zones : first %s pass\n",
+                direction ? "vertical" : "horizontal" ));
 
-      FT_TRACE2(( "Set_Snap_Zones: first %s pass\n",
-                  direction ? "vertical" : "horizontal" ));
-
-      FT_TRACE2(( "Scaled original stem snap zones:\n" ));
+      FT_TRACE2(( "Scaled original stem snap zones :\n" ));
       FT_TRACE2(( "   orus   pix   min   max\n" ));
       FT_TRACE2(( "-----------------------------\n" ));
 
@@ -367,32 +358,30 @@
       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" ));
+                  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 ));
+      FT_TRACE2(( "Standard width = %d\n", standard_width ));
+#endif
 
-#endif /* FT_DEBUG_LEVEL_TRACE */
+      /*****************************************************************/
+      /*                                                               */
+      /*  Now, each snap width which is in the range of the standard   */
+      /*  set width will be removed from the list..                    */
+      /*                                                               */
 
-      /*********************************************************************/
-      /*                                                                   */
-      /* 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;
         FT_Pos         std_pix, std_min, std_max;
 
-
         std_pix = SCALE( standard_width );
 
-        std_min = std_pix - threshold;
-        std_max = std_pix + threshold;
+        std_min = std_pix-threshold;
+        std_max = std_pix+threshold;
 
         num_zones = 0;
         zone      = base_zone;
@@ -403,10 +392,8 @@
           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;
+            if ( std_min > zone->min ) std_min = zone->min;
+            if ( std_max < zone->max ) std_max = zone->max;
           }
           else
           {
@@ -416,16 +403,14 @@
           zone++;
         }
 
-        /*******************************************************************/
-        /*                                                                 */
-        /* Now, insert the standard width zone                             */
-        /*                                                                 */
+        /**********************************************/
+        /*  Now, insert the standard width zone       */
 
-        zone = base_zone + num_zones;
+        zone = base_zone+num_zones;
         while ( zone > base_zone && zone[-1].pix > std_max )
         {
           zone[0] = zone[-1];
-          zone--;
+          zone --;
         }
 
         /* check border zones */
@@ -432,7 +417,7 @@
         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 )
+        if ( zone < base_zone+num_zones && zone[1].min < std_max )
           zone[1].min = std_max;
 
         zone->orus = standard_width;
@@ -446,19 +431,16 @@
         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;
+      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
 
-      /* print the scaled stem snap values in tracing mode */
+      FT_TRACE2(( "Set_Snap_Zones : second %s pass\n",
+                direction ? "vertical" : "horizontal" ));
 
-      FT_TRACE2(( "Set_Snap_Zones: second %s pass\n",
-                  direction ? "vertical" : "horizontal" ));
-
-      FT_TRACE2(( "Scaled clipped stem snap zones:\n" ));
+      FT_TRACE2(( "Scaled clipped stem snap zones :\n" ));
       FT_TRACE2(( "   orus   pix   min   max\n" ));
       FT_TRACE2(( "-----------------------------\n" ));
 
@@ -465,16 +447,15 @@
       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 ));
+                  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
 
-#endif /* FT_DEBUG_LEVEL_TRACE */
-
       /* continue with vertical snap zone */
       direction++;
       standard_width = priv->standard_height[0];
@@ -488,145 +469,153 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T1_New_Size_Hinter                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Allocates a new hinter structure for a given size object.          */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType Error code.  0 means success.                             */
-  /*                                                                       */
+/************************************************************************
+ *
+ * <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
   FT_Error  T1_New_Size_Hinter( T1_Size  size )
   {
     FT_Memory  memory = size->root.face->memory;
 
-
-    return MEM_Alloc( size->hints, sizeof ( *size->hints ) );
+    return MEM_Alloc( size->hints, sizeof(*size->hints) );
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T1_Done_Size_Hinter                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Releases a given size object's hinter structure.                   */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
+/************************************************************************
+ *
+ * <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 )
+  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.                    */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size :: A handle to the size object.                               */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
+
+/************************************************************************
+ *
+ * <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
   FT_Error  T1_Reset_Size_Hinter( T1_Size  size )
   {
-    return t1_set_blue_zones( size ) || t1_set_snap_zones( 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.           */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    glyph :: A handle to the target glyph slot.                        */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
+
+/************************************************************************
+ *
+ * <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
   FT_Error  T1_New_Glyph_Hinter( T1_GlyphSlot  glyph )
   {
     FT_Memory  memory = glyph->root.face->memory;
 
-
-    return MEM_Alloc( glyph->hints, sizeof ( *glyph->hints ) );
+    return MEM_Alloc( glyph->hints, sizeof(*glyph->hints) );
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    T1_Done_Glyph_Hinter                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Releases a given glyph slot's hinter structure.                    */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    glyph :: A handle to the glyph slot.                               */
-  /*                                                                       */
+/************************************************************************
+ *
+ * <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    **********/
-  /**********                                                     **********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
 
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********              HINTED GLYPH LOADER                  *********/
+  /**********                                                   *********/
+  /**********   The following code is in charge of the first    *********/
+  /**********   and second pass when loading a single outline   *********/
+  /**********                                                   *********/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
 
   static
-  FT_Error  t1_hinter_ignore( void )
+  FT_Error   t1_hinter_ignore( void )
   {
-    /* do nothing, used for `dotsection' which is unsupported for now */
+    /* do nothing, used for "dotsection" which is unsupported for now */
     return 0;
   }
 
-
   static
-  FT_Error  t1_hinter_stem( T1_Builder*  builder,
-                            FT_Pos       pos,
-                            FT_Int       width,
-                            FT_Bool      vertical )
+  FT_Error   t1_hinter_stem( T1_Builder*  builder,
+                             FT_Pos       pos,
+                             FT_Int       width,
+                             FT_Bool      vertical )
   {
     T1_Stem_Table*   stem_table;
     T1_Stem_Hint*    stems;
@@ -635,7 +624,6 @@
     FT_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;
@@ -642,8 +630,9 @@
     num_stems  = stem_table->num_stems;
 
     /* Compute minimum and maximum coord for the stem */
-    min = pos + ( vertical ? builder->left_bearing.x
-                           : builder->left_bearing.y );
+    min = pos + ( vertical
+                ? builder->left_bearing.x
+                : builder->left_bearing.y );
 
     if ( width >= 0 )
       max = min + width;
@@ -656,8 +645,8 @@
       max = min;
     }
 
-    /* now scan the array.  If we find a stem with the same borders */
-    /* simply activate it.                                          */
+    /* now scan the array. If we find a stem with the same borders */
+    /* simply activate it..                                        */
     cur_stem = stems;
     new_stem = 1;
 
@@ -667,10 +656,10 @@
            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 )
+        if ( (cur_stem->hint_flags & T1_HINT_FLAG_ACTIVE) == 0)
         {
-          cur_stem->hint_flags |= T1_HINT_FLAG_ACTIVE;
-          stem_table->num_active++;
+          cur_stem->hint_flags  |= T1_HINT_FLAG_ACTIVE;
+          stem_table->num_active ++;
         }
         new_stem = 0;
         break;
@@ -678,16 +667,16 @@
     }
 
     /* add a new stem to the array when necessary */
-    if ( new_stem )
+    if (new_stem)
     {
-      if ( cur_stem >= stems + T1_HINTER_MAX_EDGES )
+      if (cur_stem >= stems + T1_HINTER_MAX_EDGES)
       {
-        FT_ERROR(( "t1_hinter_stem: : too many stems in glyph charstring\n" ));
+        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!                                */
+      /* a bug in the glyph loader !!                              */
       if ( builder->pass == 0 )
       {
         cur_stem->min_edge.orus = min;
@@ -699,7 +688,7 @@
       }
       else
       {
-        FT_ERROR(( "t1_hinter_stem: fatal glyph loader bug - pass2-stem\n" ));
+        FT_ERROR(( "T1.Hinter : fatal glyph loader bug - pass2-stem\n" ));
         return T1_Err_Syntax_Error;
       }
     }
@@ -709,16 +698,16 @@
 
 
   static
-  FT_Error  t1_hinter_stem3( T1_Builder*  builder,
-                             FT_Pos       pos0,
-                             FT_Int       width0,
-                             FT_Pos       pos1,
-                             FT_Int       width1,
-                             FT_Pos       pos2,
-                             FT_Int       width2,
-                             FT_Bool      vertical )
+  FT_Error   t1_hinter_stem3( T1_Builder*  builder,
+                              FT_Pos       pos0,
+                              FT_Int       width0,
+                              FT_Pos       pos1,
+                              FT_Int       width1,
+                              FT_Pos       pos2,
+                              FT_Int       width2,
+                              FT_Bool      vertical )
   {
-    /* For now, simply call `stem' 3 times */
+    /* 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 );
@@ -732,10 +721,9 @@
     T1_Stem_Table*   stem_table;
     T1_Glyph_Hints*  hinter = builder->glyph->hints;
 
-
-    /* If we are 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 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 );
 
@@ -747,7 +735,6 @@
       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;
 
@@ -762,40 +749,41 @@
   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
+    (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.          *********/
-  /**********                                                      *********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********************************************************************/
+  /**********                                                   *********/
+  /**********                                                   *********/
+  /**********              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
+ *
+ ************************************************************************/
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    t1_sort_hints                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sorta the list of active stems in increasing order, through the    */
-  /*    `sort' indexing table.                                             */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    table :: A stem hints table.                                       */
-  /*                                                                       */
   static
   void  t1_sort_hints( T1_Stem_Table*  table )
   {
@@ -805,7 +793,6 @@
     T1_Stem_Hint*  stems       = table->stems;
     FT_Int         n;
 
-
     /* record active stems in sort table */
     for ( n = 0; n < num_stems; n++ )
     {
@@ -813,33 +800,32 @@
         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).          */
+    /* 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++ )
     {
-      FT_Int         p   = n - 1;
-      T1_Stem_Hint*  cur = stems + sort[n];
+      FT_Int        p   = n-1;
+      T1_Stem_Hint* cur = stems + sort[n];
 
-
       do
       {
         FT_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 values also; this wouldn't change anything).          */
+        /* 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;
+        swap      = sort[ p ];
+        sort[ p ] = sort[p+1];
+        sort[p+1] = swap;
         p--;
-      } while ( p >= 0 );
+      }
+      while ( p >= 0 );
     }
 
     table->num_active = num_active;
@@ -846,32 +832,32 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    t1_hint_horizontal_stems                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes 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.                       */
-  /*                                                                       */
+/************************************************************************
+ *
+ * <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,
@@ -881,9 +867,8 @@
     T1_Stem_Hint*  stem      = table->stems;
     T1_Stem_Hint*  limit     = stem + table->num_stems;
 
-
     /* first of all, scale the blueShift */
-    blueShift = SCALE( blueShift );
+    blueShift = SCALE(blueShift);
 
     /* then scan the horizontal stem table */
     for ( ; stem < limit; stem++ )
@@ -899,28 +884,20 @@
       FT_Pos  top         = top_pix;
       FT_Int  align       = T1_ALIGN_NONE;
 
-
-      /*********************************************************************/
-      /*                                                                   */
-      /* Snap pixel width if in stem snap range                            */
-      /*                                                                   */
-
+      /******************************************************************/
+      /* 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;
-        FT_Pos         best_dist  = 32000;
-        T1_Snap_Zone*  best_zone  = 0;
+        FT_Pos         best_dist = 32000;
+        T1_Snap_Zone*  best_zone = 0;
 
-
         for ( ; zone < zone_limit; zone++ )
         {
           FT_Pos  dist;
 
-
-          dist = width_pix - zone->min;
-          if ( dist < 0 )
-            dist = -dist;
-          if ( dist < best_dist )
+          dist = width_pix - zone->min; if (dist < 0) dist = -dist;
+          if (dist < best_dist)
           {
             best_zone = zone;
             best_dist = dist;
@@ -927,43 +904,36 @@
           }
         }
 
-        if ( best_zone )
+        if (best_zone)
         {
-          if ( width_pix > best_zone->pix )
+          if (width_pix > best_zone->pix)
           {
             width_pix -= 0x20;
-            if ( width_pix < best_zone->pix )
+            if (width_pix < best_zone->pix)
               width_pix = best_zone->pix;
           }
           else
           {
             width_pix += 0x20;
-            if ( width_pix > best_zone->pix )
+            if (width_pix > best_zone->pix)
               width_pix = best_zone->pix;
           }
         }
       }
 
-      /*********************************************************************/
-      /*                                                                   */
-      /* round width - minimum 1 pixel if this isn't a ghost stem          */
-      /*                                                                   */
-
+      /******************************************************************/
+      /* 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 );
+        width_pix = ( width_pix < ONE_PIXEL ? ONE_PIXEL : ROUND(width_pix) );
 
 
-      /*********************************************************************/
-      /*                                                                   */
-      /* Now check for bottom blue zones alignement                        */
-      /*                                                                   */
-
+      /******************************************************************/
+      /* Now check for bottom blue zones alignement                     */
       {
         FT_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 )
@@ -974,13 +944,12 @@
             align  = T1_ALIGN_BOTTOM;
             bottom = ROUND( blue->pix );
 
-            /* implement blue shift */
-            if ( !hints->supress_overshoots )
+            /* implements blue shift */
+            if (!hints->supress_overshoots)
             {
               FT_Pos  delta = blue->pix - bottom_pix;
 
-
-              delta   = delta < blueShift ? 0 : ROUND( delta );
+              delta   = ( delta < blueShift ? 0 : ROUND( delta ) );
               bottom -= delta;
             }
           }
@@ -987,11 +956,9 @@
         }
       }
 
-      /*********************************************************************/
-      /*                                                                   */
-      /* check for top blue zones alignement                               */
-      /*                                                                   */
 
+      /******************************************************************/
+      /* Check for top blue zones alignement */
       {
         FT_Int         num_blues  = hints->num_blue_zones -
                                     hints->num_bottom_zones;
@@ -1001,7 +968,6 @@
 
         T1_Snap_Zone*  blue_limit = blue + num_blues;
 
-
         for ( ; blue < blue_limit; blue++ )
         {
           if ( top_pix < blue->min )
@@ -1009,16 +975,15 @@
 
           if ( top_pix <= blue->max )
           {
-            align |= T1_ALIGN_TOP;
-            top    = ROUND( blue->pix );
+            align  |= T1_ALIGN_TOP;
+            top     = ROUND( blue->pix );
 
-            /* implement blue shift */
-            if ( !hints->supress_overshoots )
+            /* implements blue shift */
+            if (!hints->supress_overshoots)
             {
               FT_Pos  delta = top - blue->pix;
 
-
-              delta  = delta < blueShift ? 0 : ROUND( delta );
+              delta  = ( delta < blueShift ? 0 : ROUND( delta ) );
               top   += delta;
             }
           }
@@ -1025,34 +990,34 @@
         }
       }
 
-      /*********************************************************************/
-      /*                                                                   */
-      /* compute the hinted stem position, according to its alignment      */
-      /*                                                                   */
 
-      switch ( align )
+      /******************************************************************/
+      /* compute the hinted stem position, according to its alignment   */
+      switch (align)
       {
-      case T1_ALIGN_BOTTOM:  /* bottom zone alignment */
-        bottom_pix = bottom;
-        top_pix    = bottom + width_pix;
-        break;
+        case T1_ALIGN_BOTTOM:  /* bottom zone alignement */
+          bottom_pix = bottom;
+          top_pix    = bottom + width_pix;
+          break;
 
-      case T1_ALIGN_TOP:  /* top zone alignment */
-        top_pix    = top;
-        bottom_pix = top - width_pix;
-        break;
+        case T1_ALIGN_TOP:  /* top zone alignement */
+          top_pix    = top;
+          bottom_pix = top - width_pix;
 
-      case T1_ALIGN_BOTH:  /* bottom+top zone alignment */
-        bottom_pix = bottom;
-        top_pix    = top;
-        break;
+          break;
 
-      default:  /* no alignment */
-        /* XXXX : TODO : Add management of controlled stems */
-        bottom = ( SCALE( bottom_orus + top_orus ) - width_pix ) / 2;
+        case T1_ALIGN_BOTH:  /* bottom+top zone alignement */
+          bottom_pix = bottom;
+          top_pix    = top;
+          break;
 
-        bottom_pix = ROUND( bottom );
-        top_pix    = bottom_pix + width_pix;
+        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;
@@ -1061,27 +1026,33 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    t1_hint_vertical_stems                                             */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes 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.                        */
-  /*                                                                       */
+
+
+/************************************************************************
+ *
+ * <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,
@@ -1090,7 +1061,6 @@
     T1_Stem_Hint*  stem  = table->stems;
     T1_Stem_Hint*  limit = stem + table->num_stems;
 
-
     for ( ; stem < limit; stem++ )
     {
       FT_Pos  stem_left  = stem->min_edge.orus;
@@ -1097,7 +1067,6 @@
       FT_Pos  stem_right = stem->max_edge.orus;
       FT_Pos  width_pix, left;
 
-
       width_pix = SCALE( stem_right - stem_left );
 
       /* Snap pixel width if in stem snap range */
@@ -1104,19 +1073,15 @@
       {
         T1_Snap_Zone*  zone       = hints->snap_heights;
         T1_Snap_Zone*  zone_limit = zone + hints->num_snap_heights;
-        FT_Pos         best_dist  = 32000;
-        T1_Snap_Zone*  best_zone  = 0;
+        FT_Pos         best_dist = 32000;
+        T1_Snap_Zone*  best_zone = 0;
 
-
         for ( ; zone < zone_limit; zone++ )
         {
           FT_Pos  dist;
 
-
-          dist = width_pix - zone->min;
-          if ( dist < 0 )
-            dist = -dist;
-          if ( dist < best_dist )
+          dist = width_pix - zone->min; if (dist < 0) dist = -dist;
+          if (dist < best_dist)
           {
             best_zone = zone;
             best_dist = dist;
@@ -1123,18 +1088,18 @@
           }
         }
 
-        if ( best_zone )
+        if (best_zone)
         {
-          if ( width_pix > best_zone->pix )
+          if (width_pix > best_zone->pix)
           {
             width_pix -= 0x20;
-            if ( width_pix < best_zone->pix )
+            if (width_pix < best_zone->pix)
               width_pix = best_zone->pix;
           }
           else
           {
             width_pix += 0x20;
-            if ( width_pix > best_zone->pix )
+            if (width_pix > best_zone->pix)
               width_pix = best_zone->pix;
           }
         }
@@ -1142,44 +1107,49 @@
 
       /* 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 );
+        width_pix = ( width_pix < ONE_PIXEL ? ONE_PIXEL :
+                                              ROUND( width_pix ) );
 
-      /* now place the snapped and rounded stem                   */
-      /* XXX TODO: implement controlled stems for the overlapping */
-      /*           cases.                                         */
+      /* now place the snapped and rounded stem   */
 
-      left = ( SCALE( stem_left + stem_right ) - width_pix ) / 2;
+      /* XXXX : TODO : implement controlled stems for the overlapping */
+      /*               cases..                                        */
 
-      stem->min_edge.pix = ROUND( left );
+      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 :: The 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.                        */
-  /*                                                                       */
+
+
+/************************************************************************
+ *
+ * <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
   FT_Pos  t1_hint_point( T1_Stem_Table*  table,
                          FT_Pos          coord,
@@ -1193,10 +1163,9 @@
     T1_Edge*       max;
     FT_Pos         delta;
 
-
     /* only hint when there is at least one stem defined */
-    if ( num_active <= 0 )
-      return SCALE( coord );
+    if (num_active <= 0)
+      return SCALE(coord);
 
     /* scan the stem table to determine placement of coordinate */
     /* relative to the list of sorted and stems                 */
@@ -1204,16 +1173,14 @@
     {
       cur = table->stems + table->sort[n];
 
-      /* is it on the left of the current edge? */
+      /* 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 ) return cur->min_edge.pix;
 
-      if ( delta > 0 )
+      if (delta > 0)
       {
         /* if this is the left of the first edge, simply shift */
-        if ( !prev )
-          return cur->min_edge.pix - SCALE( delta );
+        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 */
@@ -1222,12 +1189,11 @@
         goto Interpolate;
       }
 
-      /* is it within the current edge? */
+      /* is it within the current edge ? */
       delta = cur->max_edge.orus - coord;
-      if ( delta == 0 )
-        return cur->max_edge.pix;
+      if ( delta == 0 ) return cur->max_edge.pix;
 
-      if ( delta > 0 )
+      if (delta > 0)
       {
         /* interpolate within the stem */
         min = &cur->min_edge;
@@ -1238,40 +1204,43 @@
 
     /* apparently, this coordinate is on the right of the last stem */
     delta = coord - cur->max_edge.orus;
-    return cur->max_edge.pix + SCALE( delta );
+    return cur->max_edge.pix + SCALE(delta);
 
   Interpolate:
     return min->pix +
-             FT_MulDiv( coord     - min->orus,
-                        max->pix  - min->pix,
-                        max->orus - min->orus );
+            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 :: A handle to target Type 1 builder.                       */
-  /*                                                                       */
-  /*   first   :: The first point to hint in the builder's current         */
-  /*              outline.                                                 */
-  /*                                                                       */
-  /*   last    :: The last point to hint in the builder's current outline. */
-  /*                                                                       */
+/************************************************************************
+ *
+ * <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 )
   {
     FT_Int    first   = builder->hint_point;
-    FT_Int    last    = builder->current.n_points-1;
+    FT_Int    last    = builder->current->n_points-1;
 
     T1_Size   size    = builder->size;
     FT_Fixed  scale_x = size->root.metrics.x_scale;
@@ -1281,10 +1250,9 @@
     T1_Stem_Table*   hori_stems = &hints->hori_stems;
     T1_Stem_Table*   vert_stems = &hints->vert_stems;
 
-    FT_Vector*  cur   = builder->current.points + first;
+    FT_Vector*  cur   = builder->current->points + first;
     FT_Vector*  limit = cur + last - first + 1;
 
-
     /* first of all, sort the active stem hints */
     t1_sort_hints( hori_stems );
     t1_sort_hints( vert_stems );
@@ -1295,23 +1263,25 @@
       cur->y = t1_hint_point( hori_stems, cur->y, scale_y );
     }
 
-    builder->hint_point = builder->current.n_points;
+    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 :: A handle to the target 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_FUNC
   void  T1_Hint_Stems( T1_Builder*  builder )
   {
@@ -1322,7 +1292,6 @@
     FT_Fixed  scale_x = size->root.metrics.x_scale;
     FT_Fixed  scale_y = size->root.metrics.y_scale;
 
-
     t1_hint_horizontal_stems( &hints->hori_stems,
                               builder->size->hints,
                               priv->blue_shift,
@@ -1333,7 +1302,4 @@
                             scale_x );
   }
 
-#endif /* 1 */
-
-
-/* END */
+#endif
--- a/src/type1/t1objs.c
+++ b/src/type1/t1objs.c
@@ -259,15 +259,11 @@
     psnames = (PSNames_Interface*)face->psnames;
     if (!psnames)
     {
-      /* look-up the PSNames driver */
-      FT_Driver  psnames_driver;
-
-      psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" );
-      if (psnames_driver)
-        face->psnames = (PSNames_Interface*)
-                            (psnames_driver->interface.format_interface);
+      psnames = (PSNames_Interface*)
+                 FT_Get_Module_Interface( FT_FACE_LIBRARY(face), "psnames" );
     }
-
+    face->psnames = psnames;
+    
     /* open the tokenizer, this will also check the font format */
     error = New_Tokenizer( stream, &tokenizer );
     if (error) goto Fail;
@@ -458,16 +454,11 @@
   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 );
+#else
+    UNUSED(glyph)    
 #endif
-	/* the bitmaps are created on demand */
-	FREE( glyph->root.bitmap.buffer );
-    FT_Outline_Done( library, &glyph->root.outline );
-    return;
   }
 
 
@@ -487,66 +478,15 @@
   LOCAL_FUNC
   FT_Error  T1_Init_GlyphSlot( T1_GlyphSlot  glyph )
   {
-    FT_Library  library = glyph->root.face->driver->library;
-    FT_Error    error;
+    FT_Error    error = FT_Err_Ok;
 
-    glyph->max_points         = 0;
-    glyph->max_contours       = 0;
-    glyph->root.bitmap.buffer = 0;
-
-    error = FT_Outline_New( 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_Outline_Done( library, &glyph->root.outline );
+#else
+    UNUSED(glyph);    
 #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
-  FT_Error  T1_Init_Driver( T1_Driver  driver )
-  {
-    UNUSED(driver);
-    return T1_Err_Ok;
-  }
-
-
-
-/*******************************************************************
- *
- *  <Function> T1_Done_Driver
- *
- *  <Description>
- *     finalise a given Type 1 driver
- *
- *  <Input>
- *     driver  :: handle to target Type 1 driver
- *
- ******************************************************************/
-
-  LOCAL_DEF
-  void  T1_Done_Driver( T1_Driver  driver )
-  {
-    UNUSED(driver);
   }
 
 
--- a/src/type1/t1objs.h
+++ b/src/type1/t1objs.h
@@ -260,40 +260,6 @@
 
 
 
-/*******************************************************************
- *
- *  <Function>  T1_Init_Driver
- *
- *  <Description>
- *     Initialise a given Type 1 driver object
- *
- *  <Input>
- *     driver ::  handle to target driver object
- *
- *  <Return>
- *     Error code.
- *
- ******************************************************************/
-
-  LOCAL_DEF
-  FT_Error  T1_Init_Driver( T1_Driver  driver );
-
-
-
-/*******************************************************************
- *
- *  <Function> T1_Done_Driver
- *
- *  <Description>
- *     finalise a given Type 1 driver
- *
- *  <Input>
- *     driver  :: handle to target Type 1 driver
- *
- ******************************************************************/
-
-  LOCAL_DEF
-  void  T1_Done_Driver( T1_Driver  driver );
 
 #ifdef __cplusplus
   }
--- a/src/type1z/module.mk
+++ b/src/type1z/module.mk
@@ -1,7 +1,7 @@
 make_module_list: add_type1z_driver
 
 add_type1z_driver:
-	$(OPEN_DRIVER)t1z_driver_interface$(CLOSE_DRIVER)
+	$(OPEN_DRIVER)t1z_driver_class$(CLOSE_DRIVER)
 	$(ECHO_DRIVER)type1z    $(ECHO_DRIVER_DESC)Postscript font files with extension *.pfa or *.pfb$(ECHO_DRIVER_DONE)
 
 # EOF
--- a/src/type1z/t1driver.c
+++ b/src/type1z/t1driver.c
@@ -55,26 +55,21 @@
   /*    time).                                                             */
   /*                                                                       */
   static
-  FTDriver_Interface  Get_Interface( FT_Driver         driver,
-                                     const FT_String*  interface )
+  FT_Module_Interface  Get_Interface( FT_Driver         driver,
+                                      const FT_String*  interface )
   {
     UNUSED(driver);
     UNUSED(interface);
     
-#ifndef T1_CONFIG_OPTION_NO_AFM
-    if ( strcmp( (const char*)interface, "attach_file" ) == 0 )
-      return (FTDriver_Interface)T1_Read_AFM;
-#endif
-
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
     if ( strcmp( (const char*)interface, "get_mm" ) == 0 )
-      return (FTDriver_Interface)T1_Get_Multi_Master;
+      return (FT_Module_Interface)T1_Get_Multi_Master;
       
     if ( strcmp( (const char*)interface, "set_mm_design") == 0 )
-      return (FTDriver_Interface)T1_Set_MM_Design;      
+      return (FT_Module_Interface)T1_Set_MM_Design;      
 
     if ( strcmp( (const char*)interface, "set_mm_blend") == 0 )
-      return (FTDriver_Interface)T1_Set_MM_Blend;      
+      return (FT_Module_Interface)T1_Set_MM_Blend;      
 #endif
     return 0;
   }
@@ -132,76 +127,6 @@
   }
 #endif
 
-  /******************************************************************/
-  /*                                                                */
-  /* <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
-  FT_Error  Set_Char_Sizes( T1_Size      size,
-                            FT_F26Dot6   char_width,
-                            FT_F26Dot6   char_height,
-                            FT_UInt      horz_resolution,
-                            FT_UInt      vert_resolution )
-  {
-    UNUSED(char_width);
-    UNUSED(char_height);
-    UNUSED(horz_resolution);
-    UNUSED(vert_resolution);
-
-    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
-  FT_Error  Set_Pixel_Sizes( T1_Size     size,
-                             FT_Int      pixel_width,
-                             FT_Int      pixel_height )
-  {
-    UNUSED(pixel_width);
-    UNUSED(pixel_height);
-
-    size->valid = FALSE;
-    return T1_Reset_Size(size);
-  }
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -298,117 +223,48 @@
   }
 
 
-  /******************************************************************/
-  /*                                                                */
-  /* <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.                        */
-  /*                                                                */
-
-  const  FT_DriverInterface  t1z_driver_interface =
+  const  FT_Driver_Class  t1z_driver_class =
   {
-    sizeof( FT_DriverRec ),
+    {
+      ft_module_font_driver | ft_module_driver_scalable,
+      sizeof( FT_DriverRec ),
+      
+      "type1",
+      100,
+      200,
+  
+      0,   /* format interface */
+  
+      (FT_Module_Constructor)           T1_Init_Driver,
+      (FT_Module_Destructor)            T1_Done_Driver,
+      (FT_Module_Requester)             Get_Interface,
+    },
+
     sizeof( T1_FaceRec ),
     sizeof( T1_SizeRec ),
     sizeof( T1_GlyphSlotRec ),
 
-    "type1",
-    100,
-    200,
-
-    0,   /* format interface */
-
-    (FTDriver_initDriver)           T1_Init_Driver,
-    (FTDriver_doneDriver)           T1_Done_Driver,
-
-    (FTDriver_getInterface)         Get_Interface,
-
     (FTDriver_initFace)             T1_Init_Face,
     (FTDriver_doneFace)             T1_Done_Face,
+    (FTDriver_initSize)             0,
+    (FTDriver_doneSize)             0,
+    (FTDriver_initGlyphSlot)        0,
+    (FTDriver_doneGlyphSlot)        0,
 
+    (FTDriver_setCharSizes)         0,
+    (FTDriver_setPixelSizes)        0,
+    (FTDriver_loadGlyph)            T1_Load_Glyph,
+    (FTDriver_getCharIndex)         Get_Char_Index,
+
 #ifdef T1_CONFIG_OPTION_NO_AFM
     (FTDriver_getKerning)           0,
+    (FTDriver_attachFile)           0,
 #else
     (FTDriver_getKerning)           Get_Kerning,
+    (FTDriver_attachFile)           T1_Read_AFM,
 #endif
+    (FTDriver_getAdvances)          0
 
-    (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)         Get_Char_Index,
   };
 
 
@@ -434,9 +290,9 @@
 
 #ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
 
-  EXPORT_FUNC(FT_DriverInterface*)  getDriverInterface( void )
+  EXPORT_FUNC(const FT_Driver_Class*)  getDriverClass( void )
   {
-    return &t1z_driver_interface;
+    return &t1z_driver_class;
   }
 
 #endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
--- a/src/type1z/t1driver.h
+++ b/src/type1z/t1driver.h
@@ -18,10 +18,9 @@
 #ifndef T1DRIVER_H
 #define T1DRIVER_H
 
-#include <t1objs.h>
-#include <freetype/internal/t1errors.h>
+#include <freetype/internal/ftdriver.h>
 
-  FT_EXPORT_VAR(const  FT_DriverInterface)  t1z_driver_interface;
+  FT_EXPORT_VAR(const  FT_Driver_Class)  t1z_driver_class;
 
 #endif /* T1DRIVER_H */
 
--- a/src/type1z/t1gload.c
+++ b/src/type1z/t1gload.c
@@ -129,9 +129,13 @@
 
     if (glyph)
     {
-      builder->base         = glyph->root.outline;
-      builder->max_points   = glyph->max_points;
-      builder->max_contours = glyph->max_contours;
+      FT_GlyphLoader*  loader = glyph->root.loader;
+      
+      builder->loader = loader;
+      builder->current = &loader->current.outline;
+      builder->base    = &loader->base.outline;
+
+      FT_GlyphLoader_Rewind(loader);
     }
 
     if (size)
@@ -147,10 +151,6 @@
     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;
   }
 
 
@@ -175,11 +175,7 @@
     T1_GlyphSlot  glyph = builder->glyph;
 
     if (glyph)
-    {
-      glyph->root.outline = builder->base;
-      glyph->max_points   = builder->max_points;
-      glyph->max_contours = builder->max_contours;
-    }
+      glyph->root.outline = *builder->base;
   }
 
 
@@ -217,39 +213,7 @@
   FT_Error  check_points( T1_Builder*  builder,
                           FT_Int       count )
   {
-    FT_Outline*  base    = &builder->base;
-    FT_Outline*  outline = &builder->current;
-
-    if (!builder->load_points)
-      return T1_Err_Ok;
-
-    count += base->n_points + outline->n_points;
-
-    /* realloc points table if necessary */
-    if ( count >= builder->max_points )
-    {
-      FT_Error   error;
-      FT_Memory  memory    = builder->memory;
-      FT_Int     increment = outline->points - base->points;
-      FT_Int     current   = builder->max_points;
-
-      while ( builder->max_points < count )
-        builder->max_points += 8;
-
-      if ( REALLOC_ARRAY( base->points, current,
-                          builder->max_points, FT_Vector )  ||
-
-           REALLOC_ARRAY( base->tags, current,
-                          builder->max_points, FT_Byte )    )
-      {
-        builder->error = error;
-        return error;
-      }
-
-      outline->points = base->points + increment;
-      outline->tags  = base->tags  + increment;
-    }
-    return T1_Err_Ok;
+    return FT_GlyphLoader_Check_Points( builder->loader, count, 0 );
   }
 
 
@@ -260,7 +224,7 @@
                    FT_Pos       y,
                    FT_Byte      flag )
   {
-    FT_Outline*  outline = &builder->current;
+    FT_Outline*  outline = builder->current;
 
     if (builder->load_points)
     {
@@ -298,41 +262,25 @@
   static
   FT_Error  add_contour( T1_Builder*  builder )
   {
-    FT_Outline*  base    = &builder->base;
-    FT_Outline*  outline = &builder->current;
+    FT_Outline*  outline = builder->current;
+    FT_Error     error;
 
     if (!builder->load_points)
     {
       outline->n_contours++;
-      return T1_Err_Ok;
+      return FT_Err_Ok;
     }
 
     /* realloc contours array if necessary */
-    if ( base->n_contours + outline->n_contours >= builder->max_contours &&
-         builder->load_points )
+    error = FT_GlyphLoader_Check_Points( builder->loader, 0, 1 );
+    if (!error)
     {
-      FT_Error  error;
-      FT_Memory memory = builder->memory;
-      FT_Int    increment = outline->contours - base->contours;
-      FT_Int    current   = builder->max_contours;
-
-      builder->max_contours += 4;
-
-      if ( REALLOC_ARRAY( base->contours,
-                          current, builder->max_contours, FT_Short ) )
-      {
-        builder->error = error;
-        return error;
-      }
-
-      outline->contours = base->contours + increment;
+      if (outline->n_contours > 0)
+        outline->contours[ outline->n_contours-1 ] = outline->n_points-1;
+        
+      outline->n_contours++;
     }
-
-    if (outline->n_contours > 0)
-      outline->contours[ outline->n_contours-1 ] = outline->n_points-1;
-
-    outline->n_contours++;
-    return T1_Err_Ok;
+    return error;
   }
 
   /* if a path was begun, add its first on-curve point */
@@ -358,7 +306,7 @@
   static
   void  close_contour( T1_Builder*  builder )
   {
-    FT_Outline*  outline = &builder->current;
+    FT_Outline*  outline = builder->current;
 
     if ( outline->n_contours > 0 )
       outline->contours[outline->n_contours-1] = outline->n_points-1;
@@ -442,61 +390,37 @@
                              FT_Int       achar )
   {
     FT_Error     error;
-    T1_Face      face = decoder->builder.face;
     FT_Int       bchar_index, achar_index, n_base_points;
-    FT_Outline*  cur  = &decoder->builder.current;
-    FT_Outline*  base = &decoder->builder.base;
+    FT_Outline*  cur  = decoder->builder.current;
+    FT_Outline*  base = decoder->builder.base;
     FT_Vector    left_bearing, advance;
+    T1_Face      face  = decoder->builder.face;
     T1_Font*     type1 = &face->type1;
 
     bchar_index = lookup_glyph_by_stdcharcode( face, bchar );
     achar_index = lookup_glyph_by_stdcharcode( face, achar );
 
-    if (bchar_index < 0 || achar_index < 0)
+    if ( bchar_index < 0 || achar_index < 0 )
     {
-      FT_ERROR(( "T1.Parse_Seac : invalid seac character code arguments\n" ));
+      FT_ERROR(( "t1operator_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->tags      = base->tags    + base->n_points;
-    cur->contours   = base->contours + base->n_contours;
-
-    error = T1_Parse_CharStrings( decoder,
-                                  type1->charstrings    [bchar_index],
-                                  type1->charstrings_len[bchar_index],
-                                  type1->num_subrs,
-                                  type1->subrs,
-                                  type1->subrs_len );
-    if (error) return error;
-
-    n_base_points   = cur->n_points;
-
+    /* if we are trying to load a composite glyph, do not load the */
+    /* accent character and return the array of subglyphs.         */
     if ( decoder->builder.no_recurse )
     {
-      /* if we're trying to load a composite glyph, do not load the */
-      /* accent character and return the array of subglyphs..       */
-      FT_GlyphSlot  glyph = (FT_GlyphSlot)decoder->builder.glyph;
-      FT_SubGlyph*  subg;
 
+      FT_GlyphSlot     glyph = (FT_GlyphSlot)decoder->builder.glyph;
+      FT_GlyphLoader*  loader = glyph->loader;
+      FT_SubGlyph*     subg;
+
       /* reallocate subglyph array if necessary */
-      if (glyph->max_subglyphs < 2)
-      {
-        FT_Memory  memory = decoder->builder.face->root.memory;
+      error = FT_GlyphLoader_Check_Subglyphs( loader, 2 );
+      if (error) goto Exit;
+      
+      subg = loader->current.subglyphs;
 
-        if ( REALLOC_ARRAY( glyph->subglyphs, glyph->max_subglyphs,
-                            2, FT_SubGlyph ) )
-          return error;
-
-        glyph->max_subglyphs = 2;
-      }
-
-      subg = glyph->subglyphs;
-
       /* subglyph 0 = base character */
       subg->index = bchar_index;
       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
@@ -514,11 +438,29 @@
       /* set up remaining glyph fields */
       glyph->num_subglyphs = 2;
       glyph->format        = ft_glyph_format_composite;
+      
+      loader->current.num_subglyphs = 2;
     }
-    else
+
+    /* First load `bchar' in builder */
+    /* now load the unscaled outline */
+    
+    FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
+
+    error = T1_Parse_CharStrings( decoder,
+                                  type1->charstrings    [bchar_index],
+                                  type1->charstrings_len[bchar_index],
+                                  type1->num_subrs,
+                                  type1->subrs,
+                                  type1->subrs_len );
+    if ( error ) goto Exit;
+
+    n_base_points = cur->n_points;
+
     {
       /* save the left bearing and width of the base character */
-      /* as they will be erase by the next load..              */
+      /* as they will be erased by the next load.              */
+
       left_bearing = decoder->builder.left_bearing;
       advance      = decoder->builder.advance;
 
@@ -525,15 +467,8 @@
       decoder->builder.left_bearing.x = 0;
       decoder->builder.left_bearing.y = 0;
 
-      /* Now load "achar" on top of */
+      /* 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->tags      = base->tags    + base->n_points;
-      cur->contours   = base->contours + base->n_contours;
-
       error = T1_Parse_CharStrings( decoder,
                                     type1->charstrings    [achar_index],
                                     type1->charstrings_len[achar_index],
@@ -540,27 +475,26 @@
                                     type1->num_subrs,
                                     type1->subrs,
                                     type1->subrs_len );
-      if (error) return error;
+      if ( error ) return error;
 
-      /* adjust contours in accented character outline */
-      if (decoder->builder.load_points)
-      {
-        FT_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 */
-      if (decoder->builder.load_points)
-        FT_Outline_Translate( cur, adx - asb, ady );
+      if ( decoder->builder.load_points )
+      {
+        FT_Outline  dummy;
+        
+        dummy.n_points = base->n_points - n_base_points;
+        dummy.points   = base->points   + n_base_points;
+        FT_Outline_Translate( &dummy, adx - asb, ady );
+      }
     }
-    return T1_Err_Ok;
+  Exit:
+    return error;
   }
 
 
@@ -615,7 +549,7 @@
     ip    = zone->cursor = zone->base;
 
     error   = T1_Err_Ok;
-    outline = &builder->current;
+    outline = builder->current;
 
     x = builder->pos_x;
     y = builder->pos_y;
@@ -922,8 +856,7 @@
             close_contour( builder );
 
             /* add current outline to the glyph slot */
-            builder->base.n_points   += builder->current.n_points;
-            builder->base.n_contours += builder->current.n_contours;
+            FT_GlyphLoader_Add( builder->loader );
 
             /* return now !! */
             FT_TRACE4(( "\n\n" ));
@@ -1397,7 +1330,7 @@
         {
           /* scale the outline and the metrics */
           FT_Int       n;
-          FT_Outline*  cur = &decoder.builder.base;
+          FT_Outline*  cur = decoder.builder.base;
           FT_Vector*   vec = cur->points;
           FT_Fixed     x_scale = glyph->x_scale;
           FT_Fixed     y_scale = glyph->y_scale;
--- a/src/type1z/t1gload.h
+++ b/src/type1z/t1gload.h
@@ -83,34 +83,32 @@
 
   typedef struct T1_Builder_
   {
-    FT_Memory     memory;
-    T1_Face       face;
-    T1_GlyphSlot  glyph;
+    FT_Memory        memory;
+    T1_Face          face;
+    T1_GlyphSlot     glyph;
+    FT_GlyphLoader*  loader;
 
-    FT_Outline    current;       /* the current glyph outline   */
-    FT_Outline    base;          /* the composite glyph outline */
+    FT_Outline*      current;       /* the current glyph outline   */
+    FT_Outline*      base;          /* the composite glyph outline */
 
-    FT_Int        max_points;    /* capacity of base outline in points   */
-    FT_Int        max_contours;  /* capacity of base outline in contours */
+    FT_Vector        last;
 
-    FT_Vector     last;
+    FT_Fixed         scale_x;
+    FT_Fixed         scale_y;
 
-    FT_Fixed      scale_x;
-    FT_Fixed      scale_y;
+    FT_Pos           pos_x;
+    FT_Pos           pos_y;
 
-    FT_Pos        pos_x;
-    FT_Pos        pos_y;
+    FT_Vector        left_bearing;
+    FT_Vector        advance;
 
-    FT_Vector     left_bearing;
-    FT_Vector     advance;
+    FT_BBox          bbox;          /* bounding box */
+    FT_Bool          path_begun;
+    FT_Bool          load_points;
+    FT_Bool          no_recurse;
 
-    FT_BBox       bbox;          /* bounding box */
-    FT_Bool       path_begun;
-    FT_Bool       load_points;
-    FT_Bool       no_recurse;
-
-    FT_Error      error;         /* only used for memory errors */
-    FT_Bool       metrics_only;
+    FT_Error         error;         /* only used for memory errors */
+    FT_Bool          metrics_only;
 
   } T1_Builder;
 
--- a/src/type1z/t1objs.c
+++ b/src/type1z/t1objs.c
@@ -29,103 +29,6 @@
 
 /*******************************************************************
  *                                                                 *
- *                         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 )
-  {
-    UNUSED(size);
-  }
-
-
-/*******************************************************************
- *
- *  <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
-  FT_Error  T1_Init_Size( T1_Size  size )
-  {
-    size->valid = 0;
-    return T1_Err_Ok;
-  }
-
-
-/*******************************************************************
- *
- *  <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
-  FT_Error  T1_Reset_Size( T1_Size  size )
-  {
-    /* recompute ascender, descender, etc.. */
-    T1_Face           face    = (T1_Face)size->root.face;
-    FT_Size_Metrics*  metrics = &size->root.metrics;
-
-    if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
-      return T1_Err_Invalid_Argument;
-
-    /* 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;
-    return 0;
-  }
-
-
-/*******************************************************************
- *                                                                 *
  *                         FACE  FUNCTIONS                         *
  *                                                                 *
  *                                                                 *
@@ -238,16 +141,9 @@
 
     psnames = (PSNames_Interface*)face->psnames;
     if (!psnames)
-    {
-      /* look-up the PSNames driver */
-      FT_Driver  psnames_driver;
+      psnames = (PSNames_Interface*)
+                 FT_Get_Module_Interface( FT_FACE_LIBRARY(face), "psnames" );
 
-      psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" );
-      if (psnames_driver)
-        face->psnames = (PSNames_Interface*)
-                            (psnames_driver->interface.format_interface);
-    }
-
     /* open the tokenizer, this will also check the font format */
     error = T1_Open_Face( face );
     if (error) goto Exit;
@@ -412,57 +308,6 @@
     }
   Exit:
     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;
-
-	/* the bitmaps are created on demand */
-	FREE( glyph->root.bitmap.buffer );
-    FT_Outline_Done( 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
-  FT_Error  T1_Init_GlyphSlot( T1_GlyphSlot  glyph )
-  {
-    FT_Library  library = glyph->root.face->driver->library;
-
-    glyph->max_points         = 0;
-    glyph->max_contours       = 0;
-    glyph->root.bitmap.buffer = 0;
-
-    return FT_Outline_New( library, 0, 0, &glyph->root.outline );
   }
 
 
--- a/src/type1z/t1objs.h
+++ b/src/type1z/t1objs.h
@@ -170,95 +170,6 @@
   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
-  FT_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
-  FT_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
-  FT_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