shithub: freetype+ttf2subf

Download patch

ref: 414f38c572e34bcd92d93cd0b1813de8572dd1c9
parent: 33aab6e5b6c14d3cf2c4334f79a8debf959c9e38
author: David Turner <[email protected]>
date: Tue May 16 18:37:30 EDT 2000

at last, fixed the bug, and re-enabled 5-gray levels support
for backwards compatibility..

git/fs: mount .git/fs: mount/attach disallowed
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -140,17 +140,35 @@
 
   /*************************************************************************/
   /*                                                                       */
+  /* DLL Export Compilation                                                */
+  /*                                                                       */
   /* When compiling FreeType as a DLL, some systems/compilers need a       */
-  /* special keyword in front of each function definition instead of       */
-  /* `extern'.                                                             */
+  /* special keyword in front OR after the return type of function         */
+  /* declarations.                                                         */
   /*                                                                       */
-  /* The macros EXPORT_DEF and EXPORT_FUNC are thus used to define         */
-  /* exported library function interfaces and exported library functions   */
-  /* implementations respectively.                                         */
+  /* Two macros are used within the FreeType source code to define         */
+  /* exported library functions: EXPORT_DEF and EXPORT_FUNC                */
   /*                                                                       */
-  /* If not defined here, they automatically default to `extern' and void  */
-  /* later in this header file.                                            */
+  /* EXPORT_DEF(return_type) is used in a function declaration, as in:     */
   /*                                                                       */
+  /*   EXPORT_DEF(FT_Error)  FT_Init_FreeType( FT_Library *alibrary );     */
+  /*                                                                       */
+  /*                                                                       */
+  /*                                                                       */
+  /* EXPORT_FUNC(return_type) is used in a function definition, as in:     */
+  /*                                                                       */
+  /*   EXPORT_FUNC(FT_Error)  FT_Init_FreeType( FT_Library *alibrary )     */
+  /*   {                                                                   */
+  /*     ... some code ...                                                 */
+  /*     return FT_Err_Ok;                                                 */
+  /*   }                                                                   */
+  /*                                                                       */
+  /*                                                                       */
+  /* You can provide your own implementation of EXPORT_DEF and EXPORT_FUNC */
+  /* here if you want. If you leave them undefined, they'll later be       */
+  /* automatically defined as "extern return_type" to allow normal         */
+  /* compilation..                                                         */
+  /*                                                                       */
 #undef EXPORT_DEF
 #undef EXPORT_FUNC
 
@@ -157,6 +175,25 @@
 
   /*************************************************************************/
   /*                                                                       */
+  /* 5-levels Anti Aliasing support:                                       */
+  /*                                                                       */
+  /*  FreeType 2 provides a new "smooth" renderer that is capable of       */
+  /*  producing anti-aliased glyph bitmaps with up to 256 gray-levels.     */
+  /*                                                                       */
+  /*  However, for compatibility purposes with FreeType 1.x, the standard  */
+  /*  raster is still capable of generating anti-aliased bitmaps with 5    */
+  /*  gray levels.                                                         */
+  /*                                                                       */
+  /*  If you do not need this capability (i.e. if you always use the       */
+  /*  "smooth" renderer for anti-aliased glyphs), we suggest you to        */
+  /*  undefine this configuration macro, as it will save both code and     */
+  /*  memory..                                                             */
+  /*                                                                       */
+#define FT_CONFIG_OPTION_5_GRAY_LEVELS
+
+
+  /*************************************************************************/
+  /*                                                                       */
   /* Debug level                                                           */
   /*                                                                       */
   /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
@@ -175,17 +212,6 @@
 
   /*************************************************************************/
   /*                                                                       */
-  /* Anti-aliasing support                                                 */
-  /*                                                                       */
-  /*   Undefine this macro only if you want to disable the anti-aliasing   */
-  /*   support in FreeType.  This will save you about 5 Kb of code.  It    */
-  /*   may be important for some embedded systems.                         */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_ANTI_ALIAS
-
-
-  /*************************************************************************/
-  /*                                                                       */
   /* Endianess performance improvement                                     */
   /*                                                                       */
   /*   FreeType is completely endian-independent, and can thus be compiled */
@@ -211,6 +237,7 @@
   /*   soon..                                                              */
   /*                                                                       */
 #define FT_CONFIG_OPTION_OLD_CALCS
+
 
   /*************************************************************************/
   /*                                                                       */
--- a/src/base/ftraster.c
+++ b/src/base/ftraster.c
@@ -1,235 +1,160 @@
-/***************************************************************************/
-/*                                                                         */
-/*  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.                                        */
-/*                                                                         */
-/***************************************************************************/
+/*******************************************************************
+ *
+ *  ftraster.c                                                  1.5
+ *
+ *  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
+ *
+ *
+ *
+ ******************************************************************/
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The `raster' component implements FreeType's scan-line converter, the */
-  /* one used to generate bitmaps and pixmaps from vectorial outline       */
-  /* descriptions.                                                         */
-  /*                                                                       */
-  /* It has been rewritten entirely for FreeType 2.0, in order to become   */
-  /* completely independent of the rest of the library.  It should now be  */
-  /* possible to include it more easily in all kinds of libraries and      */
-  /* applications, which do not necessarily need the font engines and API. */
-  /*                                                                       */
-  /* This version contains the following features:                         */
-  /*                                                                       */
-  /* - Support for third-order Bezier arcs.                                */
-  /*                                                                       */
-  /* - Improved performance of the 5-levels anti-aliasing algorithm.       */
-  /*                                                                       */
-  /* - 17-levels anti-aliasing for smoother curves, though the difference  */
-  /*   isn't always noticeable, depending on your palette.                 */
-  /*                                                                       */
-  /* - An API to decompose a raster outline into a path (i.e., into a      */
-  /*   a series of segments and arcs).                                     */
-  /*                                                                       */
-  /* Planned additions:                                                    */
-  /*                                                                       */
-  /* - Getting rid of the second pass for horizontal drop-out detection.   */
-  /*   I've got a few ideas, but I'll have to experiment in Pascal with    */
-  /*   them.  to avoid damaging of the rendering of glyphs at small sizes. */
-  /*                                                                       */
-  /* - Adding a `composition' callback, which should be invoked during     */
-  /*   anti-aliased rendering.  In short, it will allow line-by-line       */
-  /*   composition (i.e., transparencies, etc.) of the output in a fairly  */
-  /*   portable way.  Of course, a single sweep is required there.         */
-  /*                                                                       */
-  /*************************************************************************/
-
-#define OLD
-
-
-#define xxxDEBUG_RAS
-#ifdef DEBUG_RAS
-#include <stdio.h>
-#endif
-
-
 #include <freetype/ftraster.h>
-#ifndef _STANDALONE_
-#include <freetype/internal/ftdebug.h>
-#endif
+#include <freetype/internal/ftcalc.h>      /* for FT_MulDiv only */
 
-#ifndef UNUSED
-#define UNUSED( arg )  ( (arg)=(arg) )
-#endif
-
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_raster
-
-#ifdef _STANDALONE_
-
   /*************************************************************************/
   /*                                                                       */
-  /* The following defines are used when the raster is compiled as a       */
-  /* stand-alone object.  Each of them is commented, and you're free to    */
-  /* toggle them to suit your needs.                                       */
+  /* A simple technical note on how the raster works:                      */
   /*                                                                       */
-  /*************************************************************************/
-
-  /*************************************************************************/
+  /*   Converting an outline into a bitmap is achieved in several steps    */
+  /*   which are:                                                          */
   /*                                                                       */
-  /* FT_RASTER_INT_IS_32                                                   */
+  /*   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                     */
   /*                                                                       */
-  /*   Set this configuration macro to the unsigned type which has 32      */
-  /*   bits.                                                               */
+  /*       o its scanline position boundaries, i.e. `Ymin' and `Ymax'.     */
   /*                                                                       */
-#define FT_RASTER_INT_IS_32
-
-
-  /*************************************************************************/
+  /*       o an array of intersection coordinates for each scanline        */
+  /*         between `Ymin' and `Ymax'.                                    */
   /*                                                                       */
-  /* FT_RASTER_OPTION_ANTI_ALIAS                                           */
+  /*       o a direction, indicating wether is was built going `up' or     */
+  /*         `down', as this is very important for filling rules.          */
   /*                                                                       */
-  /*   Define this configuration macro if you want to support              */
-  /*   anti-aliasing.                                                      */
+  /*   2 - Sweeping the target map's scanlines in order to compute segment */
+  /*       `spans' which are then filled.  Additionaly, this pass performs */
+  /*       drop-out control.                                               */
   /*                                                                       */
-#undef  FT_RASTER_OPTION_ANTI_ALIAS
-
-
-  /*************************************************************************/
+  /*   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:       */
   /*                                                                       */
-  /* FT_RASTER_OPTION_CONIC_BEZIERS                                        */
+  /*     ____________________________________________________________ _ _  */
+  /*    |         |                   |         |                 |        */
+  /*    | profile | coordinates for   | profile | coordinates for |-->     */
+  /*    |    1    |  profile 1        |    2    |  profile 2      |-->     */
+  /*    |_________|___________________|_________|_________________|__ _ _  */
   /*                                                                       */
-  /*   Define this configuration macro if your source outlines contain     */
-  /*   second-order Bezier arcs.  Typically, these are TrueType outlines.  */
+  /*    ^                                                         ^        */
+  /*    |                                                         |        */
+  /*    start of render pool                                   top         */
   /*                                                                       */
-#define FT_RASTER_CONIC_BEZIERS
-
-
-  /*************************************************************************/
+  /*   The top of the profile stack is kept in the `top' variable.         */
   /*                                                                       */
-  /* FT_RASTER_OPTION_CUBIC_BEZIERS                                        */
+  /*   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.                             */
   /*                                                                       */
-  /*   Define this configuration macro if your source outlines contain     */
-  /*   third-order Bezier arcs.  Typically, these are Type1 outlines.      */
+  /*   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:         */
   /*                                                                       */
-#define FT_RASTER_CUBIC_BEZIERS
-
-
-  /*************************************************************************/
+  /*      _ _ _______________________________________                      */
+  /*                            |                    |                     */
+  /*                         <--| sorted list of     |                     */
+  /*                         <--|  extrema scanlines |                     */
+  /*      _ _ __________________|____________________|                     */
   /*                                                                       */
-  /* FT_RASTER_CONSTANT_PRECISION                                          */
+  /*                            ^                    ^                     */
+  /*                            |                    |                     */
+  /*                       maxBuff             sizeBuff = end of pool      */
   /*                                                                       */
-  /*   Define this configuration macro if you want to use a constant       */
-  /*   precision for the internal sub-pixel coordinates. Otherwise, the    */
-  /*   precision is either 64 or 1024 units per pixel, depending on the    */
-  /*   outline's "high_precision" flag..                                   */
+  /*   This list is later used during the sweep phase in order to          */
+  /*   optimize performance (see technical note on the sweep below).       */
   /*                                                                       */
-  /*   This results in a speed boost, but the macro can be undefined if    */
-  /*   it results in rendering errors (mainly changed drop-outs)..         */
+  /*   Of course, the raster detects whether the two stacks collide and    */
+  /*   handles the situation propertly.                                    */
   /*                                                                       */
-#undef  FT_RASTER_CONSTANT_PRECISION
-
-
   /*************************************************************************/
-  /*                                                                       */
-  /* FT_PRECISION_BITS                                                     */
-  /*                                                                       */
-  /*   When the macro FT_RASTER_CONSTANT_PRECISION is defined, this        */
-  /*   constant holds the number of bits used for the internal sub-pixels  */
-  /*                                                                       */
-  /*   This number should be at least 6, but use at least 8 if you         */
-  /*   intend to generate small glyph images (use 6 for a printer, for     */
-  /*   example..)                                                          */
-  /*                                                                       */
-#define FT_PRECISION_BITS 8
 
+  /****************************************************************/
+  /****************************************************************/
+  /**                                                            **/
+  /**  CONFIGURATION MACROS                                      **/
+  /**                                                            **/
+  /****************************************************************/
+  /****************************************************************/
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* FT_DYNAMIC_BEZIER_STEPS                                               */
-  /*                                                                       */
-  /*   Set this macro to enable the bezier decomposition to be             */
-  /*   dynamically computed. This is interesting when the precision is     */
-  /*   constant, as it speeds things a bit while keeping a very good       */
-  /*   accuracy on the bezier intersections..                              */
-  /*                                                                       */
-#undef  FT_DYNAMIC_BEZIER_STEPS
+/* 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
 
-#else /* _STANDALONE_ */
-
-#include <freetype/freetype.h>
-#include <freetype/config/ftconfig.h>
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The following defines are used when the raster is compiled within the */
-  /* FreeType base layer.  Don't change these unless you really know what  */
-  /* you're doing.                                                         */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#ifdef FT_CONFIG_OPTION_ANTI_ALIAS
-#define FT_RASTER_OPTION_ANTI_ALIAS
+/* 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
 
-#define FT_RASTER_CONIC_BEZIERS
-#define FT_RASTER_CUBIC_BEZIERS
+/* The size of the two-lines intermediate bitmap used */
+/* for anti-aliasing, in bytes..                      */
+#define  RASTER_GRAY_LINES    2048
 
-#define FT_RASTER_ANTI_ALIAS_5
-/* #define  FT_RASTER_ANTI_ALIAS_17 */
 
-#ifdef FT_CONFIG_OPTION_LITTLE_ENDIAN
-#define FT_RASTER_LITTLE_ENDIAN
-#endif
+  /****************************************************************/
+  /****************************************************************/
+  /**                                                            **/
+  /**  OTHER MACROS (do not change)                              **/
+  /**                                                            **/
+  /****************************************************************/
+  /****************************************************************/
 
-#ifdef FT_CONFIG_OPTION_BIG_ENDIAN
-#define FT_RASTER_BIG_ENDIAN
-#endif
+/* required by the tracing mode */
+#undef  FT_COMPONENT
+#define FT_COMPONENT      trace_raster
 
-#undef  FT_RASTER_CONSTANT_PRECISION
-#undef  FT_DYNAMIC_BEZIER_STEPS
-#define FT_PRECISION_BITS    8
+#include <freetype/internal/ftdebug.h>
 
-#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 in 32 bits.      */
+#define FMulDiv( a, b, c )  ( (a) * (b) / (c) )
 
-/* to keep the compiler happy */
-#ifndef FT_TRACE2
-#define FT_TRACE2(x)  /*void*/
-#endif
+/* On the other hand, SMulDiv is for "Slow MulDiv", and is used typically */
+/* for clipping computations.  It simply uses the FT_MulDiv() function    */
+/* defined in "ftcalc.h"                                                  */
+/*                                                                        */
+#define SMulDiv   FT_MulDiv
 
-#ifndef FT_TRACE4
-#define FT_TRACE4(x)  /* void */
-#endif
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* FT_RASTER_ANY_ENDIAN indicates that no endianess was defined by one   */
-  /* of the configuration macros.                                          */
-  /*                                                                       */
-#if !defined( FT_RASTER_LITTLE_ENDIAN ) && !defined( FT_RASTER_BIG_ENDIAN )
-#define FT_RASTER_ANY_ENDIAN
-#endif
 
+/* The rasterizer is a very general purpose component, please leave */
+/* the following redefinitions there (you never know your target    */
+/* environment).                                                    */
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* The rasterizer is a very general purpose component.  Please leave the */
-  /* following redefinitions here (you never know your target              */
-  /* environment).                                                         */
-  /*                                                                       */
-  /*************************************************************************/
-
 #ifndef TRUE
 #define TRUE   1
 #endif
@@ -242,192 +167,84 @@
 #define NULL  (void*)0
 #endif
 
-
-#ifndef UNUSED
-#define UNUSED( arg )  ( (void)(arg) )
+#ifndef SUCCESS
+#define SUCCESS 0
 #endif
 
-
-#undef  FAILURE
-#define FAILURE  TRUE
-
-#undef  SUCCESS
-#define SUCCESS  FALSE
-
-#ifndef ABS
-#define ABS(x)  ( (x) < 0 ? -(x) : (x) )
+#ifndef FAILURE
+#define FAILURE 1
 #endif
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Please don't touch the following macros. Their importance is          */
-  /* historical to FreeType, but they have some nice effects, like getting */
-  /* rid of all `->' symbols when accessing the raster object (replacing   */
-  /* them with a simple `.').                                              */
-  /*                                                                       */
-  /*************************************************************************/
 
-  /* used in function signatures to define the _first_ argument */
-#define RAS_ARG_  FT_Raster  raster,
-#define RAS_ARG   FT_Raster  raster
+#define MaxBezier  32   /* The maximum number of stacked Bezier curves. */
+                        /* Setting this constant to more than 32 is a   */
+                        /* pure waste of space.                         */
 
-  /* used to call a function within this component, first parameter */
-#define RAS_VAR_  raster,
-#define RAS_VAR   raster
+#define Pixel_Bits  6   /* fractional bits of *input* coordinates */
 
-  /* used to access the current raster object, with a `.' instead of a */
-  /* `->'                                                              */
-#define ras       (*raster)
+  /****************************************************************/
+  /****************************************************************/
+  /**                                                            **/
+  /**  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;
 
-#define           UNUSED_RASTER   (raster=raster);
+  typedef struct TPoint_
+  {
+    Long  x;
+    Long  y;
+    
+  } TPoint;
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Error codes returned by the scan-line converter/raster.               */
-  /*                                                                       */
-#define ErrRaster_Ok                     0
-#define ErrRaster_Uninitialized_Object   1
-#define ErrRaster_Overflow               2
-#define ErrRaster_Negative_Height        3
-#define ErrRaster_Invalid_Outline        4
-#define ErrRaster_Invalid_Map            5
-#define ErrRaster_AntiAlias_Unsupported  6
-#define ErrRaster_Invalid_Pool           7
-#define ErrRaster_Unimplemented          8
-#define ErrRaster_Bad_Palette_Count      9
 
+  typedef enum TFlow_
+  {
+    Flow_None = 0,
+    Flow_Up   = 1,
+    Flow_Down = -1
+  
+  } TFlow;
 
-#define Flow_Up     1
-#define Flow_Down  -1
 
-#define SET_High_Precision( p )  Set_High_Precision( RAS_VAR_  p )
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Fast MulDiv, as `b' is always < 64.  Don't use intermediate           */
-  /* precision.                                                            */
-  /*                                                                       */
-#define FMulDiv( a, b, c )  ( (a) * (b) / (c) )
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define DEBUG_RASTER if you want to generate a debug version of the    */
-  /* rasterizer.  This will progressively draw the glyphs while all the    */
-  /* computation are done directly on the graphics screen (the glyphs will */
-  /* will be shown inverted).                                              */
-  /*                                                                       */
-  /* Note that DEBUG_RASTER should only be used for debugging with b/w     */
-  /* rendering, not with gray levels.                                      */
-  /*                                                                       */
-  /* The definition of DEBUG_RASTER should appear in the file              */
-  /* `ftconfig.h'.                                                         */
-  /*                                                                       */
-#ifdef DEBUG_RASTER
-  extern char*  vio;  /* A pointer to VRAM or display buffer */
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The maximum number of stacked Bezier curves.  Setting this constant   */
-  /* to more than 32 is a pure waste of space.                             */
-  /*                                                                       */
-#define MaxBezier  32
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The number fractional bits of *input* coordinates.  We always use the */
-  /* 26.6 format (i.e, 6 bits for the fractional part), but hackers are    */
-  /* free to experiment with different values.                             */
-  /*                                                                       */
-#define INPUT_BITS  6
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* An unsigned type that is exactly 32 bits on your platform.  This      */
-  /* means `unsigned long' on 16-bit machines, and `unsigned int' on       */
-  /* others.                                                               */
-  /*                                                                       */
-#ifdef _STANDALONE_
-#if defined( FT_RASTER_INT_IS_32 )
-  typedef unsigned int   FT_Word32;
-#elif defined( FT_RASTER_LONG_IS_32 )
-  typedef unsigned long  FT_Word32;
-#else
-#error "no 32bit type found - please check your configuration"
-#endif
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* A pointer to an unsigned char.                                        */
-  /*                                                                       */
-  typedef unsigned char Byte, *PByte;
-  typedef int           TResult;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The type of the pixel coordinates used within the render pool during  */
-  /* scan-line conversion.  We use longs to store either 26.6 or 22.10     */
-  /* fixed float values, depending on the `precision' we want to use       */
-  /* (i.e., low resp. high precision).  These are ideals in order to       */
-  /* subdivise Bezier arcs in halves by simple additions and shifts.       */
-  /*                                                                       */
-  /* Note that this is an 8-bytes integer on 64 bits systems.              */
-  /*                                                                       */
-  typedef long  TPos, *PPos;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The type of a scanline position/coordinate within a map.              */
-  /*                                                                       */
-  typedef int  TScan, *PScan;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* States and directions of each line, arc, and profile.                 */
-  /*                                                                       */
-  typedef enum  _TDirection
+  /* States of each line, arc and profile */
+  typedef enum  TStates_
   {
     Unknown,
     Ascending,
     Descending,
     Flat
+    
+  } TStates;
 
-  } TDirection;
 
-
-  struct  _TProfile;
-  typedef struct _TProfile  TProfile;
+  typedef struct TProfile_  TProfile;
   typedef TProfile*         PProfile;
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The `master' structure used for decomposing outlines.                 */
-  /*                                                                       */
-  struct  _TProfile
+  struct  TProfile_
   {
-    TPos      X;           /* current coordinate during sweep          */
-    PProfile  link;        /* link to next profile - various purpose   */
-    PPos      offset;      /* start of profile's data in render pool   */
-    int       flow;        /* Profile orientation: Asc/Descending      */
-    TScan     height;      /* profile's height in scanlines            */
-    TScan     start;       /* profile's starting scanline              */
+    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              */
 
-    TScan     countL;      /* number of lines to step before this      */
-                           /* profile becomes drawable                 */
+    UShort      countL;      /* number of lines to step before this      */
+                             /* profile becomes drawable                 */
 
-    PProfile  next;        /* next profile in same contour, used       */
-                           /* during drop-out control                  */
+    PProfile    next;        /* next profile in same contour, used       */
+                             /* during drop-out control                  */
   };
 
   typedef PProfile   TProfileList;
@@ -434,307 +251,212 @@
   typedef PProfile*  PProfileList;
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* A simple record used to implement a stack of bands, required by the   */
-  /* sub-banding mechanism.                                                */
-  /*                                                                       */
-  typedef struct  _TBand
+  /* Simple record used to implement a stack of bands, required */
+  /* by the sub-banding mechanism                               */
+  typedef struct  TBand_
   {
-    TScan  y_min;   /* band's minimum */
-    TScan  y_max;   /* band's maximum */
-
+    Short  y_min;   /* band's minimum */
+    Short  y_max;   /* band's maximum */
+    
   } TBand;
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* The size in _TPos_ of a profile record in the render pool.            */
-  /*                                                                       */
-#define AlignProfileSize  \
-          ( (sizeof ( TProfile ) + sizeof ( TPos ) - 1) / sizeof ( TPos ) )
 
+#define AlignProfileSize \
+          (( sizeof(TProfile)+sizeof(long)-1 ) / sizeof(long))
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Prototypes used for sweep function dispatch.                          */
-  /*                                                                       */
-  typedef void  (*Function_Sweep_Init)( RAS_ARG_ int*  min,
-                                                 int*  max );
 
-  typedef void  (*Function_Sweep_Span)( RAS_ARG_ TScan  y,
-                                                 TPos   x1,
-                                                 TPos   x2 );
 
-  typedef int   (*Function_Test_Pixel)( RAS_ARG_ TScan  y,
-                                                 int    x );
+#ifdef TT_STATIC_RASTER
 
-  typedef void  (*Function_Set_Pixel)( RAS_ARG_  TScan  y,
-                                                 int    x,
-                                                 int    color );
+#define  RAS_ARGS  /* void */
+#define  RAS_ARG   /* void */
 
-  typedef void  (*Function_Sweep_Step)( RAS_ARG );
+#define  RAS_VARS  /* void */
+#define  RAS_VAR   /* void */
 
-  typedef struct Raster_Render_
-  {
-    Function_Sweep_Init  init;
-    Function_Sweep_Span  span;
-    Function_Sweep_Step  step;
-    Function_Test_Pixel  test_pixel;
-    Function_Set_Pixel   set_pixel;
-
-  } Raster_Render;
-
-
-#ifdef FT_RASTER_CONSTANT_PRECISION
-
-  #define PRECISION_BITS    FT_PRECISION_BITS
-  #define PRECISION         (1 << PRECISION_BITS)
-  #define PRECISION_MASK    (-1L << PRECISION_BITS)
-  #define PRECISION_HALF    (PRECISION >> 1)
-  #define PRECISION_JITTER  (PRECISION >> 5)
-  #define PRECISION_STEP    PRECISION_HALF
-
 #else
 
-  #define PRECISION_BITS    ras.precision_bits
-  #define PRECISION         ras.precision
-  #define PRECISION_MASK    ras.precision_mask
-  #define PRECISION_HALF    ras.precision_half
-  #define PRECISION_JITTER  ras.precision_jitter
-  #define PRECISION_STEP    ras.precision_step
+#define  RAS_ARGS  TRaster_Instance*  raster,
+#define  RAS_ARG   TRaster_Instance*  raster
 
+#define  RAS_VARS  raster,
+#define  RAS_VAR   raster
+
 #endif
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compute lowest integer coordinate below a given value.                */
-  /*                                                                       */
-#define FLOOR( x )  ( (x) & PRECISION_MASK )
 
+  typedef struct TRaster_Instance_  TRaster_Instance;
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compute highest integer coordinate above a given value.               */
-  /*                                                                       */
-#define CEILING( x )  ( ((x) + PRECISION - 1) & PRECISION_MASK )
 
+  /* prototypes used for sweep function dispatch */
+  typedef void  Function_Sweep_Init( RAS_ARGS Short*  min,
+                                              Short*  max );
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Get integer coordinate of a given 26.6 or 22.10 `x' coordinate -- no  */
-  /* rounding.                                                             */
-  /*                                                                       */
-#define TRUNC( x )  ( (signed long)(x) >> PRECISION_BITS )
+  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 );
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Get the fractional part of a given coordinate.                        */
-  /*                                                                       */
-#define FRAC( x )  ( (x) & (PRECISION-1) )
 
+/* NOTE: These operations are only valid on 2's complement processors */
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Scale an `input coordinate' (as found in FT_Outline structures) into  */
-  /* a `work coordinate' which depends on current resolution and render    */
-  /* mode.                                                                 */
-  /*                                                                       */
-#define SCALED( x )  ( ((x) << ras.scale_shift) - ras.scale_delta )
+#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.          */
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* DEBUG_PSET is used to plot a single pixel in VRam during debug mode.  */
-  /*                                                                       */
-#ifdef DEBUG_RASTER
-#define DEBUG_PSET  Pset()
-#else
-#define DEBUG_PSET
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* This structure defines a point in a plane.                            */
-  /*                                                                       */
-  typedef struct  _TPoint
+  struct  TRaster_Instance_
   {
-    TPos  x, y;
+    Int       precision_bits;       /* precision related variables */
+    Int       precision;
+    Int       precision_half;
+    Long      precision_mask;
+    Int       precision_shift;
+    Int       precision_step;
+    Int       precision_jitter;
 
-  } TPoint;
+    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     */
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* The most used variables are at the beginning of the structure.  Thus, */
-  /* their offset can be coded with less opcodes which results in a        */
-  /* smaller executable.                                                   */
-  /*                                                                       */
-  struct  FT_RasterRec_
-  {
-    PPos      cursor;              /* Current cursor in render pool  */
+    FT_Error  error;
 
-    PPos      pool;                /* The render pool base address   */
-    PPos      pool_size;           /* The render pool's size         */
-    PPos      pool_limit;          /* Limit of profiles zone in pool */
+    Int       numTurns;             /* number of Y-turns in outline        */
 
-    int       bit_width;           /* target bitmap width  */
-    PByte     bit_buffer;          /* target bitmap buffer */
-    PByte     pix_buffer;          /* target pixmap buffer */
+    TPoint*   arc;                  /* current Bezier arc pointer */
 
-    TPoint    last;
-    long      minY, maxY;
+    UShort    bWidth;               /* target bitmap width  */
+    PByte     bTarget;              /* target bitmap buffer */
+    PByte     gTarget;              /* target pixmap buffer */
 
-    int       error;
+    Long      lastX, lastY, minY, maxY;
 
-#ifndef FT_RASTER_CONSTANT_PRECISION
-    int       precision_bits;       /* precision related variables */
-    int       precision;
-    int       precision_half;
-    long      precision_mask;
-    int       precision_shift;
-    int       precision_step;
-    int       precision_jitter;
-#endif
+    UShort    num_Profs;            /* current number of profiles */
 
-    FT_Outline*  outline;
-
-    int       n_points;             /* number of points in current glyph   */
-    int       n_contours;           /* number of contours in current glyph */
-    int       n_extrema;            /* number of `extrema' scanlines       */
-
-    TPoint*   arc;                  /* current Bezier arc pointer */
-
-    int       num_profs;            /* current number of profiles */
-
-    char      fresh;                /* signals a fresh new profile which */
-                                    /* `start' field must be completed   */
-    char      joint;                /* signals that the last arc ended   */
+    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  cur_prof;             /* current profile                   */
-    PProfile  start_prof;           /* head of linked list of profiles   */
-    PProfile  first_prof;           /* contour's first profile in case   */
+    PProfile  cProfile;             /* current profile                   */
+    PProfile  fProfile;             /* head of linked list of profiles   */
+    PProfile  gProfile;             /* contour's first profile in case   */
                                     /* of impact                         */
-    TDirection  state;              /* rendering state */
+    TStates   state;                /* rendering state */
 
-    FT_Bitmap target;          /* description of target bit/pixmap */
-    void*     memory;
+    FT_Bitmap  target;          /* description of target bit/pixmap */
+    FT_Outline outline;
 
-    int       trace_bit;            /* current offset in target bitmap    */
-    int       trace_pix;            /* current offset in target pixmap    */
-    int       trace_incr;           /* sweep's increment in target bitmap */
+    Long      traceOfs;             /* current offset in target bitmap */
+    Long      traceG;               /* current offset in target pixmap */
 
-    /* dispatch variables */
+    Short     traceIncr;            /* sweep's increment in target bitmap */
 
-    Raster_Render     render;
+    Short     gray_min_x;           /* current min x during gray rendering */
+    Short     gray_max_x;           /* current max x during gray rendering */
 
-    int       scale_shift;      /* == 0  for bitmaps           */
-                                /* == 1  for 5-levels pixmaps  */
-                                /* == 2  for 17-levels pixmaps */
+    /* dispatch variables */
 
-    int       scale_delta;      /* ras.precision_half for bitmaps */
-                                /* 0 for pixmaps                  */
+    Function_Sweep_Init*  Proc_Sweep_Init;
+    Function_Sweep_Span*  Proc_Sweep_Span;
+    Function_Sweep_Span*  Proc_Sweep_Drop;
+    Function_Sweep_Step*  Proc_Sweep_Step;
 
-    char      dropout_mode;     /* current drop_out control method */
+    Byte      dropOutControl;       /* current drop_out control method */
 
-    char      second_pass;      /* indicates whether a horizontal pass     */
+    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 */
 
-    char      flipped;          /* this flag is set during the rendering to */
-                                /* indicate the second pass.                */
+    TBand     band_stack[16];       /* band stack used for sub-banding */
+    Int       band_top;             /* band stack top                  */
 
-    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         */
 
-    TPoint    arcs[2 * MaxBezier + 1];  /* The Bezier stack */
-  };
+    void*     memory;
 
+#ifdef FT_RASTER_OPTION_ANTI_ALIASING
 
+    Byte      grays[5];         /* Palette of gray levels used for render */
 
-#ifdef DEBUG_RASTER
+    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 */
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Pset                                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Used for debugging only.  Plots a point in VRAM during rendering   */
-  /*    (not afterwards).                                                  */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This procedure relies on the value of cProfile->start, which may   */
-  /*    not be set when Pset() is called sometimes.  This will usually     */
-  /*    result in a dot plotted on the first screen scanline (far away     */
-  /*    from its original position).                                       */
-  /*                                                                       */
-  /*    This `feature' reflects nothing wrong in the current               */
-  /*    implementation, and the bitmap is rendered correctly, so don't     */
-  /*    panic if you see `flying' dots in debugging mode.                  */
-  /*                                                                       */
-  static
-  void  Pset( RAS_ARG )
-  {
-    long  o;
-    long  x;
+                        /* The gray_lines must hold 2 lines, thus with size */
+                        /* in bytes of at least 'gray_width*2'              */
 
-    x = ras.cursor[-1];
+#endif /* FT_RASTER_ANTI_ALIASING */
+    
+#if 0
+    PByte     flags;                /* current flags table    */
+    PUShort   outs;                 /* current outlines table */
+    FT_Vector*  coords;
 
-    switch ( ras.cur_prof->flow )
-    {
-    case FT_Flow_Up:
-      o = Vio_ScanLineWidth *
-         ( ras.cursor - ras.cur_prof->offset + ras.cur_prof->start ) +
-         ( x / (PRECISION * 8) );
-      break;
+    UShort    nPoints;              /* number of points in current glyph   */
+    Short     nContours;            /* number of contours in current glyph */
+#endif
 
-    case FT_Flow_Down:
-      o = Vio_ScanLineWidth *
-         ( ras.cur_prof->start - ras.cursor + ras.cur_prof->offset ) +
-         ( x / (PRECISION * 8) );
-      break;
-    }
 
-    if ( o > 0 )
-      Vio[o] |= (unsigned)0x80 >> ( (x/PRECISION) & 7 );
-  }
+  };
 
 
-  static
-  void  Clear_Band( RAS_ARG_ TScan  y1,
-                             TScan  y2 )
-  {
-    MEM_Set( Vio + y1*Vio_ScanLineWidth, (y2-y1+1)*Vio_ScanLineWidth, 0 );
-  }
+#ifdef FT_CONFIG_OPTION_STATIC_RASTER
 
-#endif /* DEBUG_RASTER */
+  static TRaster_Instance  cur_ras;
+  #define ras  cur_ras
+  
+#else
 
+  #define ras  (*raster)
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Set_High_Precision                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets precision variables according to the parameter flag.          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    High :: Set to True for high precision (typically for ppem < 18),  */
-  /*    false otherwise.                                                   */
-  /*                                                                       */
-  static
-  void  Set_High_Precision( RAS_ARG_  char  High )
+#endif /* FT_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 )
   {
-#ifdef FT_RASTER_CONSTANT_PRECISION
-    (void)High;
-    (void)&ras;
-#else
     if ( High )
     {
       ras.precision_bits   = 10;
@@ -748,206 +470,127 @@
       ras.precision_jitter = 2;
     }
 
+    FT_TRACE7(( "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 - INPUT_BITS;
+    ras.precision_shift = ras.precision_bits - Pixel_Bits;
     ras.precision_mask  = -ras.precision;
-#endif
   }
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* A simple technical note on how the raster works:                      */
-  /*                                                                       */
-  /*   Converting an outline into a bitmap is achieved in several steps    */
-  /*   which are:                                                          */
-  /*                                                                       */
-  /*   1 - Decomposing the outline into successive `profiles'.  Each       */
-  /*       profile is simply an array of scanline intersections on a given */
-  /*       dimension.  A profile's main attributes are                     */
-  /*                                                                       */
-  /*       o its scanline position boundaries, i.e. `Ymin' and `Ymax'.     */
-  /*                                                                       */
-  /*       o an array of intersection coordinates for each scanline        */
-  /*         between `Ymin' and `Ymax'.                                    */
-  /*                                                                       */
-  /*       o a direction, indicating wether is was built going `up' or     */
-  /*         `down', as this is very important for filling rules.          */
-  /*                                                                       */
-  /*   2 - Sweeping the target map's scanlines in order to compute segment */
-  /*       `spans' which are then filled.  Additionaly, this pass performs */
-  /*       drop-out control.                                               */
-  /*                                                                       */
-  /*   The outline data is parsed during step 1 only.  The profiles are    */
-  /*   built from the bottom of the render pool, used as a stack.  The     */
-  /*   following graphics shows the profile list under construction:       */
-  /*                                                                       */
-  /*     ____________________________________________________________ _ _  */
-  /*    |         |                   |         |                 |        */
-  /*    | profile | coordinates for   | profile | coordinates for |-->     */
-  /*    |    1    |  profile 1        |    2    |  profile 2      |-->     */
-  /*    |_________|___________________|_________|_________________|__ _ _  */
-  /*                                                                       */
-  /*    ^                                                         ^        */
-  /*    |                                                         |        */
-  /*    start of render pool                                   cursor      */
-  /*                                                                       */
-  /*   The top of the profile stack is kept in the `cursor' variable.      */
-  /*                                                                       */
-  /*   As you can see, a profile record is pushed on top of the render     */
-  /*   pool, which is then followed by its coordinates/intersections.  If  */
-  /*   a change of direction is detected in the outline, a new profile is  */
-  /*   generated until the end of the outline.                             */
-  /*                                                                       */
-  /*   Note that when all profiles have been generated, the function       */
-  /*   Finalize_Profile_Table() is used to record, for each profile, its   */
-  /*   bottom-most scanline as well as the scanline above its upmost       */
-  /*   boundary.  These positions are called `extrema' because they (sort  */
-  /*   of) correspond to local extrema.  They are stored in a sorted list  */
-  /*   built from the top of the render pool as a downwards stack:         */
-  /*                                                                       */
-  /*      _ _ _______________________________________                      */
-  /*                            |                    |                     */
-  /*                         <--| sorted list of     |                     */
-  /*                         <--|  extrema scanlines |                     */
-  /*      _ _ __________________|____________________|                     */
-  /*                                                                       */
-  /*                            ^                    ^                     */
-  /*                            |                    |                     */
-  /*                       pool_limit        end of render pool            */
-  /*                                                                       */
-  /*   This list is later used during the sweep phase in order to          */
-  /*   optimize performance (see technical note on the sweep below).       */
-  /*                                                                       */
-  /*   Of course, the raster detects whether the two stacks collide and    */
-  /*   handles the situation propertly.                                    */
-  /*                                                                       */
-  /*************************************************************************/
 
+/****************************************************************************/
+/*                                                                          */
+/* Function:    New_Profile                                                 */
+/*                                                                          */
+/* Description: Creates a new Profile in the render pool.                   */
+/*                                                                          */
+/* Input:       aState   state/orientation of the new Profile               */
+/*                                                                          */
+/* Returns:     SUCCESS on success.                                         */
+/*              FAILURE in case of overflow or of incoherent Profile.       */
+/*                                                                          */
+/****************************************************************************/
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    New_Profile                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Creates a new Profile in the render pool.                          */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    aState :: The state/orientation of the new profile.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
-  static
-  TResult  New_Profile( RAS_ARG_ TDirection  direction )
+  static Bool  New_Profile( RAS_ARGS TStates  aState )
   {
-    if ( ras.start_prof == NULL )
+    if ( !ras.fProfile )
     {
-      ras.cur_prof   = (PProfile)ras.cursor; /* current profile          */
-      ras.start_prof = ras.cur_prof;         /* first profile in pool    */
-      ras.cursor    += AlignProfileSize;     /* record profile in buffer */
+      ras.cProfile  = (PProfile)ras.top;
+      ras.fProfile  = ras.cProfile;
+      ras.top      += AlignProfileSize;
     }
 
-    /* check for overflow */
-    if ( ras.cursor >= ras.pool_limit )
+    if ( ras.top >= ras.maxBuff )
     {
-      ras.error = ErrRaster_Overflow;
+      ras.error = Raster_Err_Overflow;
       return FAILURE;
     }
 
-    /* record profile direction */
-    switch ( direction )
+    switch ( aState )
     {
     case Ascending:
-      ras.cur_prof->flow = Flow_Up;
+      ras.cProfile->flow = Flow_Up;
+      FT_TRACE7(( "New ascending profile = %lx\n", (long)ras.cProfile ));
       break;
 
     case Descending:
-      ras.cur_prof->flow = Flow_Down;
+      ras.cProfile->flow = Flow_Down;
+      FT_TRACE7(( "New descending profile = %lx\n", (long)ras.cProfile ));
       break;
 
     default:
-      ras.error = ErrRaster_Invalid_Map;
+      FT_ERROR(( "Invalid profile direction in Raster:New_Profile !!\n" ));
+      ras.error = Raster_Err_Invalid;
       return FAILURE;
     }
 
-    /* initialize a few fields */
-    {
-      PProfile  cur = ras.cur_prof;
+    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;
 
-      cur->start  = 0;            /* current start scanline          */
-      cur->height = 0;            /* current height                  */
-      cur->offset = ras.cursor;   /* address of first coordinate     */
-      cur->link   = (PProfile)0;  /* link to next profile in pool    */
-      cur->next   = (PProfile)0;  /* link to next profile in contour */
-    }
+    ras.state = aState;
+    ras.fresh = TRUE;
+    ras.joint = FALSE;
 
-    /* record the first profile in a contour */
-    if ( ras.first_prof == NULL )
-      ras.first_prof = ras.cur_prof;
-
-    ras.state  = direction;
-    ras.fresh  = TRUE;       /* this profile has no coordinates yet */
-    ras.joint  = FALSE;
-
     return SUCCESS;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    End_Profile                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Finalizes the current Profile and computes its height.  If it is   */
-  /*    not 0, the profile's fields are updated and a new profile is       */
-  /*    pushed on top of its coordinates.  Otherwise the current profile   */
-  /*    is kept and the recording of intersections is restarted.           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
-  static
-  TResult  End_Profile( RAS_ARG )
+/****************************************************************************/
+/*                                                                          */
+/* Function:    End_Profile                                                 */
+/*                                                                          */
+/* Description: Finalizes the current Profile.                              */
+/*                                                                          */
+/* Input:       None                                                        */
+/*                                                                          */
+/* Returns:     SUCCESS on success.                                         */
+/*              FAILURE in case of overflow or incoherency.                 */
+/*                                                                          */
+/****************************************************************************/
+
+  static Bool  End_Profile( RAS_ARG )
   {
-    int  h;
+    Long      h;
+    PProfile  oldProfile;
 
 
-    h = ras.cursor - ras.cur_prof->offset;
+    h = ras.top - ras.cProfile->offset;
 
     if ( h < 0 )
     {
-      /* This error should _never_ occur unless the raster is buggy */
-      ras.error = ErrRaster_Negative_Height;
+      FT_ERROR(( "Negative height encountered in End_Profile!\n" ));
+      ras.error = Raster_Err_Neg_Height;
       return FAILURE;
     }
 
     if ( h > 0 )
     {
-      PProfile  old, new;
+      FT_TRACE1(( "Ending profile %lx, start = %ld, height = %ld\n",
+                (long)ras.cProfile, ras.cProfile->start, h ));
 
-      /* record scanline height in current profile, create a new one */
-      /* and set a link from the old one to it                       */
-      old          = ras.cur_prof;
-      old->height  = h;
-      ras.cur_prof = new = (PProfile)ras.cursor;
+      oldProfile           = ras.cProfile;
+      ras.cProfile->height = h;
+      ras.cProfile         = (PProfile)ras.top;
 
-      ras.cursor  += AlignProfileSize;
+      ras.top             += AlignProfileSize;
 
-      new->height  = 0;
-      new->offset  = ras.cursor;
-      old->next    = new;
-
-      ras.num_profs++;
+      ras.cProfile->height = 0;
+      ras.cProfile->offset = ras.top;
+      oldProfile->next     = ras.cProfile;
+      ras.num_Profs++;
     }
 
-    /* check for overflow */
-    if ( ras.cursor >= ras.pool_limit )
+    if ( ras.top >= ras.maxBuff )
     {
-      ras.error = ErrRaster_Overflow;
+      FT_TRACE1(( "overflow in End_Profile\n" ));
+      ras.error = Raster_Err_Overflow;
       return FAILURE;
     }
 
@@ -957,41 +600,36 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Insert_Extrema                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Records that a given scanline contains at least one local          */
-  /*    extremum.  The table of extrema is placed at the end of the render */
-  /*    pool and grows downwards.  It is used during the sweep phase.      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*     y :: The coordinate of the scanline containing an extremum.       */
-  /*                                                                       */
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Insert_Y_Turn                                               */
+/*                                                                          */
+/* Description: Insert a salient into the sorted list placed on top         */
+/*              of the render pool                                          */
+/*                                                                          */
+/* Input:       New y scanline position                                     */
+/*                                                                          */
+/****************************************************************************/
+
   static
-  TResult  Insert_Extrema( RAS_ARG_ TScan  y )
+  Bool Insert_Y_Turn( RAS_ARGS  Int  y )
   {
-    PPos   extrema;
-    TScan  y2;
-    int    n;
+    PLong     y_turns;
+    Int       y2, n;
 
+    n       = ras.numTurns-1;
+    y_turns = ras.sizeBuff - ras.numTurns;
 
-    FT_TRACE2(( "EXTREMA += %d", y ));
-    n       = ras.n_extrema - 1;
-    extrema = ras.pool_size - ras.n_extrema;
-
-    /* look for first y extremum that is <= */
-    while ( n >= 0 && y < extrema[n] )
+    /* 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 > extrema[n] )
+    if ( n >= 0 && y > y_turns[n] )
       while ( n >= 0 )
       {
-        y2 = extrema[n];
-        extrema[n] = y;
+        y2 = y_turns[n];
+        y_turns[n] = y;
         y = y2;
         n--;
       }
@@ -998,44 +636,45 @@
 
     if ( n < 0 )
     {
-      ras.pool_limit--;
-      ras.n_extrema++;
-      ras.pool_size[-ras.n_extrema] = y;
-
-      if ( ras.pool_limit <= ras.cursor )
+      if (ras.maxBuff <= ras.top)
       {
-        ras.error = ErrRaster_Overflow;
+        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.  Called when the outline   */
-  /*    parsing is done.                                                   */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Finalize_Profile_Table                                      */
+/*                                                                          */
+/* Description: Adjusts all links in the Profiles list.                     */
+/*                                                                          */
+/* Input:       None                                                        */
+/*                                                                          */
+/* Returns:     None.                                                       */
+/*                                                                          */
+/****************************************************************************/
+
   static
-  TResult  Finalize_Profile_Table( RAS_ARG )
+  Bool Finalize_Profile_Table( RAS_ARG )
   {
-    int       n, bottom, top;
+    Int       bottom, top;
+    UShort    n;
     PProfile  p;
 
 
-    n = ras.num_profs;
+    n = ras.num_Profs;
 
     if ( n > 1 )
     {
-      p = ras.start_prof;
+      p = ras.fProfile;
       while ( n > 0 )
       {
         if ( n > 1 )
@@ -1045,25 +684,21 @@
 
         switch ( p->flow )
         {
-          case Flow_Down:
-            FT_TRACE2(( "FLOW DOWN (start = %d, height = %d)",
-                      p->start, p->height ));
-            bottom     = p->start - p->height+1;
-            top        = p->start;
-            p->start   = bottom;
-            p->offset += p->height-1;
-            break;
+        case Flow_Down:
+          bottom     = p->start - p->height+1;
+          top        = p->start;
+          p->start   = bottom;
+          p->offset += p->height-1;
+          break;
 
-          case Flow_Up:
-          default:
-            FT_TRACE2(( "FLOW UP (start = %d, height = %d)",
-                      p->start, p->height ));
-            bottom = p->start;
-            top    = p->start + p->height-1;
+        case Flow_Up:
+        default:
+          bottom = p->start;
+          top    = p->start + p->height-1;
         }
 
-        if ( Insert_Extrema( RAS_VAR_  bottom ) ||
-             Insert_Extrema( RAS_VAR_  top+1 )  )
+        if ( Insert_Y_Turn( RAS_VARS  bottom ) ||
+             Insert_Y_Turn( RAS_VARS  top+1 )  )
           return FAILURE;
 
         p = p->link;
@@ -1071,57 +706,119 @@
       }
     }
     else
-      ras.start_prof = NULL;
+      ras.fProfile = NULL;
 
     return SUCCESS;
   }
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /****         COMPUTE SCAN-LINE INTERSECTIONS FROM SEGMENTS           ****/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
 
+/****************************************************************************/
+/*                                                                          */
+/* 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).                                                     */
+/*                                                                          */
+/* Returns:     None.                                                       */
+/*                                                                          */
+/*                                                                          */
+/* 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>                                                            */
-  /*    Line_Up                                                            */
+  /* <Function>   Split_Cubic                                              */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Computes the scan-line intersections of an ascending line segment  */
-  /*    and stores them in the render pool.                                */
+  /*     Subdivides a third-order Bezier arc into two joint sub-arcs in    */
+  /*     the Bezier stack.                                                 */
   /*                                                                       */
-  /* <Input>                                                               */
-  /*    x1   :: The start x coordinate.                                    */
-  /*    y1   :: The start y coordinate.                                    */
-  /*    x2   :: The end x coordinate.                                      */
-  /*    y2   :: The end y coordinate.                                      */
-  /*    miny :: The minimum vertical grid coordinate.                      */
-  /*    maxy :: The maximum vertical grid coordinate.                      */
+  /* <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.                                                       */
   /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
   static
-  TResult  Line_Up( RAS_ARG_ TPos  x1,   TPos  y1,
-                             TPos  x2,   TPos  y2,
-                             TPos  miny, TPos  maxy )
+  void  Split_Cubic( TPoint*  base )
   {
-    TPos   Dx, Dy;
-    int    e1, e2, f1, f2, size;
-    TPos   Ix, Rx, Ax;
+    Long  a, b, c, d;
 
-    PPos  top;
+    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,y1,x2,y2  Segment start (x1,y1) and end (x2,y2) points   */
+/*                                                                          */
+/* Returns:     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;
 
@@ -1128,70 +825,38 @@
     if ( Dy <= 0 || y2 < miny || y1 > maxy )
       return SUCCESS;
 
-    /* clip to higher scanline when necessary */
-    if ( y2 > maxy )
+    if ( y1 < miny )
     {
-      /* x2 += FMulDiv( Dx, maxy-y2, Dy );  UNNECESSARY */
-      e2  = TRUNC( maxy );
-      f2  = 0;
+      /* 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
     {
-      e2 = TRUNC( y2 );
-      f2 = FRAC( y2 );
+      e1 = TRUNC( y1 );
+      f1 = FRAC( y1 );
     }
 
-    /* clip to lower scanline when necessary */
-    if ( y1 < miny )
+    if ( y2 > maxy )
     {
-#ifdef OLD
-      x1 += FT_MulDiv( Dx, miny-y1, Dy );
-      e1  = TRUNC( miny );
-      f1  = 0;
-#else    
-      TPos  x, y;
-
-      /* we use a binary search to compute the lower
-      // clipping intersection. That's because we don't
-      // want to use an external function like FT_MulDiv
-      // to compute it directly.
-      */
-      if ( y2 == miny ) goto Exit;
-      do
-      {
-        x = (x1 + x2) >> 1;
-        y = (y1 + y2) >> 1;
-
-        if (y <= miny)
-        {
-          x1 = x;
-          y1 = y;
-        }
-        else
-        {
-          x2 = x;
-          y2 = y;
-        }
-      }
-      while ( y1 < miny );
-
-      e1  = TRUNC( miny );
-      f1  = 0;
-#endif      
+      /* x2 += FMulDiv( Dx, maxy - y2, Dy );  UNNECESSARY */
+      e2  = TRUNC( maxy );
+      f2  = 0;
     }
     else
     {
-      e1 = TRUNC( y1 );
-      f1 = FRAC( y1 );
+      e2 = TRUNC( y2 );
+      f2 = FRAC( y2 );
     }
 
-    /* adjust start point so that we begin on an integer scanline position */
     if ( f1 > 0 )
     {
-      if ( e1 == e2 ) goto Exit;
+      if ( e1 == e2 ) return SUCCESS;
       else
       {
-        x1 += FMulDiv( Dx, PRECISION - f1, Dy );
+        x1 += FMulDiv( Dx, ras.precision - f1, Dy );
         e1 += 1;
       }
     }
@@ -1198,265 +863,127 @@
     else
       if ( ras.joint )
       {
-        ras.cursor--;
+        ras.top--;
         ras.joint = FALSE;
       }
 
     ras.joint = ( f2 == 0 );
 
-    /* if this is a `fresh' profile, record its starting scanline */
     if ( ras.fresh )
     {
-      ras.cur_prof->start = e1;
+      ras.cProfile->start = e1;
       ras.fresh           = FALSE;
     }
 
-    /* check for overflow */
     size = e2 - e1 + 1;
-    if ( ras.cursor + size >= ras.pool_limit )
+    if ( ras.top + size >= ras.maxBuff )
     {
-      ras.error = ErrRaster_Overflow;
+      ras.error = Raster_Err_Overflow;
       return FAILURE;
     }
 
-#ifdef OLD
     if ( Dx > 0 )
     {
-      Ix = ( PRECISION*Dx ) / Dy;
-      Rx = ( PRECISION*Dx ) % Dy;
+      Ix = (ras.precision*Dx) / Dy;
+      Rx = (ras.precision*Dx) % Dy;
       Dx = 1;
     }
     else
     {
-      Ix = -( (PRECISION*-Dx) / Dy );
-      Rx =    (PRECISION*-Dx) % Dy;
+      Ix = -( (ras.precision*-Dx) / Dy );
+      Rx =    (ras.precision*-Dx) % Dy;
       Dx = -1;
     }
-    
-    Ax = -Dy;
-#else
-    /* compute decision variables and push the intersections on top */
-    /* of the render pool                                           */
-    Dx <<= PRECISION_BITS;
-    Ix   = Dx / Dy;
-    Rx   = Dx % Dy;
-    if (Rx < 0)
-    {
-      Ix --;
-      Rx += Dy;
-    }
 
-    Ax   = -Dy;
-    Rx <<= 1;
-    Dy <<= 1;
-#endif
+    Ax  = -Dy;
+    top = ras.top;
 
-    top = ras.cursor;
-
     while ( size > 0 )
     {
       *top++ = x1;
 
-      DEBUG_PSET;
-
       x1 += Ix;
       Ax += Rx;
       if ( Ax >= 0 )
       {
         Ax -= Dy;
-#ifdef OLD
         x1 += Dx;
-#else        
-        x1 ++;
-#endif        
       }
       size--;
     }
 
-    ras.cursor = top;
-  Exit:
+    ras.top = top;
     return SUCCESS;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Line_Down                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the scan-line intersections of a descending line segment  */
-  /*    and stores them in the render pool.                                */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    x1   :: The start x coordinate.                                    */
-  /*    y1   :: The start y coordinate.                                    */
-  /*    x2   :: The end x coordinate.                                      */
-  /*    y2   :: The end y coordinate.                                      */
-  /*    miny :: The minimum vertical grid coordinate.                      */
-  /*    maxy :: The maximum vertical grid coordinate.                      */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
-  static
-  TResult  Line_Down( RAS_ARG_ TPos  x1,   TPos  y1,
-                               TPos  x2,   TPos  y2,
-                               TPos  miny, TPos  maxy )
+  static Bool  Line_Down( RAS_ARGS Long  x1, Long  y1,
+                                   Long  x2, Long  y2,
+                                   Long  miny, Long  maxy )
   {
-    TResult  result, fresh;
+    Bool result, fresh;
 
 
-    /* simply invert the coordinates and call Line_Up */
     fresh  = ras.fresh;
-    result = Line_Up( RAS_VAR_ x1, -y1, x2, -y2, -maxy, -miny );
 
-    /* if this was a fresh profile, invert the recorded start position */
+    result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny );
+
     if ( fresh && !ras.fresh )
-      ras.cur_prof->start = -ras.cur_prof->start;
+      ras.cProfile->start = -ras.cProfile->start;
 
     return result;
   }
 
 
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Bezier_Up                                                   */
+/*                                                                          */
+/* Description: Computes thes x-coordinates of an ascending bezier arc      */
+/*              and stores them in the render pool.                         */
+/*                                                                          */
 
-
  /* A function type describing the functions used to split bezier arcs */
   typedef  void  (*TSplitter)( TPoint*  base );
 
-#ifdef FT_DYNAMIC_BEZIER_STEPS
-  static
-  TPos  Dynamic_Bezier_Threshold( RAS_ARG_ int degree, TPoint*  arc )
+  static Bool  Bezier_Up( RAS_ARGS Int        degree,
+                                   TSplitter  splitter,
+                                   Long       miny,
+                                   Long       maxy )
   {
-    TPos    min_x,  max_x,  min_y, max_y, A, B;
-    TPos    wide_x, wide_y, threshold;
-    TPoint* cur   = arc;
-    TPoint* limit = cur + degree;
+    Long   y1, y2, e, e2, e0;
+    Short  f1;
 
-    /* first of all, set the threshold to the maximum x or y extent */
-    min_x = max_x = arc[0].x;
-    min_y = max_y = arc[0].y;
-    cur++;
-    for ( ; cur < limit; cur++ )
-    {
-      TPos  x = cur->x;
-      TPos  y = cur->y;
-
-      if ( x < min_x ) min_x = x;
-      if ( x > max_x ) max_x = x;
-
-      if ( y < min_y ) min_y = y;
-      if ( y > max_y ) max_y = y;
-    }
-    wide_x = (max_x - min_x) << 4;
-    wide_y = (max_y - min_y) << 4;
-
-    threshold = wide_x;
-    if (threshold < wide_y) threshold = wide_y;
-
-    /* now compute the second and third order error values */
-    
-    wide_x = arc[0].x + arc[1].x - arc[2].x*2;
-    wide_y = arc[0].y + arc[1].y - arc[2].y*2;
-
-    if (wide_x < 0) wide_x = -wide_x;
-    if (wide_y < 0) wide_y = -wide_y;
-
-    A = wide_x; if ( A < wide_y ) A = wide_y;
-
-    if (degree >= 3)
-    {
-      wide_x = arc[3].x - arc[0].x + 3*(arc[2].x - arc[3].x);
-      wide_y = arc[3].y - arc[0].y + 3*(arc[2].y - arc[3].y);
-
-      if (wide_x < 0) wide_x = -wide_x;
-      if (wide_y < 0) wide_y = -wide_y;
-
-      B = wide_x; if ( B < wide_y ) B = wide_y;
-    }
-    else
-      B = 0;
-
-    while ( A > 0 || B > 0 )
-    {
-      threshold >>= 1;
-      A         >>= 2;
-      B         >>= 3;
-    }
-
-    if (threshold < PRECISION_STEP)
-      threshold = PRECISION_STEP;
-
-    return threshold;
-  }
-#endif
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Bezier_Up                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the scan-line intersections of an ascending second-order  */
-  /*    Bezier arc and stores them in the render pool.  The arc is taken   */
-  /*    from the top of the stack.                                         */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    miny :: The minimum vertical grid coordinate.                      */
-  /*    maxy :: The maximum vertical grid coordinate.                      */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
-  static
-  TResult  Bezier_Up( RAS_ARG_ int        degree,
-                               TSplitter  splitter,
-                               TPos       miny,
-                               TPos       maxy )
-  {
-    TPos  y1, y2, e, e2, e0, threshold;
-    int   f1;
-
     TPoint*  arc;
     TPoint*  start_arc;
 
-    PPos top;
+    PLong top;
 
 
     arc = ras.arc;
     y1  = arc[degree].y;
     y2  = arc[0].y;
-    top = ras.cursor;
+    top = ras.top;
 
     if ( y2 < miny || y1 > maxy )
       goto Fin;
 
-    e2 = FLOOR( y2 );  /* integer end y */
+    e2 = FLOOR( y2 );
 
-#ifdef OLD
     if ( e2 > maxy )
       e2 = maxy;
-      
+
     e0 = miny;
-#else    
-    if ( e2 > maxy )
-      e2 = FLOOR(maxy);
 
-    e0 = CEILING(miny);
-#endif
-
-
     if ( y1 < miny )
-    {
-      e = e0;        /* integer start y == current scanline */
-    }
+      e = miny;
     else
     {
-      e  = CEILING( y1 );   /* integer start y == current scanline */
-      f1 = FRAC( y1 );      /* fractional shift of start y         */
-      e0 = e;               /* first integer scanline to be pushed */
+      e  = CEILING( y1 );
+      f1 = FRAC( y1 );
+      e0 = e;
 
-      if ( f1 == 0 )        /* do we start on an integer scanline? */
+      if ( f1 == 0 )
       {
         if ( ras.joint )
         {
@@ -1464,127 +991,89 @@
           ras.joint = FALSE;
         }
 
-        *top++ = arc[degree].x;  /* write directly start position */
+        *top++ = arc[degree].x;
 
-        DEBUG_PSET;
-
-        e += PRECISION; /* go to next scanline */
+        e += ras.precision;
       }
     }
 
-    /* record start position if necessary */
     if ( ras.fresh )
     {
-      ras.cur_prof->start = TRUNC( e0 );
+      ras.cProfile->start = TRUNC( e0 );
       ras.fresh = FALSE;
     }
 
-    /* exit if the current scanline is already above the max scanline */
     if ( e2 < e )
       goto Fin;
 
-    /* check for overflow */
-    if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.pool_limit )
+    if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff )
     {
-      ras.cursor = top;
-      ras.error  = ErrRaster_Overflow;
+      ras.top   = top;
+      ras.error = Raster_Err_Overflow;
       return FAILURE;
     }
 
-    
-#ifdef FT_DYNAMIC_BEZIER_STEPS
-    /* compute dynamic bezier step threshold */
-    threshold = Dynamic_Bezier_Threshold( RAS_VAR_ degree, arc );
-#else
-    threshold = PRECISION_STEP;
-#endif
-
     start_arc = arc;
 
-    /* loop while there is still an arc on the bezier stack */
-    /* and the current scan line is below y max == e2       */
     while ( arc >= start_arc && e <= e2 )
     {
       ras.joint = FALSE;
 
-      y2 = arc[0].y;  /* final y of the top-most arc */
+      y2 = arc[0].y;
 
-      if ( y2 > e )   /* the arc intercepts the current scanline */
+      if ( y2 > e )
       {
-        y1 = arc[degree].y;  /* start y of top-most arc */
-
-#ifdef OLD
-        if ( y2-y1 >= PRECISION_STEP )
-#else        
-        if ( y2 >= e + PRECISION || y2 - y1 >= threshold )
-#endif        
+        y1 = arc[degree].y;
+        if ( y2 - y1 >= ras.precision_step )
         {
-          /* if the arc's height is too great, split it */
           splitter( arc );
           arc += degree;
         }
         else
         {
-          /* otherwise, approximate it as a segment and compute */
-          /* its intersection with the current scanline         */
-          *top++ = arc[degree].x +
-                   FMulDiv( arc[0].x-arc[degree].x,
-                            e  - y1,
-                            y2 - y1 );
-
-          DEBUG_PSET;
-
-          arc -= degree;         /* pop the arc         */
-          e   += PRECISION;  /* go to next scanline */
+          *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x,
+                                            e - y1, y2 - y1 );
+          arc -= degree;
+          e   += ras.precision;
         }
       }
       else
       {
-        if ( y2 == e )        /* if the arc falls on the scanline */
-        {                     /* record its _joint_ intersection  */
+        if ( y2 == e )
+        {
           ras.joint  = TRUE;
           *top++     = arc[0].x;
 
-          DEBUG_PSET;
-
-          e += PRECISION; /* go to next scanline */
+          e += ras.precision;
         }
-        arc -= degree;        /* pop the arc */
+        arc -= degree;
       }
     }
 
   Fin:
-    ras.cursor = top;
-    ras.arc   -= degree;
+    ras.top  = top;
+    ras.arc -= degree;
     return SUCCESS;
   }
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Bezier_Down                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the scan-line intersections of a descending second-order  */
-  /*    Bezier arc and stores them in the render pool.  The arc is taken   */
-  /*    from the top of the stack.                                         */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    miny :: The minimum vertical grid coordinate.                      */
-  /*    maxy :: The maximum vertical grid coordinate.                      */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
-  static
-  TResult  Bezier_Down( RAS_ARG_ int        degree,
-                                 TSplitter  splitter,
-                                 TPos       miny,
-                                 TPos       maxy )
+
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Bezier_Down                                                 */
+/*                                                                          */
+/* Description: Computes the x-coordinates of a descending bezier arc       */
+/*              and stores them in the render pool.                         */
+/*                                                                          */
+
+  static Bool  Bezier_Down( RAS_ARGS Int        degree,
+                                     TSplitter  splitter,
+                                     Long       miny,
+                                     Long       maxy )
   {
     TPoint*  arc = ras.arc;
-    TResult  result, fresh;
+    Bool     result, fresh;
 
+
     arc[0].y = -arc[0].y;
     arc[1].y = -arc[1].y;
     arc[2].y = -arc[2].y;
@@ -1593,10 +1082,10 @@
 
     fresh = ras.fresh;
 
-    result = Bezier_Up( RAS_VAR_ degree, splitter, -maxy, -miny );
+    result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny );
 
     if ( fresh && !ras.fresh )
-      ras.cur_prof->start = -ras.cur_prof->start;
+      ras.cProfile->start = -ras.cProfile->start;
 
     arc[0].y = -arc[0].y;
     return result;
@@ -1603,278 +1092,71 @@
   }
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /****         SPLITTING CONIC AND CUBIC BEZIERS IN HALF               ****/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Line_To                                                     */
+/*                                                                          */
+/* Description: Injects a new line segment and adjusts Profiles list.       */
+/*                                                                          */
+/* Input:       x, y : segment endpoint (start point in LastX,LastY)        */
+/*                                                                          */
+/* Returns:     SUCCESS on success.                                         */
+/*              FAILURE on Render Pool overflow or Incorrect Profile.       */
+/*                                                                          */
+/****************************************************************************/
 
-
-#ifdef FT_RASTER_CONIC_BEZIERS
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Split_Conic                                                        */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Subdivides one second-order Bezier arc into two joint sub-arcs in  */
-  /*    the Bezier stack.                                                  */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This routine is the `beef' of the component.  It is one of _the_   */
-  /*    inner loops that should be optimized like hell to get the best     */
-  /*    performance.                                                       */
-  /*                                                                       */
-  static
-  void  Split_Conic( TPoint*  base )
+  static Bool  Line_To( RAS_ARGS Long  x, Long  y )
   {
-    TPos  a, b;
+    /* First, detect a change of direction */
 
-
-    base[4].x = base[2].x;
-    b = base[1].x;
-    a = base[3].x = ( base[2].x + b + 1 ) >> 1;
-    b = base[1].x = ( base[0].x + b + 1 ) >> 1;
-    base[2].x = ( a + b + 1 ) >> 1;
-
-    base[4].y = base[2].y;
-    b = base[1].y;
-    a = base[3].y = ( base[2].y + b + 1 ) >> 1;
-    b = base[1].y = ( base[0].y + b + 1 ) >> 1;
-    base[2].y = ( a + b ) / 2;
-  }
-
-#endif
-
-#ifdef FT_RASTER_CUBIC_BEZIERS
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>   Split_Cubic                                              */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*     Subdivides a third-order Bezier arc into two joint sub-arcs in    */
-  /*     the Bezier stack.                                                 */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This routine is the `beef' of the component.  It is one of _the_   */
-  /*    inner loops that should be optimized like hell to get the best     */
-  /*    performance.                                                       */
-  /*                                                                       */
-  static
-  void  Split_Cubic( TPoint*  base )
-  {
-    TPos   a, b, c, d;
-
-
-    base[6].x = base[3].x;
-    c = base[1].x;
-    d = base[2].x;
-    base[1].x = a = ( base[0].x + c + 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;
-  }
-
-#endif /* FT_RASTER_CUBIC_BEZIERS */
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /****                   PROCESSING OUTLINE SEGMENTS                   ****/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Check_Contour                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Performs some checks at contour closure.                           */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
-  static
-  TResult  Check_Contour( RAS_ARG )
-  {
-    PProfile  lastProfile;
-
-    /* Sometimes, the first and last profile in a contour join on      */
-    /* an integer scan-line; we must then remove the last intersection */
-    /* from the last profile to get rid of doublets                    */
-    if ( ( FRAC( ras.last.y ) == 0     &&
-           ras.last.y >= ras.minY      &&
-           ras.last.y <= ras.maxY )    )
+    switch ( ras.state )
     {
-      if ( ras.first_prof && ras.first_prof->flow == ras.cur_prof->flow )
-        ras.cursor--;
-    }
+    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;
 
-    lastProfile = ras.cur_prof;
-    if ( End_Profile( RAS_VAR ) )
-      return FAILURE;
-
-    /* close the `next profile in contour' linked list */
-    lastProfile->next = ras.first_prof;
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Move_To                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This function injects a new contour in the render pool.            */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    to     :: A pointer to the contour's first point.                  */
-  /*    raster :: A pointer to the current raster object.                  */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Error code.  0 means success.                                      */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This function is used as a `FTRasterMoveTo_Func' by the outline    */
-  /*    decomposer.                                                        */
-  /*                                                                       */
-  static
-  int  Move_To( FT_Vector*  to,
-                FT_Raster   raster )
-  {
-    TPos  scaled_x, scaled_y;
-
-
-    /* if there was already a contour being built, perform some checks */
-    if ( ras.start_prof )
-      if ( Check_Contour( RAS_VAR ) )
-        return FAILURE;
-
-    /* set the `current last point' */
-    scaled_x = SCALED( to->x );
-    scaled_y = SCALED( to->y );
-
-    if ( ras.flipped )
-    {
-      ras.last.x = scaled_y;
-      ras.last.y = scaled_x;
-    }
-    else
-    {
-      ras.last.x = scaled_x;
-      ras.last.y = scaled_y;
-    }
-
-    ras.state      = Unknown;
-    ras.first_prof = NULL;
-
-    return SUCCESS;
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Line_To                                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    This function injects a new line segment in the render pool and    */
-  /*    adjusts the profiles list accordingly.                             */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    to     :: A pointer to the target position.                        */
-  /*    raster :: A pointer to the current raster object.                  */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Error code.  0 means success.                                      */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This function is used as a `FTRasterLineTo_Func' by the outline    */
-  /*    decomposer.                                                        */
-  /*                                                                       */
-  static
-  int  Line_To( FT_Vector*  to,
-                FT_Raster   raster )
-  {
-    TPos  x, scaled_x;
-    TPos  y, scaled_y;
-
-
-    scaled_x = SCALED( to->x );
-    scaled_y = SCALED( to->y );
-
-    if ( ras.flipped )
-    {
-      x = scaled_y;
-      y = scaled_x;
-    }
-    else
-    {
-      x = scaled_x;
-      y = scaled_y;
-    }
-
-    /* First, detect a change of direction */
-    if ( y != ras.last.y )
-    {
-      TDirection  new_state = ( (y > ras.last.y) ? Ascending : Descending );
-
-
-      if ( ras.state != new_state )
+    case Ascending:
+      if ( y < ras.lastY )
       {
-        if ( ras.state != Unknown   &&
-             End_Profile( RAS_VAR ) )
-          goto Fail;
+        if ( End_Profile( RAS_VAR ) ||
+             New_Profile( RAS_VARS  Descending ) ) return FAILURE;
+      }
+      break;
 
-        if ( New_Profile( RAS_VAR_  new_state ) )
-          goto Fail;
+    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_VAR_  ras.last.x, ras.last.y,
-                               x, y, ras.minY, ras.maxY ) )
-        goto Fail;
+      if ( Line_Up ( RAS_VARS  ras.lastX, ras.lastY,
+                     x, y, ras.minY, ras.maxY ) )
+        return FAILURE;
       break;
 
     case Descending:
-      if ( Line_Down( RAS_VAR_ ras.last.x, ras.last.y,
-                               x, y, ras.minY, ras.maxY ) )
-        goto Fail;
+      if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,
+                      x, y, ras.minY, ras.maxY ) )
+        return FAILURE;
       break;
 
     default:
@@ -1881,101 +1163,35 @@
       ;
     }
 
-    ras.last.x = x;
-    ras.last.y = y;
+    ras.lastX = x;
+    ras.lastY = y;
 
     return SUCCESS;
-
-  Fail:
-    return FAILURE;
   }
 
 
-#ifdef FT_RASTER_CONIC_BEZIERS
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Conic_To                                                    */
+/*                                                                          */
+/* Description: Injects a new conic arc and adjusts the profile list.       */
+/*                                                                          */
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Push_Conic                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Clears the Bezier stack and pushes a new arc on top of it.         */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    p2 :: A pointer to the second (control) point.                     */
-  /*    p3 :: A pointer to the third (end) point.                          */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The first point is taken as `raster->last', so it doesn't appear   */
-  /*    in the signature.                                                  */
-  /*                                                                       */
-  static
-  void  Push_Conic( RAS_ARG_ FT_Vector*  p2,
-                             FT_Vector*  p3 )
+  static Bool  Conic_To( RAS_ARGS Long  cx,
+                                  Long  cy,
+                                  Long  x,
+                                  Long  y )
   {
-#undef  STORE
-#define STORE( _arc, point )                    \
-          {                                     \
-            TPos  x = SCALED( point->x );       \
-            TPos  y = SCALED( point->y );       \
-                                                \
-                                                \
-            if ( ras.flipped )                  \
-            {                                   \
-              _arc.x = y;                       \
-              _arc.y = x;                       \
-            }                                   \
-            else                                \
-            {                                   \
-              _arc.x = x;                       \
-              _arc.y = y;                       \
-            }                                   \
-          }
+    Long     y1, y2, y3, x3, ymin, ymax;
+    TStates  state_bez;
 
-    TPoint*  arc;
 
+    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;
 
-    ras.arc = arc = ras.arcs;
-
-    arc[2] = ras.last;
-    STORE( arc[1], p2 );
-    STORE( arc[0], p3 );
-#undef  STORE
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Conic_To                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Injects a new conic Bezier arc and adjusts the profile list        */
-  /*    accordingly.                                                       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    control :: A pointer to an intermediate control point.             */
-  /*    to      :: A pointer to the end point.                             */
-  /*    raster  :: A handle to the current raster object.                  */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Error code.  0 means success.                                      */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This function is used as a `FTRasterConicTo_Func' by the outline   */
-  /*    decomposer.                                                        */
-  /*                                                                       */
-  static
-  int  Conic_To( FT_Vector*  control,
-                 FT_Vector*  to,
-                 FT_Raster   raster )
-  {
-    TPos        y1, y2, y3, x3, ymin, ymax;
-    TDirection  state_bez;
-
-
-    Push_Conic( RAS_VAR_  control, to );
-
     do
     {
       y1 = ras.arc[2].y;
@@ -2020,7 +1236,7 @@
             goto Fail;
 
           /* create a new profile */
-          if ( New_Profile( RAS_VAR_ state_bez ) )
+          if ( New_Profile( RAS_VARS state_bez ) )
             goto Fail;
         }
 
@@ -2027,135 +1243,49 @@
         /* now call the appropriate routine */
         if ( state_bez == Ascending )
         {
-          if ( Bezier_Up( RAS_VAR_  2, Split_Conic, ras.minY, ras.maxY ) )
+          if ( Bezier_Up( RAS_VARS  2, Split_Conic, ras.minY, ras.maxY ) )
             goto Fail;
         }
         else
-          if ( Bezier_Down( RAS_VAR_  2, Split_Conic, ras.minY, ras.maxY ) )
+          if ( Bezier_Down( RAS_VARS  2, Split_Conic, ras.minY, ras.maxY ) )
             goto Fail;
       }
 
     } while ( ras.arc >= ras.arcs );
 
-    ras.last.x = x3;
-    ras.last.y = y3;
+    ras.lastX = x3;
+    ras.lastY = y3;
 
     return SUCCESS;
-
   Fail:
     return FAILURE;
   }
 
-#else /* FT_RASTER_CONIC_BEZIERS */
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Cubic_To                                                    */
+/*                                                                          */
+/* Description: Injects a new cubic arc and adjusts the profile list.       */
+/*                                                                          */
 
-
-  static
-  int  Conic_To( FT_Vector*  control,
-                 FT_Vector*  to,
-                 FT_Raster   raster )
+  static Bool  Cubic_To( RAS_ARGS Long  cx1,
+                                  Long  cy1,
+                                  Long  cx2,
+                                  Long  cy2,
+                                  Long  x,
+                                  Long  y )
   {
-    UNUSED( control );
-    UNUSED( to );
-    UNUSED( raster );
+    Long     y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
+    TStates  state_bez;
 
-    return ErrRaster_Invalid_Outline;
-  }
 
-#endif /* FT_RASTER_CONIC_BEZIERS */
+    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;
 
-
-#ifdef FT_RASTER_CUBIC_BEZIERS
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Push_Cubic                                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Clears the Bezier stack and pushes a new third-order Bezier arc on */
-  /*    top of it.                                                         */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    p2 :: A pointer to the second (control) point.                     */
-  /*    p3 :: A pointer to the third (control) point.                      */
-  /*    p4 :: A pointer to the fourth (end) point.                         */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The first point is taken as `raster->last', so it doesn't appear   */
-  /*    in the signature.                                                  */
-  /*                                                                       */
-  /*    This is the same as Push_Conic(), except that it deals with        */
-  /*    third-order Beziers.                                               */
-  /*                                                                       */
-  static
-  void  Push_Cubic( RAS_ARG_ FT_Vector*  p2,
-                             FT_Vector*  p3,
-                             FT_Vector*  p4 )
-  {
-#undef  STORE
-#define STORE( _arc, point )                    \
-          {                                     \
-            TPos  x = SCALED( point->x );       \
-            TPos  y = SCALED( point->y );       \
-                                                \
-            if ( ras.flipped )                  \
-            {                                   \
-              _arc.x = y;                       \
-              _arc.y = x;                       \
-            }                                   \
-            else                                \
-            {                                   \
-              _arc.x = x;                       \
-              _arc.y = y;                       \
-            }                                   \
-          }
-
-    TPoint*  arc;
-    ras.arc = arc = ras.arcs;
-
-    arc[3] = ras.last;
-    STORE( arc[2], p2 );
-    STORE( arc[1], p3 );
-    STORE( arc[0], p4 );
-
-#undef STORE
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Cubic_To                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Injects a new cubic Bezier arc and adjusts the profile list        */
-  /*    accordingly.                                                       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    control1 :: A pointer to the first control point.                  */
-  /*    control2 :: A pointer to the second control point.                 */
-  /*    to       :: A pointer to the end point.                            */
-  /*    raster   :: A handle to the current raster object.                 */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Error code.  0 means success.                                      */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    This function is used as a `FTRasterCubicTo_Func' by the outline   */
-  /*    decomposer.                                                        */
-  /*                                                                       */
-  static
-  int  Cubic_To( FT_Vector*  control1,
-                 FT_Vector*  control2,
-                 FT_Vector*  to,
-                 FT_Raster   raster )
-  {
-    TPos        y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
-    TDirection  state_bez;
-
-
-    Push_Cubic( RAS_VAR_  control1, control2, to );
-
     do
     {
       y1 = ras.arc[3].y;
@@ -2210,7 +1340,7 @@
                End_Profile( RAS_VAR ) )
             goto Fail;
 
-          if ( New_Profile( RAS_VAR_ state_bez ) )
+          if ( New_Profile( RAS_VARS state_bez ) )
             goto Fail;
         }
 
@@ -2217,128 +1347,338 @@
         /* compute intersections */
         if ( state_bez == Ascending )
         {
-          if ( Bezier_Up ( RAS_VAR_ 3, Split_Cubic, ras.minY, ras.maxY ) )
+          if ( Bezier_Up ( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
             goto Fail;
         }
         else
-          if ( Bezier_Down ( RAS_VAR_ 3, Split_Cubic, ras.minY, ras.maxY ) )
+          if ( Bezier_Down ( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
             goto Fail;
       }
 
     } while ( ras.arc >= ras.arcs );
 
-    ras.last.x = x4;
-    ras.last.y = y4;
+    ras.lastX = x4;
+    ras.lastY = y4;
 
     return SUCCESS;
-
   Fail:
     return FAILURE;
   }
 
 
-#else /* FT_RASTER_CUBIC_BEZIERS */
+/****************************************************************************/
+/*                                                                          */
+/* 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, last    : indexes of first and last point in         */
+/*                               contour.                                   */
+/*                                                                          */
+/* Returns:     SUCCESS on success.                                         */
+/*              FAILURE on error.                                           */
+/*                                                                          */
+/****************************************************************************/
 
+#undef  SWAP_
+#define SWAP_(x,y)  { Long swap = x; x = y; y = swap; }
 
-  int  Cubic_To( FT_Vector*  control1,
-                 FT_Vector*  control2,
-                 FT_Vector*  to,
-                 FT_Raster   raster )
+
+  static Bool  Decompose_Curve( RAS_ARGS UShort  first,
+                                         UShort  last,
+                                         int     flipped )
   {
-    UNUSED( control1 );
-    UNUSED( control2 );
-    UNUSED( to );
-    UNUSED( raster );
+    FT_Vector  v_last;
+    FT_Vector  v_control;
+    FT_Vector  v_start;
 
-    return ErrRaster_Invalid_Outline;
-  }
+    FT_Vector* points;
+    FT_Vector* point;
+    FT_Vector* limit;
+    char*      tags;
 
+    char   tag;       /* current point's state           */
 
-#endif /* FT_RASTER_CUBIC_BEZIERS */
+    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] );
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Convert_Glyph                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Converts a glyph into a series of segments and arcs and makes a    */
-  /*    profiles list with them.                                           */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    outline :: The glyph outline.                                      */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    SUCCESS or FAILURE.                                                */
-  /*                                                                       */
-  static
-  TResult  Convert_Glyph( RAS_ARG_ FT_Outline*  outline )
+    /* 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:       _xCoord, _yCoord : coordinates tables.                      */
+/*                                                                          */
+/*              Uses the 'Flag' table too.                                  */
+/*                                                                          */
+/* Returns:     SUCCESS on success.                                         */
+/*              FAILURE if any error was encountered during rendering.      */
+/*                                                                          */
+/****************************************************************************/
+
+  static Bool  Convert_Glyph( RAS_ARGS int  flipped )
   {
-    static
-    FT_Outline_Funcs  interface =
+    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++ )
     {
-      (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
-    };
+      ras.state    = Unknown;
+      ras.gProfile = NULL;
 
-    /* Set up state in the raster object */
-    ras.start_prof = NULL;
-    ras.joint      = FALSE;
-    ras.fresh      = FALSE;
+      if ( Decompose_Curve( RAS_VARS  start, ras.outline.contours[i], flipped ) )
+        return FAILURE;
 
-    ras.pool_limit = ras.pool_size - AlignProfileSize;
+      start = ras.outline.contours[i] + 1;
 
-    ras.n_extrema = 0;
+      /* We must now see if 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.                                                   */
 
-    ras.cur_prof         = (PProfile)ras.cursor;
-    ras.cur_prof->offset = ras.cursor;
-    ras.num_profs        = 0;
+      lastProfile = ras.cProfile;
+      if ( End_Profile( RAS_VAR ) ) return FAILURE;
 
-    /* Now decompose curve */
-    if ( FT_Outline_Decompose( outline, &interface, &ras ) )
-      return FAILURE;
-    /* XXX: the error condition is in ras.error */
+      /* close the 'next profile in contour' linked list */
+      if ( ras.gProfile )
+        lastProfile->next = ras.gProfile;
+    }
 
-    /* Check the last contour if needed */
-    if ( Check_Contour( RAS_VAR ) )
+    if (Finalize_Profile_Table( RAS_VAR ))
       return FAILURE;
 
-    /* Finalize profiles list */
-    return Finalize_Profile_Table( RAS_VAR );
+    return (ras.top < ras.maxBuff ? SUCCESS : FAILURE );
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Init_Linked                                                           */
-  /*                                                                       */
-  /*    Inits an empty linked list.                                        */
-  /*                                                                       */
-  static
-  void  Init_Linked( TProfileList*  l )
+  /****************************************************************/
+  /****************************************************************/
+  /**                                                            **/
+  /**  SCAN-LINE SWEEPS AND DRAWING                              **/
+  /**                                                            **/
+  /****************************************************************/
+  /****************************************************************/
+  
+
+/************************************************/
+/*                                              */
+/*  Init_Linked                                 */
+/*                                              */
+/*    Inits an empty linked list.               */
+/*                                              */
+/************************************************/
+
+  static void  Init_Linked( TProfileList*  l )
   {
     *l = NULL;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* InsNew                                                                */
-  /*                                                                       */
-  /*    Inserts a new Profile in a linked list.                            */
-  /*                                                                       */
-  static
-  void  InsNew( PProfileList  list,
-                PProfile      profile )
+/************************************************/
+/*                                              */
+/*  InsNew :                                    */
+/*                                              */
+/*    Inserts a new Profile in a linked list.   */
+/*                                              */
+/************************************************/
+
+  static void  InsNew( PProfileList  list,
+                       PProfile      profile )
   {
     PProfile  *old, current;
-    TPos       x;
+    Long       x;
 
 
     old     = list;
@@ -2358,15 +1698,16 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* DelOld                                                                */
-  /*                                                                       */
-  /*    Removes an old Profile from a linked list.                         */
-  /*                                                                       */
-  static
-  void  DelOld( PProfileList  list,
-                PProfile      profile )
+/*************************************************/
+/*                                               */
+/*  DelOld :                                     */
+/*                                               */
+/*    Removes an old Profile from a linked list. */
+/*                                               */
+/*************************************************/
+
+  static void  DelOld( PProfileList  list,
+                       PProfile      profile )
   {
     PProfile  *old, current;
 
@@ -2386,19 +1727,20 @@
       current = *old;
     }
 
-    /* We should never reach this place, unless the Profile was not  */
-    /* part of the list.                                             */
+    /* we should never get there, unless the Profile was not part of */
+    /* the list.                                                     */
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Update                                                                */
-  /*                                                                       */
-  /*    Updates all X offsets of a drawing list.                           */
-  /*                                                                       */
-  static
-  void  Update( PProfile  first )
+/************************************************/
+/*                                              */
+/*  Update :                                    */
+/*                                              */
+/*    Update all X offsets of a drawing list    */
+/*                                              */
+/************************************************/
+
+  static void  Update( PProfile  first )
   {
     PProfile  current = first;
 
@@ -2413,16 +1755,18 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Sort                                                                  */
-  /*                                                                       */
-  /*    Sorts a trace list.  In 95%, the list is already sorted.  We need  */
-  /*    an algorithm which is fast in this case.  Bubble sort is enough    */
-  /*    and simple to implement.                                           */
-  /*                                                                       */
-  static
-  void  Sort( PProfileList  list )
+/************************************************/
+/*                                              */
+/*  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;
 
@@ -2464,98 +1808,70 @@
   }
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /********                                                         ********/
-  /********            Vertical Bitmap Sweep Routines               ********/
-  /********                                                         ********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
+/***********************************************************************/
+/*                                                                     */
+/*  Vertical Sweep Procedure Set :                                     */
+/*                                                                     */
+/*  These three routines are used during the vertical black/white      */
+/*  sweep phase by the generic Draw_Sweep() function.                  */
+/*                                                                     */
+/***********************************************************************/
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Sweep_Init                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes the vertical bitmap sweep.  Called by the generic      */
-  /*    sweep/draw routine before its loop.                                */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    min :: The address of the current minimum scanline.                */
-  /*    max :: The address of the current maximum scanline.                */
-  /*                                                                       */
-  static
-  void  Vertical_Sweep_Init( RAS_ARG_ int*  min, int*  max )
+  static void  Vertical_Sweep_Init( RAS_ARGS Short*  min, Short*  max )
   {
-    long  pitch;
-
-    UNUSED( max );
-
-    pitch          = ras.target.pitch;
-
-    /* start from the bottom line, going up !! */
-    ras.trace_bit  = - *min * pitch;
-    ras.trace_incr = -pitch;
-
+    Long  pitch = ras.target.pitch;
+    
+    UNUSED(max);
+    
+    ras.traceIncr = (Short)- pitch;
+    ras.traceOfs  = - *min * pitch;
     if (pitch > 0)
-      ras.trace_bit += pitch*(ras.target.rows-1);
+      ras.traceOfs += (ras.target.rows-1)*pitch;
+  
+    ras.gray_min_x = 0;
+    ras.gray_max_x = 0;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Sweep_Span                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Draws a single horizontal bitmap span during the vertical bitmap   */
-  /*    sweep.                                                             */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y  :: The current scanline.                                        */
-  /*    x1 :: The left span edge.                                          */
-  /*    x2 :: The right span edge.                                         */
-  /*                                                                       */
-  static
-  void  Vertical_Sweep_Span( RAS_ARG_ TScan  y,
-                                      TPos   x1,
-                                      TPos   x2 )
+  static void  Vertical_Sweep_Span( RAS_ARGS Short       y,
+                                             FT_F26Dot6  x1,
+                                             FT_F26Dot6  x2,
+                                             PProfile    left,
+                                             PProfile    right )
   {
-    TPos   e1, e2;
-    int    c1, c2;
+    Long   e1, e2;
+    Short  c1, c2;
     Byte   f1, f2;
-    PByte  target;
+    Byte*  target;
 
-    UNUSED( y );
+    UNUSED(y);
+    UNUSED(left);
+    UNUSED(right);
 
     /* Drop-out control */
+
     e1 = TRUNC( CEILING( x1 ) );
-    
-    if ( x2 - x1 - PRECISION <= PRECISION_JITTER )
+
+    if ( x2-x1-ras.precision <= ras.precision_jitter )
       e2 = e1;
     else
       e2 = TRUNC( FLOOR( x2 ) );
 
-#ifdef OLD
-    if ( e2 >= 0 && e1 < ras.bit_width )
-#else
-    if ( e1 <= e2 && e2 >= 0 && e1 < ras.bit_width )
-#endif    
+    if ( e2 >= 0 && e1 < ras.bWidth )
     {
-      if ( e1 < 0 )              e1 = 0;
-      if ( e2 >= ras.bit_width ) e2 = ras.bit_width - 1;
+      if ( e1 < 0 )           e1 = 0;
+      if ( e2 >= ras.bWidth ) e2 = ras.bWidth-1;
 
-      c1 = e1 >> 3;
-      c2 = e2 >> 3;
+      c1 = (Short)(e1 >> 3);
+      c2 = (Short)(e2 >> 3);
 
       f1 =  ((unsigned char)0xFF >> (e1 & 7));
       f2 = ~((unsigned char)0x7F >> (e2 & 7));
 
-      target = ras.bit_buffer + ras.trace_bit + c1;
+      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 )
@@ -2579,828 +1895,543 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Test_Pixel                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Tests a pixel `light' during the vertical bitmap sweep.  Used      */
-  /*    during drop-out control only.                                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y :: The current scanline.                                         */
-  /*    x :: The current x coordinate.                                     */
-  /*                                                                       */
-  static
-  int  Vertical_Test_Pixel( RAS_ARG_ TScan  y,
-                                     int    x )
+  static void  Vertical_Sweep_Drop( RAS_ARGS Short       y,
+                                             FT_F26Dot6  x1,
+                                             FT_F26Dot6  x2,
+                                             PProfile    left,
+                                             PProfile    right )
   {
-    int c1 = x >> 3;
+    Long   e1, e2;
+    Short  c1, f1;
 
 
-    UNUSED( y );
+    /* Drop-out control */
 
-    return ( x >= 0 && x < ras.bit_width &&
-             ras.bit_buffer[ras.trace_bit + c1] & (0x80 >> (x & 7)) );
-  }
+    e1 = CEILING( x1 );
+    e2 = FLOOR  ( x2 );
 
+    if ( e1 > e2 )
+    {
+      if ( e1 == e2 + ras.precision )
+      {
+        switch ( ras.dropOutControl )
+        {
+        case 1:
+          e1 = e2;
+          break;
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Set_Pixel                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets a single pixel in a bitmap during the vertical sweep.  Used   */
-  /*    during drop-out control.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y     :: The current scanline.                                     */
-  /*    x     :: The current x coordinate.                                 */
-  /*    color :: Ignored by this function.                                 */
-  /*                                                                       */
-  static
-  void  Vertical_Set_Pixel( RAS_ARG_ int  y,
-                                     int  x,
-                                     int  color )
-  {
-    UNUSED( color );
-    UNUSED( y );
+        case 4:
+          e1 = CEILING( (x1 + x2 + 1) / 2 );
+          break;
 
-    if ( x >= 0 && x < ras.bit_width )
-      ras.bit_buffer[ras.trace_bit+(x >> 3)] |= (char)(0x80 >> (x & 7));
-  }
+        case 2:
+        case 5:
+          /* Drop-out Control Rule #4 */
 
+          /* The spec is not very clear regarding rule #4.  It      */
+          /* presents a method that is way too costly to implement  */
+          /* while the general idea seems to get rid of 'stubs'.    */
+          /*                                                        */
+          /* Here, we only get rid of stubs recognized when:        */
+          /*                                                        */
+          /*  upper stub:                                           */
+          /*                                                        */
+          /*   - P_Left and P_Right are in the same contour         */
+          /*   - P_Right is the successor of P_Left in that contour */
+          /*   - y is the top of P_Left and P_Right                 */
+          /*                                                        */
+          /*  lower stub:                                           */
+          /*                                                        */
+          /*   - P_Left and P_Right are in the same contour         */
+          /*   - P_Left is the successor of P_Right in that contour */
+          /*   - y is the bottom of P_Left                          */
+          /*                                                        */
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Sweep_Step                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Called whenever the sweep jumps to another scanline.  Only updates */
-  /*    the pointers in the vertical bitmap sweep.                         */
-  /*                                                                       */
-  static
-  void Vertical_Sweep_Step( RAS_ARG )
-  {
-    ras.trace_bit += ras.trace_incr;
-  }
+          /* 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 ( x2-x1 < ras.precision_half ) */
+          {
+            /* upper stub test */
 
-  static
-  const  Raster_Render   vertical_render_mono =
-  {
-    &Vertical_Sweep_Init,
-    &Vertical_Sweep_Span,
-    &Vertical_Sweep_Step,
-    &Vertical_Test_Pixel,
-    &Vertical_Set_Pixel
-  };
+            if ( left->next == right && left->height <= 0 ) return;
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /********                                                         ********/
-  /********           Horizontal Bitmap Sweep Routines              ********/
-  /********                                                         ********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
+            /* lower stub test */
 
+            if ( right->next == left && left->start == y ) return;
+          }
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Horizontal_Sweep_Init                                              */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes the horizontal bitmap sweep.  Called by the generic    */
-  /*    sweep/draw routine before its loop.                                */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    min :: The address of the current minimum pixel column.            */
-  /*    max :: The address of the current maximum pixel column.            */
-  /*                                                                       */
-  static
-  void  Horizontal_Sweep_Init( RAS_ARG_ int*  min,
-                                        int*  max )
-  {
-    UNUSED( ras );
-    UNUSED( min );
-    UNUSED( max );
+          /* check that the rightmost pixel isn't set */
 
-    /* nothing, really */
-  }
+          e1 = TRUNC( e1 );
 
+          c1 = (Short)(e1 >> 3);
+          f1 = e1 &  7;
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Horizontal_Sweep_Span                                              */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Draws a single vertical bitmap span during the horizontal bitmap   */
-  /*    sweep.  Actually, this function is only used to check for weird    */
-  /*    drop-out cases.                                                    */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y  :: The current pixel column.                                    */
-  /*    x1 :: The top span edge.                                           */
-  /*    x2 :: The bottom span edge.                                        */
-  /*                                                                       */
-  static
-  void  Horizontal_Sweep_Span( RAS_ARG_ TScan  y,
-                                        TPos   x1,
-                                        TPos   x2 )
-  {
-    TPos      e1, e2;
-    PByte  bits;
-    Byte   f1;
+          if ( e1 >= 0 && e1 < ras.bWidth &&
+               ras.bTarget[ras.traceOfs + c1] & (0x80 >> f1) )
+            return;
 
-    UNUSED( y );
+          if ( ras.dropOutControl == 2 )
+            e1 = e2;
+          else
+            e1 = CEILING( (x1 + x2 + 1) / 2 );
 
-    /* During the horizontal sweep, we only take care of drop-outs */
-    if ( x2 - x1 < PRECISION )
-    {
-      e1 = CEILING( x1 );
-      e2 = FLOOR( x2 );
+          break;
 
-      if ( e1 == e2 )
-      {
-        bits = ras.bit_buffer + (y >> 3);
-        f1   = (Byte)(0x80 >> (y & 7));
+        default:
+          return;  /* unsupported mode */
+        }
+      }
+      else
+        return;
+    }
 
-        e1 = TRUNC( e1 );
+    e1 = TRUNC( e1 );
 
-        if ( e1 >= 0 && e1 < ras.target.rows )
-        {
-          long pitch  = ras.target.pitch;
-          long offset = - pitch * e1;
+    if ( e1 >= 0 && e1 < ras.bWidth )
+    {
+      c1 = (Short)(e1 >> 3);
+      f1 = e1 & 7;
 
-          if (pitch > 0)
-            offset += (ras.target.rows-1)*pitch;
+      if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;
+      if ( ras.gray_max_x < c1 ) ras.gray_max_x = c1;
 
-          bits[offset] |= f1;
-        }
-      }
+      ras.bTarget[ras.traceOfs + c1] |= (char)(0x80 >> f1);
     }
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Horizontal_Test_Pixel                                              */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Tests a pixel `light' during the horizontal bitmap sweep.  Used    */
-  /*    during drop-out control only.                                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y :: The current pixel column.                                     */
-  /*    x :: The current row/scanline.                                     */
-  /*                                                                       */
-  static
-  int   Horizontal_Test_Pixel( RAS_ARG_ int  y,
-                                        int  x )
+  static void Vertical_Sweep_Step( RAS_ARG )
   {
-    char*  bits   = (char*)ras.bit_buffer + (y >> 3);
-    int    f1     = (Byte)(0x80 >> (y & 7));
-    long   pitch  = ras.target.pitch;
-    long   offset = - pitch * x;
+    ras.traceOfs += ras.traceIncr;
+  }
 
-    if (pitch > 0)
-      offset += (ras.target.rows-1)*pitch;
 
-    return ( x >= 0 && x < ras.target.rows && (bits[0] & f1) );
+/***********************************************************************/
+/*                                                                     */
+/*  Horizontal Sweep Procedure Set :                                   */
+/*                                                                     */
+/*  These three 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);
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Horizontal_Set_Pixel                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets a single pixel in a bitmap during the horizontal sweep.  Used */
-  /*    during drop-out control.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y     :: The current pixel column.                                 */
-  /*    x     :: The current row/scanline.                                 */
-  /*    color :: Ignored by this function.                                 */
-  /*                                                                       */
-  static
-  void  Horizontal_Set_Pixel( RAS_ARG_ int  y,
-                                       int  x,
-                                       int  color )
+  static void  Horizontal_Sweep_Span( RAS_ARGS Short       y,
+                                               FT_F26Dot6  x1,
+                                               FT_F26Dot6  x2,
+                                               PProfile    left,
+                                               PProfile    right )
   {
-    char*  bits = (char*)ras.bit_buffer + (y >> 3);
-    int    f1   = (Byte)(0x80 >> (y  & 7));
+    Long  e1, e2;
+    PByte bits;
+    Byte  f1;
 
+    UNUSED(left);
+    UNUSED(right);
+    
+    if ( x2-x1 < ras.precision )
+    {
+      e1 = CEILING( x1 );
+      e2 = FLOOR  ( x2 );
 
-    UNUSED( color );
+      if ( e1 == e2 )
+      {
+        bits = ras.bTarget + (y >> 3);
+        f1   = (Byte)(0x80 >> (y  & 7));
 
-    if ( x >= 0 && x < ras.target.rows )
-    {
-      long pitch  = ras.target.pitch;
-      long offset = - x*pitch;
+        e1 = TRUNC( e1 );
 
-      if (pitch > 0)
-        offset += (ras.target.rows-1)*pitch;
+        if ( e1 >= 0 && e1 < ras.target.rows )
+        {
+          PByte  p;
 
-      bits[offset] |= f1;
+          p = bits - e1*ras.target.pitch;
+          if (ras.target.pitch > 0)
+            p += (ras.target.rows-1)*ras.target.pitch;
+         
+          p[0] |= f1;
+        }
+      }
     }
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Horizontal_Sweep_Step                                              */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Called whenever the sweep jumps to another pixel column.           */
-  /*                                                                       */
-  static
-  void  Horizontal_Sweep_Step( RAS_ARG )
+  static void  Horizontal_Sweep_Drop( RAS_ARGS Short       y,
+                                               FT_F26Dot6  x1,
+                                               FT_F26Dot6  x2,
+                                               PProfile    left,
+                                               PProfile    right )
   {
-    UNUSED( ras.target );
+    Long  e1, e2;
+    PByte bits;
+    Byte  f1;
 
-    /* Nothing, really */
-  }
 
+    /* During the horizontal sweep, we only take care of drop-outs */
 
-  static
-  const  Raster_Render   horizontal_render_mono =
-  {
-    &Horizontal_Sweep_Init,
-    &Horizontal_Sweep_Span,
-    &Horizontal_Sweep_Step,
-    &Horizontal_Test_Pixel,
-    &Horizontal_Set_Pixel
-  };
+    e1 = CEILING( x1 );
+    e2 = FLOOR  ( x2 );
 
+    if ( e1 > e2 )
+    {
+      if ( e1 == e2 + ras.precision )
+      {
+        switch ( ras.dropOutControl )
+        {
+        case 1:
+          e1 = e2;
+          break;
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /********                                                         ********/
-  /********      Anti-Aliased Vertical Bitmap Sweep Routines        ********/
-  /********                                                         ********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
+        case 4:
+          e1 = CEILING( (x1 + x2 + 1) / 2 );
+          break;
 
-#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+        case 2:
+        case 5:
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Gray_Sweep_Init                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes the vertical bitmap sweep.  Called by the generic      */
-  /*    sweep/draw routine before its loop.                                */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    min :: The address of the current minimum scanline.                */
-  /*    max :: The address of the current maximum scanline.                */
-  /*                                                                       */
-  static
-  void  Vertical_Gray_Sweep_Init( RAS_ARG_ int*  min, int*  max )
-  {
-    long  pitch;
+          /* Drop-out Control Rule #4 */
 
-    UNUSED( max );
+          /* 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'.    */
+          /*                                                        */
 
-    pitch = ras.target.pitch;
+          /* rightmost stub test */
 
-    /* start from the bottom line, going up */
-    ras.trace_incr = -pitch;
-    ras.trace_bit  = - *min * pitch;
+          if ( left->next == right && left->height <= 0 ) return;
 
-    if (pitch > 0)
-      ras.trace_bit += (ras.target.rows-1)*pitch;
-  }
+          /* leftmost stub test */
 
+          if ( right->next == left && left->start == y ) return;
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Gray_Sweep_Span                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Draws a single horizontal bitmap span during the vertical bitmap   */
-  /*    sweep.                                                             */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y  :: The current scanline.                                        */
-  /*    x1 :: The left span edge.                                          */
-  /*    x2 :: The right span edge.                                         */
-  /*                                                                       */
-  static
-  void  Vertical_Gray_Sweep_Span( RAS_ARG_ TScan  y,
-                                           TPos   x1,
-                                           TPos   x2 )
-  {
-    TPos   e1, e2;
-    int    shift = PRECISION_BITS - 6;
-    PByte  target;
+          /* check that the rightmost pixel isn't set */
 
-    UNUSED( y );
+          e1 = TRUNC( e1 );
 
-    x1 += PRECISION_HALF;
-    x2 += PRECISION_HALF;
+          bits = ras.bTarget + (y >> 3);
+          f1   = (Byte)(0x80 >> (y &  7));
 
-    e1 = TRUNC( x1 );
-    e2 = TRUNC( x2 );
+          bits -= e1*ras.target.pitch;
+          if (ras.target.pitch > 0)
+            bits += (ras.target.rows-1)*ras.target.pitch;
 
-    if ( e1 <= e2 && e2 >= 0 && e1 < ras.bit_width )
-    {
-      x1 = FRAC(x1) >> shift;
-      x2 = FRAC(x2) >> shift;
+          if ( e1 >= 0              &&
+               e1 < ras.target.rows &&
+               *bits & f1 )
+            return;
 
-      if ( e1 < 0 )
-      {
-        e1 = 0;
-        x1 = 0;
-      }
+          if ( ras.dropOutControl == 2 )
+            e1 = e2;
+          else
+            e1 = CEILING( (x1 + x2 + 1) / 2 );
 
-      if ( e2 > ras.bit_width )
-      {
-        e2 = ras.bit_width-1;
-        x2 = 0;
-      }
+          break;
 
-      target = ras.bit_buffer + ras.trace_bit + e1;
-      e2    -= e1;
-
-      if ( e2 > 0 )
-      {
-        if (x1 > 0) target[0] += (Byte)(64-x1) << 1;
-               else target[0]  = 127;
-        e2--;
-        while (e2 > 0)
-        {
-          *(++target) = 127;
-          e2--;
+        default:
+          return;  /* unsupported mode */
         }
-        if (x2)
-          target[1] += (Byte)x2 << 1;
       }
       else
-      {
-        target[0] += (Byte)(x2-x1) << 1;
-      }
+        return;
     }
-  }
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Gray_Test_Pixel                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Tests a pixel `light' during the vertical bitmap sweep.  Used      */
-  /*    during drop-out control only.                                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y :: The current scanline.                                         */
-  /*    x :: The current x coordinate.                                     */
-  /*                                                                       */
-  static
-  int  Vertical_Gray_Test_Pixel( RAS_ARG_ TScan  y,
-                                          int    x )
-  {
-    UNUSED_RASTER
-    UNUSED( y );
+    bits = ras.bTarget + (y >> 3);
+    f1   = (Byte)(0x80 >> (y  & 7));
 
-#if 0
-    /* as a rule of thumb, do not add a drop-out if the current */
-    /* gray level is over 0.5                                   */
+    e1 = TRUNC( e1 );
 
-    return ( x >= 0 && x < ras.bit_width &&
-             ras.bit_buffer[ras.trace_bit + x] >= 64 );
-#else
-    UNUSED(x);
-    return 0;
-#endif
-  }
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Gray_Set_Pixel                                            */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets a single pixel in a bitmap during the vertical sweep.  Used   */
-  /*    during drop-out control.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y     :: The current scanline.                                     */
-  /*    x     :: The current x coordinate.                                 */
-  /*    color :: Ignored by this function.                                 */
-  /*                                                                       */
-  static
-  void  Vertical_Gray_Set_Pixel( RAS_ARG_ int  y,
-                                          int  x,
-                                          int  color )
-  {
-    UNUSED( y );
-
-    if ( x >= 0 && x < ras.bit_width )
+    if ( e1 >= 0 && e1 < ras.target.rows )
     {
-      unsigned char*  pixel;
+      bits -= e1*ras.target.pitch;
+      if (ras.target.pitch > 0)
+        bits += (ras.target.rows-1)*ras.target.pitch;
 
-      pixel = ras.bit_buffer + ras.trace_bit + x;
-
-      /* do not add too much to the pixel gray level */
-      color += *pixel;
-      if (color < 64)
-        color = 64;
-
-      *pixel = ( color >= 127 ? 127 : (unsigned char)color );
+      bits[0] |= f1;
     }
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Vertical_Sweep_Step                                                */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Called whenever the sweep jumps to another scanline.  Only updates */
-  /*    the pointers in the vertical bitmap sweep.                         */
-  /*                                                                       */
-  static
-  void Vertical_Gray_Sweep_Step( RAS_ARG )
+  static void Horizontal_Sweep_Step( RAS_ARG )
   {
-    ras.trace_bit += ras.trace_incr;
+    /* Nothing, really */
+    UNUSED(raster);
   }
 
 
+#ifdef FT_RASTER_OPTION_ANTI_ALIASING
 
-  static
-  const  Raster_Render   vertical_render_gray =
-  {
-    &Vertical_Gray_Sweep_Init,
-    &Vertical_Gray_Sweep_Span,
-    &Vertical_Gray_Sweep_Step,
-    &Vertical_Gray_Test_Pixel,
-    &Vertical_Gray_Set_Pixel
-  };
+/***********************************************************************/
+/*                                                                     */
+/*  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.                                              */
+/*                                                                     */
+/***********************************************************************/
 
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /********                                                         ********/
-  /********           Horizontal Bitmap Sweep Routines              ********/
-  /********                                                         ********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Horizontal_Sweep_Init                                              */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes the horizontal bitmap sweep.  Called by the generic    */
-  /*    sweep/draw routine before its loop.                                */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    min :: The address of the current minimum pixel column.            */
-  /*    max :: The address of the current maximum pixel column.            */
-  /*                                                                       */
-  static
-  void  Horizontal_Gray_Sweep_Init( RAS_ARG_ int*  min,
-                                             int*  max )
+  static void  Vertical_Gray_Sweep_Init( RAS_ARGS Short*  min, Short*  max )
   {
-    UNUSED( ras );
-    UNUSED( min );
-    UNUSED( max );
+    Long  pitch, byte_len;
+    
+    *min = *min & -2;
+    *max = ( *max + 3 ) & -2;
 
-    /* nothing, really */
+    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;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Horizontal_Gray_Sweep_Span                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Draws a single vertical bitmap span during the horizontal bitmap   */
-  /*    sweep.                                                             */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y  :: The current scanline.                                        */
-  /*    x1 :: The left span edge.                                          */
-  /*    x2 :: The right span edge.                                         */
-  /*                                                                       */
-  static
-  void  Horizontal_Gray_Sweep_Span( RAS_ARG_ TScan  y,
-                                             TPos   x1,
-                                             TPos   x2 )
+  static void  Vertical_Gray_Sweep_Step( RAS_ARG )
   {
-    TPos   e1, e2;
-    int    shift = PRECISION_BITS - 6;
-    int    incr;
-    PByte  bits;
-    Byte   b;
+    Int    c1, c2;
+    PByte  pix, bit, bit2;
+    Int*   count = ras.count_table;
+    Byte*  grays;
 
-    UNUSED( y );
 
-    x1 += PRECISION_HALF;
-    x2 += PRECISION_HALF;
+    ras.traceOfs += ras.gray_width;
 
-    e1 = TRUNC( x1 );
-    e2 = TRUNC( x2 );
-
-    if ( e1 <= e2 && e2 >= 0 && e1 < ras.bit_width )
+    if ( ras.traceOfs > ras.gray_width )
     {
-      x1 = FRAC(x1) >> shift;
-      x2 = FRAC(x2) >> shift;
+      pix   = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
+      grays = ras.grays;
 
-      if ( e1 < 0 )
+      if ( ras.gray_max_x >= 0 )
       {
-        e1 = 0;
-        x1 = 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 ( e2 >= ras.bit_width )
-      {
-        e2 = ras.bit_width;
-        x2 = 0;
-      }
+        if ( ras.gray_min_x < 0 )
+          ras.gray_min_x = 0;
 
-      incr  = -ras.target.pitch;
-      bits  = ras.bit_buffer + y;
-      bits += incr * e1;
-      if (incr < 0)
-        bits -= incr*(ras.target.rows-1);
+        bit   = ras.bTarget + ras.gray_min_x;
+        bit2  = bit + ras.gray_width;
 
-      e2 -= e1;
+        c1 = ras.gray_max_x - ras.gray_min_x;
 
-      if ( e2 > 0 )
-      {
-        b = bits[0];
-        if (b < 127) b++;
-        b = (Byte)((64-x1) + (b >> 1));
-        bits[0] = b;
-
-        if ( e2 < 24 )
+        while ( c1 >= 0 )
         {
-          e2--;
-          while (e2 > 0)
+          c2 = count[*bit] + count[*bit2];
+
+          if ( c2 )
           {
-            bits += incr;
-            b     = bits[0];
+            pix[0] = grays[(c2 >> 12) & 0x000F];
+            pix[1] = grays[(c2 >> 8 ) & 0x000F];
+            pix[2] = grays[(c2 >> 4 ) & 0x000F];
+            pix[3] = grays[ c2        & 0x000F];
 
-            if (b < 127)
-              bits[0] = (Byte)(63+((b+1) >> 1));
-
-            e2--;
+            *bit  = 0;
+            *bit2 = 0;
           }
-        }
-        else
-          bits += incr*(e2-1);
 
-        if (x2)
+          bit ++;
+          bit2++;
+          pix += 4;
+          c1  --;
+        }
+        
+        if (over)
         {
-          bits += incr;
-          b     = bits[0];
-          if (b < 127) b++;
-          b     = (Byte)(x2 + (b >> 1));
-          bits[0] = b;
+          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;
+          }
         }
       }
-      else
-      {
-        b = bits[0];
-        if (b < 127) b++;
-        b = (Byte)((b >> 1)+(x2-x1));
-        bits[0] = b;
-      }
+
+      ras.traceOfs = 0;
+      ras.traceG  += ras.traceIncr;
+
+      ras.gray_min_x =  32000;
+      ras.gray_max_x = -32000;
     }
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Horizontal_Gray_Test_Pixel                                         */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Tests a pixel `light' during the horizontal bitmap sweep.  Used    */
-  /*    during drop-out control only.                                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y :: The current pixel column.                                     */
-  /*    x :: The current row/scanline.                                     */
-  /*                                                                       */
-  static
-  int   Horizontal_Gray_Test_Pixel( RAS_ARG_ int  y,
-                                             int  x )
+  static void  Horizontal_Gray_Sweep_Span( RAS_ARGS Short       y,
+                                                    FT_F26Dot6  x1,
+                                                    FT_F26Dot6  x2,
+                                                    PProfile    left,
+                                                    PProfile    right )
   {
-#if 0
-    unsigned char*  pixel = (unsigned char*)ras.bit_buffer + y;
-
-    if ( ras.target.flow == Flow_Down )
-      pixel += (ras.target.rows-1 - x) * ras.target.cols;
-    else
-      pixel += x * ras.target.cols;
-
-    return ( x >= 0 && x < ras.target.rows &&
-            *pixel >= 64 );
-#else
-    UNUSED_RASTER
+    /* nothing, really */
+    UNUSED(raster);
     UNUSED(y);
-    UNUSED(x);
-    return 0;
-#endif
+    UNUSED(x1);
+    UNUSED(x2);
+    UNUSED(left);
+    UNUSED(right);
   }
 
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Horizontal_Set_Pixel                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Sets a single pixel in a bitmap during the horizontal sweep.  Used */
-  /*    during drop-out control.                                           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    y     :: The current pixel column.                                 */
-  /*    x     :: The current row/scanline.                                 */
-  /*    color :: Ignored by this function.                                 */
-  /*                                                                       */
-  static
-  void  Horizontal_Gray_Set_Pixel( RAS_ARG_ int  y,
-                                            int  x,
-                                            int  color )
+  static void  Horizontal_Gray_Sweep_Drop( RAS_ARGS Short       y,
+                                                    FT_F26Dot6  x1,
+                                                    FT_F26Dot6  x2,
+                                                    PProfile    left,
+                                                    PProfile    right )
   {
-    unsigned char*  pixel = (unsigned char*)ras.bit_buffer + y;
+    Long  e1, e2;
+    PByte pixel;
+    Byte  color;
 
-    if ( x >= 0 && x < ras.target.rows )
+
+    /* During the horizontal sweep, we only take care of drop-outs */
+    e1 = CEILING( x1 );
+    e2 = FLOOR  ( x2 );
+
+    if ( e1 > e2 )
     {
-      long  pitch  = ras.target.pitch;
+      if ( e1 == e2 + ras.precision )
+      {
+        switch ( ras.dropOutControl )
+        {
+        case 1:
+          e1 = e2;
+          break;
 
-      pixel -= pitch*x;
-      if (pitch > 0)
-        pixel += pitch*(ras.target.rows-1);
+        case 4:
+          e1 = CEILING( (x1 + x2 + 1) / 2 );
+          break;
 
-      color += *pixel;
-      if (color < 64)
-        color = 64;
+        case 2:
+        case 5:
 
-      *pixel = (color >= 127 ? 127 : (unsigned char)color );
-    }
-  }
+          /* 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'.    */
+          /*                                                        */
 
-  static
-  void Gray_Ignore( void )
-  {
-    ;
-  }
+          /* rightmost stub test */
+          if ( left->next == right && left->height <= 0 ) return;
 
+          /* leftmost stub test */
+          if ( right->next == left && left->start == y ) return;
 
-  static
-  const  Raster_Render   horizontal_render_gray =
-  {
-    &Horizontal_Gray_Sweep_Init,
-    &Horizontal_Gray_Sweep_Span,
+          if ( ras.dropOutControl == 2 )
+            e1 = e2;
+          else
+            e1 = CEILING( (x1 + x2 + 1) / 2 );
 
-    (Function_Sweep_Step)  &Gray_Ignore,
-    &Horizontal_Gray_Test_Pixel,
-    &Horizontal_Gray_Set_Pixel,
-  };
+          break;
 
-#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+        default:
+          return;  /* unsupported mode */
+        }
+      }
+      else
+        return;
+    }
 
+    if ( e1 >= 0 )
+    {
+      if ( x2 - x1 >= ras.precision_half )
+        color = ras.grays[2];
+      else
+        color = ras.grays[1];
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* A technical note to explain how the scanline sweep is performed:      */
-  /*                                                                       */
-  /*   The function Draw_Sweep() is used to sweep the scanlines of the     */
-  /*   target bitmap or pixmap.  For each scanline, it must do the         */
-  /*   following:                                                          */
-  /*                                                                       */
-  /*   - Get the set of all outline intersections for the current          */
-  /*     scanline.                                                         */
-  /*                                                                       */
-  /*   - Sort these intersections (in increasing order).                   */
-  /*                                                                       */
-  /*   - Pair intersections to create spans (horizontal pixel segments)    */
-  /*     that are then `drawn' by calling a `sweep_span' function.         */
-  /*                                                                       */
-  /*   - Check for dropouts: If a span is too small to be drawn, it must   */
-  /*     be re-adjusted in order to make it visible again.                 */
-  /*                                                                       */
-  /*   The sweep starts from the bottom of the outline (ymin) and goes     */
-  /*   upwards (to ymax).  Thus, the function manages the following:       */
-  /*                                                                       */
-  /*   - A linked list of the profiles which are above the current         */
-  /*     scanline.  It is called the `wait' list as it contains all the    */
-  /*     profiles waiting to be `activated' during the sweep.  It contains */
-  /*     all profiles initially.                                           */
-  /*                                                                       */
-  /*   - A linked list of the profiles covering the current scanline,      */
-  /*     i.e., all the profiles that contain an intersection for the       */
-  /*     current scanline.  It is called the `draw' list.                  */
-  /*                                                                       */
-  /*   A profile travels from the wait list to the draw list if the        */
-  /*   current scanline reaches its bottom border (its ymin).  It is also  */
-  /*   removed from the draw list (and becomes unlisted) when the current  */
-  /*   scanline reaches the scanline above its upper border (its ymax).    */
-  /*                                                                       */
-  /*   These positions correspond to the `extrema' table built by          */
-  /*   Finalize_Profile_Table().                                           */
-  /*                                                                       */
-  /*   The draw list is always sorted in increasing order of the X         */
-  /*   coordinates.  We use a bubble sort because it is easy to implement  */
-  /*   on a linked list, and because in 95% cases, the list is already     */
-  /*   correctly sorted when going from one scanline to the other.         */
-  /*                                                                       */
-  /*   The extrema table gives the scanline coordinates at which at least  */
-  /*   one profile must be removed from the `draw' list, or another one    */
-  /*   must be moved from the `wait' to `draw' lists.                      */
-  /*                                                                       */
-  /*   Note that when a dropout is detected, the corresponding span is not */
-  /*   drawn immediately but kept on a temporary list.  All dropout spans  */
-  /*   are drawn after the regular spans on a given scanline.  This is a   */
-  /*   requirement of the TrueType specification to properly implement     */
-  /*   some drop-out control modes -- yes, it's weird!                     */
-  /*                                                                       */
-  /*   Finally, the parser contains four function pointers that are called */
-  /*   by Draw_Sweep().  Each rendering mode (monochrome, anti-aliased-5,  */
-  /*   and anti-aliased-17) provide its own set of such functions.  These  */
-  /*   are:                                                                */
-  /*                                                                       */
-  /*     sweep_init:       Called only when the sweep starts.  Used to set */
-  /*                       up some variables.                              */
-  /*                                                                       */
-  /*     sweep_span:       Used to draw a horizontal span on the current   */
-  /*                       scanline.                                       */
-  /*                                                                       */
-  /*     sweep_test_pixel: Used to test a pixel's intensity, as it is      */
-  /*                       required for drop-out control.                  */
-  /*                                                                       */
-  /*     sweep_put_pixel:  Used to write a single pixel when a drop-out    */
-  /*                       needs to be lighted/drawn.                      */
-  /*                                                                       */
-  /*************************************************************************/
+      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;
+      }
+    }
+  }
 
-  /*************************************************************************/
-  /*                                                                       */
-  /*  Generic Sweep Drawing routine                                        */
-  /*                                                                       */
-  static
-  TResult  Draw_Sweep( RAS_ARG )
+#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
+
+
+/********************************************************************/
+/*                                                                  */
+/*  Generic Sweep Drawing routine                                   */
+/*                                                                  */
+/********************************************************************/
+
+  static Bool  Draw_Sweep( RAS_ARG )
   {
-    TScan  y, y_change, y_height;
+    Short  y, y_change, y_height;
 
     PProfile  P, Q, P_Left, P_Right;
 
-    TScan   min_Y, max_Y, top, bottom, dropouts;
+    Short  min_Y, max_Y, top, bottom, dropouts;
 
-    TPos x1, x2, e1, e2;
+    Long  x1, x2, xs, e1, e2;
 
     TProfileList  wait;
-    TProfileList  draw;
+    TProfileList  draw_left, draw_right;
 
-    #ifdef DEBUG_RAS
-    int   y_set = 0;
-    #endif
 
     /* Init empty linked lists */
+
     Init_Linked( &wait );
-    Init_Linked( &draw );
 
-    /* first, compute min and max Y -- and add profiles to the wait list */
-    P     = ras.start_prof;
-    max_Y = TRUNC( ras.minY );
-    min_Y = TRUNC( ras.maxY );
+    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 = P->start;
-      top    = P->start + P->height-1;
+      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;
@@ -3411,20 +2442,21 @@
       P = Q;
     }
 
-    /* Check the extrema table */
-    if ( ras.n_extrema == 0 )
+    /* Check the Y-turns */
+    if ( ras.numTurns == 0 )
     {
-      ras.error = ErrRaster_Invalid_Outline;
+      ras.error = Raster_Err_Invalid;
       return FAILURE;
     }
 
     /* Now inits the sweep */
-    FT_TRACE2(( "draw_sweep: initialize sweep\n" ));
-    ras.render.init( RAS_VAR_  &min_Y, &max_Y );
-    FT_TRACE2(( "  init min_y = %d, max_y = %d\n", min_Y, max_Y ));
 
+    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;
@@ -3432,490 +2464,429 @@
     }
 
     /* Let's go */
+
     y        = min_Y;
     y_height = 0;
 
-    if ( ras.n_extrema > 0 &&
-         ras.pool_size[-ras.n_extrema] == min_Y )
-      ras.n_extrema--;
+    if ( ras.numTurns > 0 &&
+         ras.sizeBuff[-ras.numTurns] == min_Y )
+      ras.numTurns--;
 
-    FT_TRACE2(( "starting loop with n_extrema = %d", ras.n_extrema ));
-    while ( ras.n_extrema > 0 )
+    while ( ras.numTurns > 0 )
     {
-      PProfile  prof = wait;
+      /* look in the wait list for new activations */
 
+      P = wait;
 
-      /* look in the wait list for new activations */
-      while ( prof )
+      while ( P )
       {
-        PProfile  next = prof->link;
-
-        prof->countL -= y_height;
-        if ( prof->countL == 0 )
+        Q = P->link;
+        P->countL -= y_height;
+        if ( P->countL == 0 )
         {
-          /* move the profile from the wait list to the draw list */
-          DelOld( &wait, prof );
-          InsNew( &draw, prof );
+          DelOld( &wait, P );
+
+          switch ( P->flow )
+          {
+            case Flow_Up:    InsNew( &draw_left,  P ); break;
+            case Flow_Down:  InsNew( &draw_right, P ); break;
+          }
         }
-        prof = next;
+
+        P = Q;
       }
 
-      /* Sort the draw list */
-      Sort( &draw );
+      /* Sort the drawing lists */
 
-      /* compute next y extremum scanline; we won't change the */
-      /* elements of the wait and draw lists until there       */
-      y_change = ras.pool_size[-ras.n_extrema--];
+      Sort( &draw_left );
+      Sort( &draw_right );
+
+      y_change = (Short)ras.sizeBuff[-ras.numTurns--];
       y_height = y_change - y;
 
-      FT_TRACE2(( ">>> y = %d, y_change = %d, y_height = %d",
-                y, y_change, y_height ));
-
       while ( y < y_change )
       {
-        int       window;
-        PProfile  left;
 
-
         /* Let's trace */
+
         dropouts = 0;
 
-        /* skip to next line if there is no active profile there */
-        if ( !draw ) goto Next_Line;
+        P_Left  = draw_left;
+        P_Right = draw_right;
 
-        left   = draw;
-        window = left->flow;
-        prof   = left->link;
-
-        FT_TRACE2(( ">>>  line y = %d", y ));
-
-        while ( prof )
+        while ( P_Left )
         {
-          PProfile  next = prof->link;
+          x1 = P_Left ->X;
+          x2 = P_Right->X;
 
-          window += prof->flow;
+          if ( x1 > x2 )
+          {
+            xs = x1;
+            x1 = x2;
+            x2 = xs;
+          }
 
-          if ( window == 0 )
+          if ( x2-x1 <= ras.precision )
           {
-            x1 = left->X;
-            x2 = prof->X;
+            e1 = FLOOR( x1 );
+            e2 = CEILING( x2 );
 
-            if ( x1 > x2 )
+            if ( ras.dropOutControl != 0 &&
+                 (e1 > e2 || e2 == e1 + ras.precision) )
             {
-              TPos  xs = x1;
+              /* a drop out was detected */
 
-              x1 = x2;
-              x2 = xs;
-            }
+              P_Left ->X = x1;
+              P_Right->X = x2;
 
-            if ( x2 - x1 <= PRECISION && ras.dropout_mode )
-            {
-              e1 = CEILING( x1 );
-              e2 = FLOOR( x2 );
+              /* mark profile for drop-out processing */
+              P_Left->countL = 1;
+              dropouts++;
 
-              if ( e1 > e2 || e2 == e1 + PRECISION )
-              {
-                /* a drop out was detected */
-                left->X = x1;
-                prof->X = x2;
-
-                /* mark profiles for drop-out processing */
-                left->countL = 1;
-                prof->countL = 2;
-                dropouts++;
-                goto Skip_To_Next;
-              }
+              goto Skip_To_Next;
             }
+          }
 
-            FT_TRACE2(( "drawing span ( y=%d, x1=%d, x2=%d )", y, x1, x2 ));
-            #ifdef DEBUG_RAS
-            if (!y_set)
-            {
-              y_set = 1;
-              fprintf( stderr, "%3d", y );
-            }
-            fprintf( stderr, " [%.2f-%.2f]", x1*1.0/PRECISION, x2*1.0/PRECISION );
-            #endif
-            ras.render.span( RAS_VAR_  y, x1, x2 );
+          ras.Proc_Sweep_Span( RAS_VARS  y, x1, x2, P_Left, P_Right );
 
    Skip_To_Next:
-            left = next;
-          }
-          prof = 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 )
+        if (dropouts > 0)
           goto Scan_DropOuts;
 
    Next_Line:
-        ras.render.step( RAS_VAR );
 
+        ras.Proc_Sweep_Step( RAS_VAR );
+
         y++;
-        #ifdef DEBUG_RAS
-        if (y_set)
+
+        if ( y < y_change )
         {
-          fprintf( stderr, "\n" );
-          y_set = 0;
+          Sort( &draw_left  );
+          Sort( &draw_right );
         }
-        #endif
 
-        if ( y < y_change )
-          Sort( &draw );
-
-        FT_TRACE4(( "line sorted for next operation" ));
       }
 
       /* Now finalize the profiles that needs it */
 
-      FT_TRACE2(( "finalizing profiles..." ));
       {
-        PProfile  prof, next;
-
-        prof = draw;
-        while ( prof )
+        PProfile  Q, P;
+        P = draw_left;
+        while ( P )
         {
-          next = prof->link;
-          if (prof->height == 0)
-            DelOld( &draw, prof );
-          prof = next;
+          Q = P->link;
+          if ( P->height == 0 )
+            DelOld( &draw_left, P );
+          P = Q;
         }
       }
 
-      FT_TRACE2(( "profiles finalized for this run" ));
+      {
+        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.render.step( RAS_VAR );
+      ras.Proc_Sweep_Step( RAS_VAR );
       y++;
     }
 
     return SUCCESS;
 
-
 Scan_DropOuts :
-    P_Left = draw;
 
+    P_Left  = draw_left;
+    P_Right = draw_right;
 
-    while ( dropouts > 0 )
+    while ( P_Left )
     {
-      TPos      e1,   e2;
-      PProfile  left, right;
-
-      while ( P_Left->countL != 1 )
-        P_Left = P_Left->link;
-      P_Right = P_Left->link;
-      while ( P_Right->countL != 2 )
-        P_Right = P_Right->link;
-
-      P_Left->countL  = 0;
-      P_Right->countL = 0;
-
-      /* Now perform the dropout control */
-      x1 = P_Left->X;
-      x2 = P_Right->X;
-
-      left  = ( ras.flipped ? P_Right : P_Left  );
-      right = ( ras.flipped ? P_Left  : P_Right );
-
-      FT_TRACE2(( "performing drop-out control ( x1= %d, x2 = %d )",
-                x1, x2 ));
-
-      #ifdef DEBUG_RAS
-      if (!y_set)
+      if ( P_Left->countL )
       {
-        y_set = 1;
-        fprintf( stderr, "%3d", y );
+        P_Left->countL = 0;
+        /* dropouts--;    -- this is useful when debugging only */
+        ras.Proc_Sweep_Drop( RAS_VARS  y,
+                                       P_Left->X,
+                                       P_Right->X,
+                                       P_Left,
+                                       P_Right );
       }
-      fprintf( stderr, " <%.2f-%.2f>", P_Left->X*1.0/PRECISION, P_Right->X*1.0/PRECISION );
-      #endif
-      
-      e1 = CEILING( x1 );
-      e2 = FLOOR  ( x2 );
 
-      if ( e1 > e2 )
-      {
-        if ( e1 == e2 + PRECISION )
-        {
-          switch ( ras.dropout_mode )
-          {
-          case 1:
-            e1 = e2;
-            break;
-
-          case 4:
-            e1 = CEILING( (x1 + x2 + 1) / 2 );
-            break;
-
-          case 2:
-          case 5:
-            /* Drop-out Control Rule #4 */
-
-            /* The spec is not very clear regarding rule #4.  It      */
-            /* presents a method that is way too costly to implement  */
-            /* while the general idea seems to get rid of `stubs'.    */
-            /*                                                        */
-            /* Here, we only get rid of stubs recognized when:        */
-            /*                                                        */
-            /*  upper stub:                                           */
-            /*                                                        */
-            /*   - P_Left and P_Right are in the same contour         */
-            /*   - P_Right is the successor of P_Left in that contour */
-            /*   - y is the top of P_Left and P_Right                 */
-            /*                                                        */
-            /*  lower stub:                                           */
-            /*                                                        */
-            /*   - P_Left and P_Right are in the same contour         */
-            /*   - P_Left is the successor of P_Right in that contour */
-            /*   - y is the bottom of P_Left                          */
-            /*                                                        */
-
-            /* upper stub test */
-            if ( ( left->next == right && left->height <= 0 ) ||
-
-            /* lower stub test */
-                 ( right->next == left && left->start == y )  ||
-
-            /* check that the rightmost pixel isn't set */
-                 ras.render.test_pixel( RAS_VAR_  y, TRUNC(e1))       )
-              goto Next_Dropout;
-
-            if ( ras.dropout_mode == 2 )
-              e1 = e2;
-            else
-              e1 = CEILING( (x1 + x2 + 1)/2 );
-
-            break;
-
-          default:
-            goto Next_Dropout;  /* Unsupported mode */
-          }
-        }
-        else
-          goto Next_Dropout;
-      }
-
-      FT_TRACE2(( "  -> setting pixel" ));
-      ras.render.set_pixel( RAS_VAR_ y,
-                            TRUNC( e1 ),
-                            (x2 - x1) >> ras.scale_shift );
-    Next_Dropout:
-
-      dropouts--;
+      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 :: whether or not we have to flip.                         */
-  /*                                                                       */
-  /* <Returns>                                                             */
-  /*    Error code.  0 means success.                                      */
-  /*                                                                       */
-  static
-  int  Render_Single_Pass( RAS_ARG_ int  flipped )
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Render_Single_Pass                                          */
+/*                                                                          */
+/* Description: Performs one sweep with sub-banding.                        */
+/*                                                                          */
+/* Input:       _XCoord, _YCoord : x and y coordinates arrays               */
+/*                                                                          */
+/* Returns:     SUCCESS on success                                          */
+/*              FAILURE if any error was encountered during render.         */
+/*                                                                          */
+/****************************************************************************/
+
+  static FT_Error  Render_Single_Pass( RAS_ARGS Bool  flipped )
   {
-    TBand*  band;
+    Short  i, j, k;
 
 
-    ras.flipped = flipped;
-
-    band = ras.band_stack;
-
-    FT_TRACE2(( "raster: entering render_single_pass (flipped = %d)\n",
-              flipped ));
-
-    while ( band >= ras.band_stack )
+    while ( ras.band_top >= 0 )
     {
-      ras.maxY = ((long)band[0].y_max << PRECISION_BITS) - 1;
-      ras.minY =  (long)band[0].y_min << PRECISION_BITS;
+      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.cursor = ras.pool;
-      ras.error  = 0;
+      ras.top = ras.buff;
 
-      FT_TRACE2(( "raster: band = [ %d, %d ]\n",
-                band[0].y_min,
-                band[0].y_max ));
+      ras.error = Raster_Err_None;
 
-      if ( Convert_Glyph( RAS_VAR_  ras.outline ) )
+      if ( Convert_Glyph( RAS_VARS  flipped ) )
       {
-        int  bottom, top, half;
+        if ( ras.error != Raster_Err_Overflow ) return FAILURE;
 
+        ras.error = Raster_Err_None;
 
-        if ( ras.error != ErrRaster_Overflow )
-          return FAILURE;
-        ras.error = ErrRaster_Ok;
-
-        FT_TRACE2(( "conversion failure, performing sub-banding\n" ));
-
         /* sub-banding */
 
-#ifdef DEBUG_RASTER
-        ClearBand( RAS_VAR_  TRUNC( ras.minY ), TRUNC( ras.maxY ) );
-#endif
+        #ifdef DEBUG_RASTER
+        ClearBand( RAS_VARS  TRUNC( ras.minY ), TRUNC( ras.maxY ) );
+        #endif
 
-        bottom = band[0].y_min;
-        top    = band[0].y_max;
-        half   = ( top - bottom ) >> 1;
+        i = ras.band_stack[ras.band_top].y_min;
+        j = ras.band_stack[ras.band_top].y_max;
 
-        if ( band >= ras.band_stack + 7 || half == 0 )
+        k = ( i + j ) / 2;
+
+        if ( ras.band_top >= 7 || k < i )
         {
-          ras.band_top = 0;
-          ras.error    = ErrRaster_Invalid_Outline;
+          ras.band_top     = 0;
+          ras.error = Raster_Err_Invalid;
           return ras.error;
         }
 
-        band[1].y_min = bottom + half;
-        band[1].y_max = top;
-        band[0].y_max = bottom + half;
+        ras.band_stack[ras.band_top+1].y_min = k;
+        ras.band_stack[ras.band_top+1].y_max = j;
 
-        band ++;
+        ras.band_stack[ras.band_top].y_max = k - 1;
+
+        ras.band_top++;
       }
       else
       {
-        FT_TRACE2(( "conversion succeeded, span drawing sweep\n" ));
-#if 1  /* for debugging */
-        if ( ras.start_prof )
-          if ( Draw_Sweep( RAS_VAR ) )
-            return ras.error;
-#endif
-        band --;
+        if ( ras.fProfile )
+          if ( Draw_Sweep( RAS_VAR ) ) return ras.error;
+        ras.band_top--;
       }
     }
 
-    FT_TRACE2(( "raster: exiting render_single_pass\n" ));
-
-    return SUCCESS;  /* success */
+    return FT_Err_Ok;
   }
 
 
-  static
-  int  Raster_Render1( FT_Raster  raster )
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Render_Glyph                                                */
+/*                                                                          */
+/* Description: Renders a glyph in a bitmap.  Sub-banding if needed.        */
+/*                                                                          */
+/* Input:       AGlyph   Glyph record                                       */
+/*                                                                          */
+/* Returns:     SUCCESS on success.                                         */
+/*              FAILURE if any error was encountered during rendering.      */
+/*                                                                          */
+/****************************************************************************/
+
+  LOCAL_FUNC
+  FT_Error  Render_Glyph( RAS_ARG )
   {
-    int  error;
+    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);
 
-    if ( ras.target.width > ABS(ras.target.pitch)*8 )
-      return ErrRaster_Invalid_Map;
 
-    ras.scale_shift  = PRECISION_BITS - INPUT_BITS;
-    ras.scale_delta  = PRECISION_HALF;
-
     /* 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;
+    ras.band_stack[0].y_max = ras.target.rows - 1;
 
-    ras.render     = vertical_render_mono;
-    ras.bit_width  = ras.target.width;
-    ras.bit_buffer = (unsigned char*)ras.target.buffer;
+    ras.bWidth  = ras.target.width;
+    ras.bTarget = (Byte*)ras.target.buffer;
 
-    if ( (error = Render_Single_Pass( RAS_VAR_ 0 )) != 0 )
+    if ( (error = Render_Single_Pass( RAS_VARS 0 )) != 0 )
       return error;
 
     /* Horizontal Sweep */
-
-    if ( ras.second_pass && ras.dropout_mode != 0 )
+    if ( ras.second_pass && ras.dropOutControl != 0 )
     {
-      ras.render              = horizontal_render_mono;
+      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;
+      ras.band_stack[0].y_max = ras.target.width - 1;
 
-      if ( (error = Render_Single_Pass( RAS_VAR_  1 )) != 0 )
+      if ( (error = Render_Single_Pass( RAS_VARS  1 )) != 0 )
         return error;
     }
 
-    return ErrRaster_Ok;
+    return FT_Err_Ok;
   }
 
 
-#ifdef FT_RASTER_OPTION_ANTI_ALIAS
+/****************************************************************************/
+/*                                                                          */
+/* Function:    Render_Gray_Glyph                                           */
+/*                                                                          */
+/* Description: Renders a glyph with grayscaling. Sub-banding if needed.    */
+/*                                                                          */
+/* Input:       AGlyph   Glyph record                                       */
+/*                                                                          */
+/* Returns:     SUCCESS on success                                          */
+/*              FAILURE if any error was encountered during rendering.      */
+/*                                                                          */
+/****************************************************************************/
 
-
-  static
-  int  Raster_Render8( FT_Raster  raster )
+#ifdef FT_RASTER_OPTION_ANTI_ALIASING
+  LOCAL_FUNC
+  FT_Error  Render_Gray_Glyph( RAS_ARG )
   {
-    int  error;
+    Long      pixel_width;
+    FT_Error  error;
 
-    if ( ras.target.width > ABS(ras.target.pitch) )
-      return ErrRaster_Invalid_Map;
+    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 = ras.target.rows;
+    ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
 
-    ras.scale_shift  = PRECISION_BITS - INPUT_BITS;
-    ras.scale_delta  = PRECISION_HALF;
-    ras.dropout_mode = 2;
+    ras.bWidth  = ras.gray_width;
+    pixel_width = 2*((ras.target.width + 3) >> 2);
+      
+    if ( ras.bWidth > pixel_width )
+      ras.bWidth = pixel_width;
 
-    ras.render     = vertical_render_gray;
-    ras.bit_width  = ras.target.width;
-    ras.bit_buffer = (unsigned char*)ras.target.buffer;
-    ras.pix_buffer = (unsigned char*)ras.target.buffer;
+    ras.bWidth  = ras.bWidth * 8;
+    ras.bTarget = (Byte*)ras.gray_lines;
+    ras.gTarget = (Byte*)ras.target.buffer;
 
-    error = Render_Single_Pass( RAS_VAR_  0 );
-    if ( error )
+    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;
 
-#if 1
     /* Horizontal Sweep */
-    ras.render              = horizontal_render_gray;
-    ras.band_top            = 0;
-    ras.bit_width           = ras.target.rows;
-    ras.band_stack[0].y_min = 0;
-    ras.band_stack[0].y_max = ras.target.width;
+    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;
 
-    return Render_Single_Pass( RAS_VAR_  1 );
-#else
-    return 0;
-#endif
-  }
+      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;
+    }
 
-#else  /* FT_RASTER_OPTION_ANTI_ALIAS */
-
-
-  static
-  int  Raster_Render8( FT_Raster  raster )
+    return FT_Err_Ok;
+  }
+#else
+  LOCAL_FUNC
+  FT_Error  Render_Gray_Glyph( RAS_ARG )
   {
-    return ErrRaster_Unimplemented;
+    UNUSED_RASTER
+    return Raster_Err_Unsupported;
   }
+#endif
 
 
-#endif /* FT_RASTER_OPTION_ANTI_ALIAS */
+  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*127/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_raster_new( void*  memory, FT_Raster *araster )
+  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_raster_done( FT_Raster  raster )
+  void  ft_black_done( FT_Raster  raster )
   {
     /* nothing */
     raster->init = 0;
@@ -3926,15 +2897,17 @@
 #include <freetype/internal/ftobjs.h>
 
   static
-  int  ft_raster_new( FT_Memory  memory, FT_Raster*  araster )
+  int  ft_black_new( FT_Memory  memory, TRaster_Instance*  *araster )
   {
-    FT_Error  error;
-    FT_Raster raster;
+    FT_Error           error;
+    TRaster_Instance*  raster;
     
     *araster = 0;
     if ( !ALLOC( raster, sizeof(*raster) ))
     {
       raster->memory = memory;
+      ft_black_init( raster );
+
       *araster = raster;
     }
       
@@ -3942,7 +2915,7 @@
   }
   
   static
-  void ft_raster_done( FT_Raster  raster )
+  void ft_black_done( TRaster_Instance*  raster )
   {
     FT_Memory  memory = (FT_Memory)raster->memory;
     FREE( raster );
@@ -3951,60 +2924,67 @@
 #endif
 
 
-  static void ft_raster_reset( FT_Raster   raster,
-                               const char* pool_base,
-                               long        pool_size )
+  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->pool      = (PPos)pool_base;
-      raster->pool_size = raster->pool + pool_size / sizeof ( TPos );
+      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_raster_render( FT_Raster          raster,
-                         FT_Raster_Params*  params )
+  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->pool || !raster->pool_size )
-      return ErrRaster_Uninitialized_Object;
+    if ( !raster || !raster->buff || !raster->sizeBuff )
+      return Raster_Err_Not_Ini;
 
     if ( !outline || !outline->contours || !outline->points )
-      return ErrRaster_Invalid_Outline;
+      return Raster_Err_Invalid;
 
     /* return immediately if the outline is empty */
     if ( outline->n_points == 0 || outline->n_contours <= 0 )
-      return ErrRaster_Ok;
+      return Raster_Err_None;
 
     if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 )
-      return ErrRaster_Invalid_Outline;
+      return Raster_Err_Invalid;
 
     if ( !target_map || !target_map->buffer )
-      return ErrRaster_Invalid_Map;
+      return Raster_Err_Invalid;
 
-    ras.outline  = outline;
-    ras.target   = *target_map;
-    
-    /* Note that we always use drop-out mode 2, because it seems that */
-    /* it's the only way to do to get results consistent with Windows */
-    /* rendering..                                                    */
-    ras.dropout_mode = 2;
-
-    ras.second_pass  = (outline->flags & ft_outline_single_pass) == 0;
-    SET_High_Precision( (char)((outline->flags & ft_outline_high_precision)!= 0) );
-
     /* this version of the raster does not support direct rendering, sorry */
     if ( params->flags & ft_raster_flag_direct )
-      return ErrRaster_Unimplemented;
+      return Raster_Err_Unsupported;
 
-    return ( params->flags & ft_raster_flag_aa
-           ? Raster_Render8( raster )
-           : Raster_Render1( raster ) );
+    ras.outline  = *outline;
+    ras.target   = *target_map;
+    
+    return ( params->flags & ft_raster_flag_aa 
+           ? Render_Gray_Glyph( raster )
+           : Render_Glyph( raster ) );
   }
 
 
@@ -4011,11 +2991,11 @@
   FT_Raster_Funcs      ft_default_raster =
   {
     ft_glyph_format_outline,
-    (FT_Raster_New_Func)       ft_raster_new,
-    (FT_Raster_Reset_Func)     ft_raster_reset,
-    (FT_Raster_Set_Mode_Func)  0,
-    (FT_Raster_Render_Func)    ft_raster_render,
-    (FT_Raster_Done_Func)      ft_raster_done
+    (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
   };