Update to FreeType 2.3.12
diff --git a/Android.mk b/Android.mk
index ee6f253..12c0b6a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,10 +1,10 @@
 # this is now the default FreeType build for Android
 #
 ifndef USE_FREETYPE
-USE_FREETYPE := 2.3.9
+USE_FREETYPE := 2.3.12
 endif
 
-ifeq ($(USE_FREETYPE),2.3.9)
+ifeq ($(USE_FREETYPE),2.3.12)
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
diff --git a/include/freetype/config/ftconfig.h b/include/freetype/config/ftconfig.h
index 3c0b8b1..43d587e 100644
--- a/include/freetype/config/ftconfig.h
+++ b/include/freetype/config/ftconfig.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    ANSI-specific configuration file (specification only).               */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by             */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2010 by       */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -35,7 +35,6 @@
   /*                                                                       */
   /*************************************************************************/
 
-
 #ifndef __FTCONFIG_H__
 #define __FTCONFIG_H__
 
@@ -306,9 +305,38 @@
   /* Provide assembler fragments for performance-critical functions. */
   /* These must be defined `static __inline__' with GCC.             */
 
+#if defined( __CC_ARM ) || defined( __ARMCC__ )  /* RVCT */
+#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
+
+  /* documentation is in freetype.h */
+
+  static __inline FT_Int32
+  FT_MulFix_arm( FT_Int32  a,
+                 FT_Int32  b )
+  {
+    register FT_Int32  t, t2;
+
+
+    __asm
+    {
+      smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */
+      mov   a,  t,  asr #31         /* a   = (hi >> 31) */
+      add   a,  a,  #0x8000         /* a  += 0x8000 */
+      adds  t2, t2, a               /* t2 += a */
+      adc   t,  t,  #0              /* t  += carry */
+      mov   a,  t2, lsr #16         /* a   = t2 >> 16 */
+      orr   a,  a,  t,  lsl #16     /* a  |= t << 16 */
+    }
+    return a;
+  }
+
+#endif /* __CC_ARM || __ARMCC__ */
+
+
 #ifdef __GNUC__
 
-#if defined( __arm__ ) && !defined( __thumb__ )
+#if defined( __arm__ ) && !defined( __thumb__ )    && \
+    !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
 #define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
 
   /* documentation is in freetype.h */
@@ -333,7 +361,7 @@
     return a;
   }
 
-#endif /* __arm__ && !__thumb__ */
+#endif /* __arm__ && !__thumb__ && !( __CC_ARM || __ARMCC__ ) */
 
 #if defined( i386 )
 #define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h
index 597a2bb..0258e1b 100644
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    User-selectable configuration macros (specification only).           */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
+/*            2010 by                                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -85,9 +86,9 @@
   /*                                                                       */
   /* This macro has no impact on the FreeType API, only on its             */
   /* _implementation_.  For example, using FT_RENDER_MODE_LCD when calling */
-  /* FT_Render_Glyph still generates a bitmap that is 3 times larger than  */
-  /* the original size; the difference will be that each triplet of        */
-  /* subpixels has R=G=B.                                                  */
+  /* FT_Render_Glyph still generates a bitmap that is 3 times wider than   */
+  /* the original size in case this macro isn't defined; however, each     */
+  /* triplet of subpixels has R=G=B.                                       */
   /*                                                                       */
   /* This is done to allow FreeType clients to run unmodified, forcing     */
   /* them to display normal gray-level anti-aliased glyphs.                */
@@ -312,8 +313,9 @@
   /*                                                                       */
   /* Allow the use of FT_Incremental_Interface to load typefaces that      */
   /* contain no glyph data, but supply it via a callback function.         */
-  /* This allows FreeType to be used with the PostScript language, using   */
-  /* the GhostScript interpreter.                                          */
+  /* This is required by clients supporting document formats which         */
+  /* supply font data incrementally as the document is parsed, such        */
+  /* as the Ghostscript interpreter for the PostScript language.           */
   /*                                                                       */
 /* #define FT_CONFIG_OPTION_INCREMENTAL */
 
@@ -396,6 +398,20 @@
 #undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
 
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* Position Independent Code                                             */
+  /*                                                                       */
+  /*   If this macro is set (which is _not_ the default), FreeType2 will   */
+  /*   avoid creating constants that require address fixups.  Instead the  */
+  /*   constants will be moved into a struct and additional intialization  */
+  /*   code will be used.                                                  */
+  /*                                                                       */
+  /*   Setting this macro is needed for systems that prohibit address      */
+  /*   fixups, such as BREW.                                               */
+  /*                                                                       */
+/* #define FT_CONFIG_OPTION_PIC */
+
 
   /*************************************************************************/
   /*************************************************************************/
@@ -439,7 +455,7 @@
   /* does not contain any glyph name though.                               */
   /*                                                                       */
   /* Accessing SFNT names is done through the functions declared in        */
-  /* `freetype/ftnames.h'.                                                 */
+  /* `freetype/ftsnames.h'.                                                */
   /*                                                                       */
 #define TT_CONFIG_OPTION_SFNT_NAMES
 
@@ -457,6 +473,7 @@
 #define TT_CONFIG_CMAP_FORMAT_8
 #define TT_CONFIG_CMAP_FORMAT_10
 #define TT_CONFIG_CMAP_FORMAT_12
+#define TT_CONFIG_CMAP_FORMAT_13
 #define TT_CONFIG_CMAP_FORMAT_14
 
 
diff --git a/include/freetype/config/ftstdlib.h b/include/freetype/config/ftstdlib.h
index ce5557a..30ec14e 100644
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -61,6 +61,7 @@
 
 #define FT_CHAR_BIT   CHAR_BIT
 #define FT_INT_MAX    INT_MAX
+#define FT_INT_MIN    INT_MIN
 #define FT_UINT_MAX   UINT_MAX
 #define FT_ULONG_MAX  ULONG_MAX
 
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 364388b..942a740 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    FreeType high-level API and common types (specification only).       */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
+/*            2010 by                                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -231,6 +232,10 @@
   /*    vertAdvance ::                                                     */
   /*      Advance height for vertical layout.                              */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    If not disabled with @FT_LOAD_NO_HINTING, the values represent     */
+  /*    dimensions of the hinted glyph (in case hinting is applicable).    */
+  /*                                                                       */
   typedef struct  FT_Glyph_Metrics_
   {
     FT_Pos  width;
@@ -519,10 +524,7 @@
   /* <Note>                                                                */
   /*    Despite the name, this enumeration lists specific character        */
   /*    repertories (i.e., charsets), and not text encoding methods (e.g., */
-  /*    UTF-8, UTF-16, GB2312_EUC, etc.).                                  */
-  /*                                                                       */
-  /*    Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */
-  /*    all character codes must be expressed as FT_Longs.                 */
+  /*    UTF-8, UTF-16, etc.).                                              */
   /*                                                                       */
   /*    Other encodings might be defined in the future.                    */
   /*                                                                       */
@@ -536,6 +538,10 @@
   /*      Latin-1.  Most fonts include a Unicode charmap, but not all      */
   /*      of them.                                                         */
   /*                                                                       */
+  /*      For example, if you want to access Unicode value U+1F028 (and    */
+  /*      the font contains it), use value 0x1F028 as the input value for  */
+  /*      @FT_Get_Char_Index.                                              */
+  /*                                                                       */
   /*    FT_ENCODING_MS_SYMBOL ::                                           */
   /*      Corresponds to the Microsoft Symbol encoding, used to encode     */
   /*      mathematical symbols in the 32..255 character code range.  For   */
@@ -1476,8 +1482,13 @@
   /*                         important to perform correct WYSIWYG layout.  */
   /*                         Only relevant for outline glyphs.             */
   /*                                                                       */
-  /*    advance           :: This is the transformed advance width for the */
-  /*                         glyph (in 26.6 fractional pixel format).      */
+  /*    advance           :: This shorthand is, depending on               */
+  /*                         @FT_LOAD_IGNORE_TRANSFORM, the transformed    */
+  /*                         advance width for the glyph (in 26.6          */
+  /*                         fractional pixel format).  As specified with  */
+  /*                         @FT_LOAD_VERTICAL_LAYOUT, it uses either the  */
+  /*                         `horiAdvance' or the `vertAdvance' value of   */
+  /*                         `metrics' field.                              */
   /*                                                                       */
   /*    format            :: This field indicates the format of the image  */
   /*                         contained in the glyph slot.  Typically       */
@@ -1651,6 +1662,11 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    In case you want to provide your own memory allocating routines,   */
+  /*    use @FT_New_Library instead, followed by a call to                 */
+  /*    @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module).  */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Init_FreeType( FT_Library  *alibrary );
 
@@ -1737,7 +1753,8 @@
   /*    data :: A pointer to the parameter data.                           */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    The ID and function of parameters are driver-specific.             */
+  /*    The ID and function of parameters are driver-specific.  See the    */
+  /*    various FT_PARAM_TAG_XXX flags for more information.               */
   /*                                                                       */
   typedef struct  FT_Parameter_
   {
@@ -3757,7 +3774,7 @@
    */
 #define FREETYPE_MAJOR  2
 #define FREETYPE_MINOR  3
-#define FREETYPE_PATCH  9
+#define FREETYPE_PATCH  12
 
 
   /*************************************************************************/
diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h
index cacccf0..0b8f0c0 100644
--- a/include/freetype/ftglyph.h
+++ b/include/freetype/ftglyph.h
@@ -468,7 +468,7 @@
   /*        // convert to a bitmap (default render mode + destroying old)  */
   /*        if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )                 */
   /*        {                                                              */
-  /*          error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT,  */
+  /*          error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL,   */
   /*                                      0, 1 );                          */
   /*          if ( error ) // `glyph' unchanged                            */
   /*            ...                                                        */
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
index ccc2f71..0272e92 100644
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -5,7 +5,8 @@
 /*    FreeType glyph image formats and default raster interface            */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
+/*            2010 by                                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -51,10 +52,9 @@
   /*    FT_Pos                                                             */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    The type FT_Pos is a 32-bit integer used to store vectorial        */
-  /*    coordinates.  Depending on the context, these can represent        */
-  /*    distances in integer font units, or 16.16, or 26.6 fixed float     */
-  /*    pixel coordinates.                                                 */
+  /*    The type FT_Pos is used to store vectorial coordinates.  Depending */
+  /*    on the context, these can represent distances in integer font      */
+  /*    units, or 16.16, or 26.6 fixed float pixel coordinates.            */
   /*                                                                       */
   typedef signed long  FT_Pos;
 
@@ -99,6 +99,20 @@
   /*                                                                       */
   /*    yMax :: The vertical maximum (top-most).                           */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    The bounding box is specified with the coordinates of the lower    */
+  /*    left and the upper right corner.  In PostScript, those values are  */
+  /*    often called (llx,lly) and (urx,ury), respectively.                */
+  /*                                                                       */
+  /*    If `yMin' is negative, this value gives the glyph's descender.     */
+  /*    Otherwise, the glyph doesn't descend below the baseline.           */
+  /*    Similarly, if `ymax' is positive, this value gives the glyph's     */
+  /*    ascender.                                                          */
+  /*                                                                       */
+  /*    `xMin' gives the horizontal distance from the glyph's origin to    */
+  /*    the left edge of the glyph's bounding box.  If `xMin' is negative, */
+  /*    the glyph extends to the left of the origin.                       */
+  /*                                                                       */
   typedef struct  FT_BBox_
   {
     FT_Pos  xMin, yMin;
@@ -254,6 +268,9 @@
   /*                    flow.  In all cases, the pitch is an offset to add */
   /*                    to a bitmap pointer in order to go down one row.   */
   /*                                                                       */
+  /*                    For the B/W rasterizer, `pitch' is always an even  */
+  /*                    number.                                            */
+  /*                                                                       */
   /*    buffer       :: A typeless pointer to the bitmap buffer.  This     */
   /*                    value should be aligned on 32-bit boundaries in    */
   /*                    most cases.                                        */
@@ -318,14 +335,23 @@
   /*                  elements, giving the outline's point coordinates.    */
   /*                                                                       */
   /*    tags       :: A pointer to an array of `n_points' chars, giving    */
-  /*                  each outline point's type.  If bit~0 is unset, the   */
-  /*                  point is `off' the curve, i.e., a Bézier control     */
-  /*                  point, while it is `on' when set.                    */
+  /*                  each outline point's type.                           */
+  /*                                                                       */
+  /*                  If bit~0 is unset, the point is `off' the curve,     */
+  /*                  i.e., a Bézier control point, while it is `on' if    */
+  /*                  set.                                                 */
   /*                                                                       */
   /*                  Bit~1 is meaningful for `off' points only.  If set,  */
   /*                  it indicates a third-order Bézier arc control point; */
   /*                  and a second-order control point if unset.           */
   /*                                                                       */
+  /*                  If bit~2 is set, bits 5-7 contain the drop-out mode  */
+  /*                  (as defined in the OpenType specification; the value */
+  /*                  is the same as the argument to the SCANMODE          */
+  /*                  instruction).                                        */
+  /*                                                                       */
+  /*                  Bits 3 and~4 are reserved for internal purposes.     */
+  /*                                                                       */
   /*    contours   :: An array of `n_contours' shorts, giving the end      */
   /*                  point of each contour within the outline.  For       */
   /*                  example, the first contour is defined by the points  */
@@ -336,6 +362,12 @@
   /*                  and give hints to the scan-converter and hinter on   */
   /*                  how to convert/grid-fit it.  See @FT_OUTLINE_FLAGS.  */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    The B/W rasterizer only checks bit~2 in the `tags' array for the   */
+  /*    first point of each contour.  The drop-out mode as given with      */
+  /*    @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, and       */
+  /*    @FT_OUTLINE_INCLUDE_STUBS in `flags' is then overridden.           */
+  /*                                                                       */
   typedef struct  FT_Outline_
   {
     short       n_contours;      /* number of contours in glyph        */
@@ -349,6 +381,11 @@
 
   } FT_Outline;
 
+  /* Following limits must be consistent with */
+  /* FT_Outline.{n_contours,n_points}         */
+#define FT_OUTLINE_CONTOURS_MAX  SHRT_MAX
+#define FT_OUTLINE_POINTS_MAX    SHRT_MAX
+
 
   /*************************************************************************/
   /*                                                                       */
@@ -371,7 +408,7 @@
   /*    FT_OUTLINE_EVEN_ODD_FILL ::                                        */
   /*      By default, outlines are filled using the non-zero winding rule. */
   /*      If set to 1, the outline will be filled using the even-odd fill  */
-  /*      rule (only works with the smooth raster).                        */
+  /*      rule (only works with the smooth rasterizer).                    */
   /*                                                                       */
   /*    FT_OUTLINE_REVERSE_FILL ::                                         */
   /*      By default, outside contours of an outline are oriented in       */
@@ -384,15 +421,17 @@
   /*      By default, the scan converter will try to detect drop-outs in   */
   /*      an outline and correct the glyph bitmap to ensure consistent     */
   /*      shape continuity.  If set, this flag hints the scan-line         */
-  /*      converter to ignore such cases.                                  */
+  /*      converter to ignore such cases.  See below for more information. */
   /*                                                                       */
   /*    FT_OUTLINE_SMART_DROPOUTS ::                                       */
   /*      Select smart dropout control.  If unset, use simple dropout      */
-  /*      control.  Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.         */
+  /*      control.  Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See    */
+  /*      below for more information.                                      */
   /*                                                                       */
   /*    FT_OUTLINE_INCLUDE_STUBS ::                                        */
   /*      If set, turn pixels on for `stubs', otherwise exclude them.      */
-  /*      Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.                   */
+  /*      Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set.  See below for    */
+  /*      more information.                                                */
   /*                                                                       */
   /*    FT_OUTLINE_HIGH_PRECISION ::                                       */
   /*      This flag indicates that the scan-line converter should try to   */
@@ -409,6 +448,13 @@
   /*      scan-converter.                                                  */
   /*                                                                       */
   /* <Note>                                                                */
+  /*    The flags @FT_OUTLINE_IGNORE_DROPOUTS, @FT_OUTLINE_SMART_DROPOUTS, */
+  /*    and @FT_OUTLINE_INCLUDE_STUBS are ignored by the smooth            */
+  /*    rasterizer.                                                        */
+  /*                                                                       */
+  /*    There exists a second mechanism to pass the drop-out mode to the   */
+  /*    B/W rasterizer; see the `tags' field in @FT_Outline.               */
+  /*                                                                       */
   /*    Please refer to the description of the `SCANTYPE' instruction in   */
   /*    the OpenType specification (in file `ttinst1.doc') how simple      */
   /*    drop-outs, smart drop-outs, and stubs are defined.                 */
@@ -455,15 +501,17 @@
 
 #define FT_CURVE_TAG( flag )  ( flag & 3 )
 
-#define FT_CURVE_TAG_ON           1
-#define FT_CURVE_TAG_CONIC        0
-#define FT_CURVE_TAG_CUBIC        2
+#define FT_CURVE_TAG_ON            1
+#define FT_CURVE_TAG_CONIC         0
+#define FT_CURVE_TAG_CUBIC         2
 
-#define FT_CURVE_TAG_TOUCH_X      8  /* reserved for the TrueType hinter */
-#define FT_CURVE_TAG_TOUCH_Y     16  /* reserved for the TrueType hinter */
+#define FT_CURVE_TAG_HAS_SCANMODE  4
 
-#define FT_CURVE_TAG_TOUCH_BOTH  ( FT_CURVE_TAG_TOUCH_X | \
-                                   FT_CURVE_TAG_TOUCH_Y )
+#define FT_CURVE_TAG_TOUCH_X       8  /* reserved for the TrueType hinter */
+#define FT_CURVE_TAG_TOUCH_Y      16  /* reserved for the TrueType hinter */
+
+#define FT_CURVE_TAG_TOUCH_BOTH    ( FT_CURVE_TAG_TOUCH_X | \
+                                     FT_CURVE_TAG_TOUCH_Y )
 
 #define FT_Curve_Tag_On       FT_CURVE_TAG_ON
 #define FT_Curve_Tag_Conic    FT_CURVE_TAG_CONIC
@@ -532,8 +580,8 @@
   /*    FT_Outline_ConicToFunc                                             */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A function pointer type use to describe the signature of a `conic  */
-  /*    to' function during outline walking/decomposition.                 */
+  /*    A function pointer type used to describe the signature of a `conic */
+  /*    to' function during outline walking or decomposition.              */
   /*                                                                       */
   /*    A `conic to' is emitted to indicate a second-order Bézier arc in   */
   /*    the outline.                                                       */
@@ -565,7 +613,7 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    A function pointer type used to describe the signature of a `cubic */
-  /*    to' function during outline walking/decomposition.                 */
+  /*    to' function during outline walking or decomposition.              */
   /*                                                                       */
   /*    A `cubic to' is emitted to indicate a third-order Bézier arc.      */
   /*                                                                       */
@@ -598,8 +646,7 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    A structure to hold various function pointers used during outline  */
-  /*    decomposition in order to emit segments, conic, and cubic Béziers, */
-  /*    as well as `move to' and `close to' operations.                    */
+  /*    decomposition in order to emit segments, conic, and cubic Béziers. */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    move_to  :: The `move to' emitter.                                 */
@@ -626,7 +673,7 @@
   /*      y' = (x << shift) - delta                                        */
   /*    }                                                                  */
   /*                                                                       */
-  /*    Set the value of `shift' and `delta' to~0 to get the original      */
+  /*    Set the values of `shift' and `delta' to~0 to get the original     */
   /*    point coordinates.                                                 */
   /*                                                                       */
   typedef struct  FT_Outline_Funcs_
@@ -1011,7 +1058,7 @@
   /*                                                                       */
   /*    gray_spans  :: The gray span drawing callback.                     */
   /*                                                                       */
-  /*    black_spans :: The black span drawing callback.                    */
+  /*    black_spans :: The black span drawing callback.  UNIMPLEMENTED!    */
   /*                                                                       */
   /*    bit_test    :: The bit test callback.  UNIMPLEMENTED!              */
   /*                                                                       */
@@ -1048,7 +1095,7 @@
     const void*             source;
     int                     flags;
     FT_SpanFunc             gray_spans;
-    FT_SpanFunc             black_spans;
+    FT_SpanFunc             black_spans;  /* doesn't work! */
     FT_Raster_BitTest_Func  bit_test;     /* doesn't work! */
     FT_Raster_BitSet_Func   bit_set;      /* doesn't work! */
     void*                   user;
diff --git a/include/freetype/ftincrem.h b/include/freetype/ftincrem.h
index 96abede..aaf689f 100644
--- a/include/freetype/ftincrem.h
+++ b/include/freetype/ftincrem.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType incremental loading (specification).                        */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2006, 2007, 2008 by                              */
+/*  Copyright 2002, 2003, 2006, 2007, 2008, 2010 by                        */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -101,7 +101,10 @@
    *     Top bearing, in font units.
    *
    *   advance ::
-   *     Glyph advance, in font units.
+   *     Horizontal component of glyph advance, in font units.
+   *
+   *   advance_v ::
+   *     Vertical component of glyph advance, in font units.
    *
    * @note:
    *   These correspond to horizontal or vertical metrics depending on the
@@ -114,6 +117,7 @@
     FT_Long  bearing_x;
     FT_Long  bearing_y;
     FT_Long  advance;
+    FT_Long  advance_v;     /* since 2.3.12 */
 
   } FT_Incremental_MetricsRec;
 
diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h
index b051d34..3c9b876 100644
--- a/include/freetype/ftmodapi.h
+++ b/include/freetype/ftmodapi.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType modules public interface (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2006, 2008 by                         */
+/*  Copyright 1996-2001, 2002, 2003, 2006, 2008, 2009 by                   */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -259,6 +259,10 @@
   /*    from a given memory object.  It is thus possible to use libraries  */
   /*    with distinct memory allocators within the same program.           */
   /*                                                                       */
+  /*    Normally, you would call this function (followed by a call to      */
+  /*    @FT_Add_Default_Modules or a series of calls to @FT_Add_Module)    */
+  /*    instead of @FT_Init_FreeType to initialize the FreeType library.   */
+  /*                                                                       */
   /* <Input>                                                               */
   /*    memory   :: A handle to the original memory object.                */
   /*                                                                       */
diff --git a/include/freetype/ftoutln.h b/include/freetype/ftoutln.h
index d7d01e8..2829a05 100644
--- a/include/freetype/ftoutln.h
+++ b/include/freetype/ftoutln.h
@@ -5,7 +5,7 @@
 /*    Support for the FT_Outline type used to store glyph shapes of        */
 /*    most scalable font formats (specification).                          */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by       */
+/*  Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010 by */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -85,9 +85,8 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    Walk over an outline's structure to decompose it into individual   */
-  /*    segments and Bézier arcs.  This function is also able to emit      */
-  /*    `move to' and `close to' operations to indicate the start and end  */
-  /*    of new contours in the outline.                                    */
+  /*    segments and Bézier arcs.  This function also emits `move to'      */
+  /*    operations to indicate the start of new contours in the outline.   */
   /*                                                                       */
   /* <Input>                                                               */
   /*    outline        :: A pointer to the source target.                  */
diff --git a/include/freetype/ftsnames.h b/include/freetype/ftsnames.h
index 477e1e3..485e4e1 100644
--- a/include/freetype/ftsnames.h
+++ b/include/freetype/ftsnames.h
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    This is _not_ used to retrieve glyph names!                          */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2006 by                               */
+/*  Copyright 1996-2001, 2002, 2003, 2006, 2009, 2010 by                   */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -147,7 +147,8 @@
   /*                                                                       */
   /* <Note>                                                                */
   /*    The `string' array returned in the `aname' structure is not        */
-  /*    null-terminated.                                                   */
+  /*    null-terminated.  The application should deallocate it if it is no */
+  /*    longer in use.                                                     */
   /*                                                                       */
   /*    Use @FT_Get_Sfnt_Name_Count to get the total number of available   */
   /*    `name' table entries, then do a loop until you get the right       */
@@ -159,6 +160,35 @@
                     FT_SfntName  *aname );
 
 
+  /***************************************************************************
+   *
+   * @constant:
+   *   FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY
+   *
+   * @description:
+   *   A constant used as the tag of @FT_Parameter structures to make
+   *   FT_Open_Face() ignore preferred family subfamily names in `name'
+   *   table since OpenType version 1.4.  For backwards compatibility with
+   *   legacy systems which has 4-face-per-family restriction.
+   *
+   */
+#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY  FT_MAKE_TAG( 'i', 'g', 'p', 'f' )
+
+
+  /***************************************************************************
+   *
+   * @constant:
+   *   FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY
+   *
+   * @description:
+   *   A constant used as the tag of @FT_Parameter structures to make
+   *   FT_Open_Face() ignore preferred subfamily names in `name' table since
+   *   OpenType version 1.4.  For backwards compatibility with legacy
+   *   systems which has 4-face-per-family restriction.
+   *
+   */
+#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY  FT_MAKE_TAG( 'i', 'g', 'p', 's' )
+
   /* */
 
 
diff --git a/include/freetype/ftstroke.h b/include/freetype/ftstroke.h
index ae90500..3afb87d 100644
--- a/include/freetype/ftstroke.h
+++ b/include/freetype/ftstroke.h
@@ -598,7 +598,7 @@
    *
    * @description:
    *   Call this function after @FT_Stroker_GetBorderCounts to
-   *   export the all borders to your own @FT_Outline structure.
+   *   export all borders to your own @FT_Outline structure.
    *
    *   Note that this function appends the border points and
    *   contours to your outline, but does not try to resize its
diff --git a/include/freetype/fttypes.h b/include/freetype/fttypes.h
index 54f08e3..e78012d 100644
--- a/include/freetype/fttypes.h
+++ b/include/freetype/fttypes.h
@@ -474,6 +474,7 @@
   /*    this macro.                                                        */
   /*                                                                       */
 #define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
+          (FT_Tag)                        \
           ( ( (FT_ULong)_x1 << 24 ) |     \
             ( (FT_ULong)_x2 << 16 ) |     \
             ( (FT_ULong)_x3 <<  8 ) |     \
diff --git a/include/freetype/ftxf86.h b/include/freetype/ftxf86.h
index ae9ff07..8c68afd 100644
--- a/include/freetype/ftxf86.h
+++ b/include/freetype/ftxf86.h
@@ -49,6 +49,9 @@
   /*   however, there are special cases (like in PDF devices) where it is  */
   /*   important to differentiate, in spite of FreeType's uniform API.     */
   /*                                                                       */
+  /*   This function is in the X11/xf86 namespace for historical reasons   */
+  /*   and in no way depends on that windowing system.                     */
+  /*                                                                       */
   /*************************************************************************/
 
 
diff --git a/include/freetype/internal/autohint.h b/include/freetype/internal/autohint.h
index ee00402..7e3a08a 100644
--- a/include/freetype/internal/autohint.h
+++ b/include/freetype/internal/autohint.h
@@ -196,6 +196,32 @@
 
   } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service;
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \
+                                     done_global_hints_, load_glyph_)        \
+  FT_CALLBACK_TABLE_DEF                                                      \
+  const FT_AutoHinter_ServiceRec class_ =                                    \
+  {                                                                          \
+    reset_face_, get_global_hints_, done_global_hints_, load_glyph_          \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_AUTOHINTER_SERVICE(class_, reset_face_, get_global_hints_, \
+                                     done_global_hints_, load_glyph_)        \
+  void                                                                       \
+  FT_Init_Class_##class_( FT_Library library,                                \
+                          FT_AutoHinter_ServiceRec* clazz)                   \
+  {                                                                          \
+    FT_UNUSED(library);                                                      \
+    clazz->reset_face = reset_face_;                                         \
+    clazz->get_global_hints = get_global_hints_;                             \
+    clazz->done_global_hints = done_global_hints_;                           \
+    clazz->load_glyph = load_glyph_;                                         \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
 
 FT_END_HEADER
 
diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h
index 58def34..f8b4324 100644
--- a/include/freetype/internal/ftcalc.h
+++ b/include/freetype/internal/ftcalc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Arithmetic computations (specification).                             */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by             */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009 by       */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -165,6 +165,7 @@
 #define INT_TO_FIXED( x )      ( (FT_Long)(x) << 16 )
 #define F2DOT14_TO_FIXED( x )  ( (FT_Long)(x) << 2  )
 #define FLOAT_TO_FIXED( x )    ( (FT_Long)( x * 65536.0 ) )
+#define FIXED_TO_INT( x )      ( FT_RoundFix( x ) >> 16 )
 
 #define ROUND_F26DOT6( x )     ( x >= 0 ? (    ( (x) + 32 ) & -64 )     \
                                         : ( -( ( 32 - (x) ) & -64 ) ) )
diff --git a/include/freetype/internal/ftdriver.h b/include/freetype/internal/ftdriver.h
index 854abad..1d06997 100644
--- a/include/freetype/internal/ftdriver.h
+++ b/include/freetype/internal/ftdriver.h
@@ -240,6 +240,179 @@
 
 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DECLARE_DRIVER                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to create a forward declaration of a                          */
+  /*    FT_Driver_ClassRec stract instance.                                */
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DEFINE_DRIVER                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to initialize an instance of FT_Driver_ClassRec struct.       */
+  /*                                                                       */
+  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */
+  /*    to called with a pointer where the allocated stracture is returned.*/
+  /*    And when it is no longer needed a Destroy function needs           */
+  /*    to be called to release that allocation.                           */
+  /*    fcinit.c (ft_create_default_module_classes) already contains       */
+  /*    a mechanism to call these functions for the default modules        */
+  /*    described in ftmodule.h                                            */
+  /*                                                                       */
+  /*    Notice that the created Create and Destroy functions call          */
+  /*    pic_init and pic_free function to allow you to manually allocate   */
+  /*    and initialize any additional global data, like module specific    */
+  /*    interface, and put them in the global pic container defined in     */
+  /*    ftpic.h. if you don't need them just implement the functions as    */
+  /*    empty to resolve the link error.                                   */
+  /*                                                                       */
+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
+  /*    allocated in the global scope (or the scope where the macro        */
+  /*    is used).                                                          */
+  /*                                                                       */
+#ifndef FT_CONFIG_OPTION_PIC
+
+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \
+  a_, b_,
+#else
+  #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_)
+#endif
+
+#define FT_DECLARE_DRIVER(class_)    \
+  FT_CALLBACK_TABLE                  \
+  const FT_Driver_ClassRec  class_;  
+
+#define FT_DEFINE_DRIVER(class_,                                             \
+                         flags_, size_, name_, version_, requires_,          \
+                         interface_, init_, done_, get_interface_,           \
+                         face_object_size_, size_object_size_,               \
+                         slot_object_size_, init_face_, done_face_,          \
+                         init_size_, done_size_, init_slot_, done_slot_,     \
+                         old_set_char_sizes_, old_set_pixel_sizes_,          \
+                         load_glyph_, get_kerning_, attach_file_,            \
+                         get_advances_, request_size_, select_size_ )        \
+  FT_CALLBACK_TABLE_DEF                                                      \
+  const FT_Driver_ClassRec class_ =                                          \
+  {                                                                          \
+    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_,  \
+                          init_,done_,get_interface_)                        \
+                                                                             \
+    face_object_size_,                                                       \
+    size_object_size_,                                                       \
+    slot_object_size_,                                                       \
+                                                                             \
+    init_face_,                                                              \
+    done_face_,                                                              \
+                                                                             \
+    init_size_,                                                              \
+    done_size_,                                                              \
+                                                                             \
+    init_slot_,                                                              \
+    done_slot_,                                                              \
+                                                                             \
+    FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \
+                                                                             \
+    load_glyph_,                                                             \
+                                                                             \
+    get_kerning_,                                                            \
+    attach_file_,                                                            \
+    get_advances_,                                                           \
+                                                                             \
+    request_size_,                                                           \
+    select_size_                                                             \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+#define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_) \
+  clazz->set_char_sizes = a_; \
+  clazz->set_pixel_sizes = b_;
+#else
+  #define FT_DEFINE_DRIVERS_OLD_INTERNALS(a_,b_)
+#endif
+
+#define FT_DECLARE_DRIVER(class_)    FT_DECLARE_MODULE(class_)
+
+#define FT_DEFINE_DRIVER(class_,                                             \
+                         flags_, size_, name_, version_, requires_,          \
+                         interface_, init_, done_, get_interface_,           \
+                         face_object_size_, size_object_size_,               \
+                         slot_object_size_, init_face_, done_face_,          \
+                         init_size_, done_size_, init_slot_, done_slot_,     \
+                         old_set_char_sizes_, old_set_pixel_sizes_,          \
+                         load_glyph_, get_kerning_, attach_file_,            \
+                         get_advances_, request_size_, select_size_ )        \
+  void class_##_pic_free( FT_Library library );                              \
+  FT_Error class_##_pic_init( FT_Library library );                          \
+                                                                             \
+  void                                                                       \
+  FT_Destroy_Class_##class_( FT_Library        library,                      \
+                             FT_Module_Class*  clazz )                       \
+  {                                                                          \
+    FT_Memory       memory = library->memory;                                \
+    FT_Driver_Class dclazz = (FT_Driver_Class)clazz;                         \
+    class_##_pic_free( library );                                            \
+    if ( dclazz )                                                            \
+      FT_FREE( dclazz );                                                     \
+  }                                                                          \
+                                                                             \
+  FT_Error                                                                   \
+  FT_Create_Class_##class_( FT_Library        library,                       \
+                            FT_Module_Class**  output_class )                \
+  {                                                                          \
+    FT_Driver_Class  clazz;                                                  \
+    FT_Error         error;                                                  \
+    FT_Memory        memory = library->memory;                               \
+                                                                             \
+    if ( FT_ALLOC( clazz, sizeof(*clazz) ) )                                 \
+      return error;                                                          \
+                                                                             \
+    error = class_##_pic_init( library );                                    \
+    if(error)                                                                \
+    {                                                                        \
+      FT_FREE( clazz );                                                      \
+      return error;                                                          \
+    }                                                                        \
+                                                                             \
+    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,interface_,  \
+                          init_,done_,get_interface_)                        \
+                                                                             \
+    clazz->face_object_size    = face_object_size_;                          \
+    clazz->size_object_size    = size_object_size_;                          \
+    clazz->slot_object_size    = slot_object_size_;                          \
+                                                                             \
+    clazz->init_face           = init_face_;                                 \
+    clazz->done_face           = done_face_;                                 \
+                                                                             \
+    clazz->init_size           = init_size_;                                 \
+    clazz->done_size           = done_size_;                                 \
+                                                                             \
+    clazz->init_slot           = init_slot_;                                 \
+    clazz->done_slot           = done_slot_;                                 \
+                                                                             \
+    FT_DEFINE_DRIVERS_OLD_INTERNALS(old_set_char_sizes_, old_set_pixel_sizes_) \
+                                                                             \
+    clazz->load_glyph          = load_glyph_;                                \
+                                                                             \
+    clazz->get_kerning         = get_kerning_;                               \
+    clazz->attach_file         = attach_file_;                               \
+    clazz->get_advances        = get_advances_;                              \
+                                                                             \
+    clazz->request_size        = request_size_;                              \
+    clazz->select_size         = select_size_;                               \
+                                                                             \
+    *output_class = (FT_Module_Class*)clazz;                                 \
+    return FT_Err_Ok;                                                        \
+  }                
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
 
 FT_END_HEADER
 
diff --git a/include/freetype/internal/ftgloadr.h b/include/freetype/internal/ftgloadr.h
index 548481a..ce4dc6c 100644
--- a/include/freetype/internal/ftgloadr.h
+++ b/include/freetype/internal/ftgloadr.h
@@ -121,15 +121,15 @@
                               FT_UInt         n_contours );
 
 
-#define FT_GLYPHLOADER_CHECK_P( _loader, _count )                    \
-   ( (_count) == 0 || (int)((_loader)->base.outline.n_points    +    \
-                            (_loader)->current.outline.n_points +    \
-                            (_count)) <= (int)(_loader)->max_points )
+#define FT_GLYPHLOADER_CHECK_P( _loader, _count )                         \
+   ( (_count) == 0 || ((_loader)->base.outline.n_points    +              \
+                       (_loader)->current.outline.n_points +              \
+                       (unsigned long)(_count)) <= (_loader)->max_points )
 
-#define FT_GLYPHLOADER_CHECK_C( _loader, _count )                     \
-  ( (_count) == 0 || (int)((_loader)->base.outline.n_contours    +    \
-                           (_loader)->current.outline.n_contours +    \
-                           (_count)) <= (int)(_loader)->max_contours )
+#define FT_GLYPHLOADER_CHECK_C( _loader, _count )                          \
+  ( (_count) == 0 || ((_loader)->base.outline.n_contours    +              \
+                      (_loader)->current.outline.n_contours +              \
+                      (unsigned long)(_count)) <= (_loader)->max_contours )
 
 #define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours )      \
   ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points )   &&                  \
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index 1f22343..574cf58 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -35,6 +35,7 @@
 #include FT_INTERNAL_DRIVER_H
 #include FT_INTERNAL_AUTOHINT_H
 #include FT_INTERNAL_SERVICE_H
+#include FT_INTERNAL_PIC_H
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 #include FT_INCREMENTAL_H
@@ -205,6 +206,45 @@
 
   } FT_CMap_ClassRec;
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DECLARE_CMAP_CLASS(class_) \
+    FT_CALLBACK_TABLE const FT_CMap_ClassRec class_;
+
+#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_,       \
+        char_next_, char_var_index_, char_var_default_, variant_list_,       \
+        charvariant_list_, variantchar_list_)                                \
+  FT_CALLBACK_TABLE_DEF                                                      \
+  const FT_CMap_ClassRec class_ =                                            \
+  {                                                                          \
+    size_, init_, done_, char_index_, char_next_, char_var_index_,           \
+    char_var_default_, variant_list_, charvariant_list_, variantchar_list_   \
+  };
+#else /* FT_CONFIG_OPTION_PIC */
+
+#define FT_DECLARE_CMAP_CLASS(class_) \
+    void FT_Init_Class_##class_( FT_Library library, FT_CMap_ClassRec*  clazz);
+
+#define FT_DEFINE_CMAP_CLASS(class_, size_, init_, done_, char_index_,       \
+        char_next_, char_var_index_, char_var_default_, variant_list_,       \
+        charvariant_list_, variantchar_list_)                                \
+  void                                                                       \
+  FT_Init_Class_##class_( FT_Library library,                                \
+                          FT_CMap_ClassRec*  clazz)                          \
+  {                                                                          \
+    FT_UNUSED(library);                                                      \
+    clazz->size = size_;                                                     \
+    clazz->init = init_;                                                     \
+    clazz->done = done_;                                                     \
+    clazz->char_index = char_index_;                                         \
+    clazz->char_next = char_next_;                                           \
+    clazz->char_var_index = char_var_index_;                                 \
+    clazz->char_var_default = char_var_default_;                             \
+    clazz->variant_list = variant_list_;                                     \
+    clazz->charvariant_list = charvariant_list_;                             \
+    clazz->variantchar_list = variantchar_list_;                             \
+  } 
+#endif /* FT_CONFIG_OPTION_PIC */
 
   /* create a new charmap and add it to charmap->face */
   FT_BASE( FT_Error )
@@ -765,6 +805,10 @@
   /*                                                                       */
   /*    debug_hooks      :: XXX                                            */
   /*                                                                       */
+  /*    pic_container    :: Contains global structs and tables, instead    */
+  /*                        of defining them globallly.                    */
+  /*                                                                       */
+
   typedef struct  FT_LibraryRec_
   {
     FT_Memory          memory;           /* library's memory manager */
@@ -795,6 +839,10 @@
     FT_Bitmap_LcdFilterFunc  lcd_filter_func;  /* filtering callback     */
 #endif
 
+#ifdef FT_CONFIG_OPTION_PIC
+    FT_PIC_Container   pic_container;
+#endif
+
   } FT_LibraryRec;
 
 
@@ -866,6 +914,484 @@
   FT_EXPORT_VAR( FT_Raster_Funcs )  ft_default_raster;
 #endif
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****              PIC-Support Macros for ftimage.h                   ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DEFINE_OUTLINE_FUNCS                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to initialize an instance of FT_Outline_Funcs struct.         */
+  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */
+  /*    called with a pre-allocated stracture to be filled.                */
+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
+  /*    allocated in the global scope (or the scope where the macro        */
+  /*    is used).                                                          */
+  /*                                                                       */
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_,       \
+                                cubic_to_, shift_, delta_)                   \
+  static const FT_Outline_Funcs class_ =                                     \
+  {                                                                          \
+    move_to_, line_to_, conic_to_, cubic_to_, shift_, delta_                 \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_OUTLINE_FUNCS(class_, move_to_, line_to_, conic_to_,       \
+                                cubic_to_, shift_, delta_)                   \
+  static FT_Error                                                            \
+  Init_Class_##class_( FT_Outline_Funcs*  clazz )                            \
+  {                                                                          \
+    clazz->move_to = move_to_;                                               \
+    clazz->line_to = line_to_;                                               \
+    clazz->conic_to = conic_to_;                                             \
+    clazz->cubic_to = cubic_to_;                                             \
+    clazz->shift = shift_;                                                   \
+    clazz->delta = delta_;                                                   \
+    return FT_Err_Ok;                                                        \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DEFINE_RASTER_FUNCS                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to initialize an instance of FT_Raster_Funcs struct.          */
+  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */
+  /*    called with a pre-allocated stracture to be filled.                */
+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
+  /*    allocated in the global scope (or the scope where the macro        */
+  /*    is used).                                                          */
+  /*                                                                       */
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_,           \
+                               raster_reset_, raster_set_mode_,              \
+                               raster_render_, raster_done_)                 \
+  const FT_Raster_Funcs class_ =                                      \
+  {                                                                          \
+    glyph_format_, raster_new_, raster_reset_,                               \
+    raster_set_mode_, raster_render_, raster_done_                           \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_RASTER_FUNCS(class_, glyph_format_, raster_new_,           \
+    raster_reset_, raster_set_mode_, raster_render_, raster_done_)           \
+  void                                                                       \
+  FT_Init_Class_##class_( FT_Raster_Funcs*  clazz )                          \
+  {                                                                          \
+    clazz->glyph_format = glyph_format_;                                     \
+    clazz->raster_new = raster_new_;                                         \
+    clazz->raster_reset = raster_reset_;                                     \
+    clazz->raster_set_mode = raster_set_mode_;                               \
+    clazz->raster_render = raster_render_;                                   \
+    clazz->raster_done = raster_done_;                                       \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****              PIC-Support Macros for ftrender.h                  ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DEFINE_GLYPH                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to initialize an instance of FT_Glyph_Class struct.           */
+  /*    When FT_CONFIG_OPTION_PIC is defined an init funtion will need to  */
+  /*    called with a pre-allocated stracture to be filled.                */
+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
+  /*    allocated in the global scope (or the scope where the macro        */
+  /*    is used).                                                          */
+  /*                                                                       */
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_,         \
+                        transform_, bbox_, prepare_)                         \
+  FT_CALLBACK_TABLE_DEF                                                      \
+  const FT_Glyph_Class class_ =                                              \
+  {                                                                          \
+    size_, format_, init_, done_, copy_, transform_, bbox_, prepare_         \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_GLYPH(class_, size_, format_, init_, done_, copy_,         \
+                        transform_, bbox_, prepare_)                         \
+  void                                                                       \
+  FT_Init_Class_##class_( FT_Glyph_Class*  clazz )                           \
+  {                                                                          \
+    clazz->glyph_size = size_;                                               \
+    clazz->glyph_format = format_;                                           \
+    clazz->glyph_init = init_;                                               \
+    clazz->glyph_done = done_;                                               \
+    clazz->glyph_copy = copy_;                                               \
+    clazz->glyph_transform = transform_;                                     \
+    clazz->glyph_bbox = bbox_;                                               \
+    clazz->glyph_prepare = prepare_;                                         \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DECLARE_RENDERER                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to create a forward declaration of a                          */
+  /*    FT_Renderer_Class stract instance.                                 */
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DEFINE_RENDERER                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to initialize an instance of FT_Renderer_Class struct.        */
+  /*                                                                       */
+  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */
+  /*    to called with a pointer where the allocated stracture is returned.*/
+  /*    And when it is no longer needed a Destroy function needs           */
+  /*    to be called to release that allocation.                           */
+  /*    fcinit.c (ft_create_default_module_classes) already contains       */
+  /*    a mechanism to call these functions for the default modules        */
+  /*    described in ftmodule.h                                            */
+  /*                                                                       */
+  /*    Notice that the created Create and Destroy functions call          */
+  /*    pic_init and pic_free function to allow you to manually allocate   */
+  /*    and initialize any additional global data, like module specific    */
+  /*    interface, and put them in the global pic container defined in     */
+  /*    ftpic.h. if you don't need them just implement the functions as    */
+  /*    empty to resolve the link error.                                   */
+  /*                                                                       */
+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
+  /*    allocated in the global scope (or the scope where the macro        */
+  /*    is used).                                                          */
+  /*                                                                       */
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DECLARE_RENDERER(class_)                                          \
+    FT_EXPORT_VAR( const FT_Renderer_Class ) class_;
+
+#define FT_DEFINE_RENDERER(class_,                                           \
+                           flags_, size_, name_, version_, requires_,        \
+                           interface_, init_, done_, get_interface_,         \
+                           glyph_format_, render_glyph_, transform_glyph_,   \
+                           get_glyph_cbox_, set_mode_, raster_class_ )       \
+  FT_CALLBACK_TABLE_DEF                                                      \
+  const FT_Renderer_Class  class_ =                                          \
+  {                                                                          \
+    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,             \
+                          interface_,init_,done_,get_interface_)             \
+    glyph_format_,                                                           \
+                                                                             \
+    render_glyph_,                                                           \
+    transform_glyph_,                                                        \
+    get_glyph_cbox_,                                                         \
+    set_mode_,                                                               \
+                                                                             \
+    raster_class_                                                            \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DECLARE_RENDERER(class_)  FT_DECLARE_MODULE(class_)
+
+#define FT_DEFINE_RENDERER(class_, \
+                           flags_, size_, name_, version_, requires_,        \
+                           interface_, init_, done_, get_interface_,         \
+                           glyph_format_, render_glyph_, transform_glyph_,   \
+                           get_glyph_cbox_, set_mode_, raster_class_ )       \
+  void class_##_pic_free( FT_Library library );                              \
+  FT_Error class_##_pic_init( FT_Library library );                          \
+                                                                             \
+  void                                                                       \
+  FT_Destroy_Class_##class_( FT_Library        library,                      \
+                        FT_Module_Class*  clazz )                            \
+  {                                                                          \
+    FT_Renderer_Class* rclazz = (FT_Renderer_Class*)clazz;                   \
+    FT_Memory         memory = library->memory;                              \
+    class_##_pic_free( library );                                            \
+    if ( rclazz )                                                            \
+      FT_FREE( rclazz );                                                     \
+  }                                                                          \
+                                                                             \
+  FT_Error                                                                   \
+  FT_Create_Class_##class_( FT_Library         library,                      \
+                            FT_Module_Class**  output_class )                \
+  {                                                                          \
+    FT_Renderer_Class*  clazz;                                               \
+    FT_Error            error;                                               \
+    FT_Memory           memory = library->memory;                            \
+                                                                             \
+    if ( FT_ALLOC( clazz, sizeof(*clazz) ) )                                 \
+      return error;                                                          \
+                                                                             \
+    error = class_##_pic_init( library );                                    \
+    if(error)                                                                \
+    {                                                                        \
+      FT_FREE( clazz );                                                      \
+      return error;                                                          \
+    }                                                                        \
+                                                                             \
+    FT_DEFINE_ROOT_MODULE(flags_,size_,name_,version_,requires_,             \
+                          interface_,init_,done_,get_interface_)             \
+                                                                             \
+    clazz->glyph_format       = glyph_format_;                               \
+                                                                             \
+    clazz->render_glyph       = render_glyph_;                               \
+    clazz->transform_glyph    = transform_glyph_;                            \
+    clazz->get_glyph_cbox     = get_glyph_cbox_;                             \
+    clazz->set_mode           = set_mode_;                                   \
+                                                                             \
+    clazz->raster_class       = raster_class_;                               \
+                                                                             \
+    *output_class = (FT_Module_Class*)clazz;                                 \
+    return FT_Err_Ok;                                                        \
+  } 
+
+
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /****              PIC-Support Macros for ftmodapi.h                  ****/
+  /****                                                                 ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Module_Creator                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function used to create (allocate) a new module class object.    */
+  /*    The object's members are initialized, but the module itself is     */
+  /*    not.                                                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory       :: A handle to the memory manager.                    */
+  /*    output_class :: Initialized with the newly allocated class.        */
+  /*                                                                       */
+  typedef FT_Error
+  (*FT_Module_Creator)( FT_Memory          memory,
+                        FT_Module_Class**  output_class );
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
+  /*    FT_Module_Destroyer                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function used to destroy (deallocate) a module class object.     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    memory :: A handle to the memory manager.                          */
+  /*    clazz  :: Module class to destroy.                                 */
+  /*                                                                       */
+  typedef void
+  (*FT_Module_Destroyer)( FT_Memory         memory,
+                          FT_Module_Class*  clazz );
+
+#endif
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DECLARE_MODULE                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to create a forward declaration of a                          */
+  /*    FT_Module_Class stract instance.                                   */
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DEFINE_MODULE                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to initialize an instance of FT_Module_Class struct.          */
+  /*                                                                       */
+  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */
+  /*    to called with a pointer where the allocated stracture is returned.*/
+  /*    And when it is no longer needed a Destroy function needs           */
+  /*    to be called to release that allocation.                           */
+  /*    fcinit.c (ft_create_default_module_classes) already contains       */
+  /*    a mechanism to call these functions for the default modules        */
+  /*    described in ftmodule.h                                            */
+  /*                                                                       */
+  /*    Notice that the created Create and Destroy functions call          */
+  /*    pic_init and pic_free function to allow you to manually allocate   */
+  /*    and initialize any additional global data, like module specific    */
+  /*    interface, and put them in the global pic container defined in     */
+  /*    ftpic.h. if you don't need them just implement the functions as    */
+  /*    empty to resolve the link error.                                   */
+  /*                                                                       */
+  /*    When FT_CONFIG_OPTION_PIC is not defined the struct will be        */
+  /*    allocated in the global scope (or the scope where the macro        */
+  /*    is used).                                                          */
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DEFINE_ROOT_MODULE                                              */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to initialize an instance of FT_Module_Class struct inside    */
+  /*    another stract that contains it or in a function that initializes  */
+  /*    that containing stract                                             */
+  /*                                                                       */
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DECLARE_MODULE(class_)                                            \
+  FT_CALLBACK_TABLE                                                          \
+  const FT_Module_Class  class_;                                             \
+
+#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_,     \
+                              interface_, init_, done_, get_interface_)      \
+  {                                                                          \
+    flags_,                                                                  \
+    size_,                                                                   \
+                                                                             \
+    name_,                                                                   \
+    version_,                                                                \
+    requires_,                                                               \
+                                                                             \
+    interface_,                                                              \
+                                                                             \
+    init_,                                                                   \
+    done_,                                                                   \
+    get_interface_,                                                          \
+  },
+
+#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_,  \
+                         interface_, init_, done_, get_interface_)           \
+  FT_CALLBACK_TABLE_DEF                                                      \
+  const FT_Module_Class class_ =                                             \
+  {                                                                          \
+    flags_,                                                                  \
+    size_,                                                                   \
+                                                                             \
+    name_,                                                                   \
+    version_,                                                                \
+    requires_,                                                               \
+                                                                             \
+    interface_,                                                              \
+                                                                             \
+    init_,                                                                   \
+    done_,                                                                   \
+    get_interface_,                                                          \
+  };
+
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#define FT_DECLARE_MODULE(class_)                                            \
+  FT_Error FT_Create_Class_##class_( FT_Library library,                     \
+                                     FT_Module_Class** output_class );       \
+  void     FT_Destroy_Class_##class_( FT_Library library,                    \
+                                      FT_Module_Class*  clazz );
+
+#define FT_DEFINE_ROOT_MODULE(flags_, size_, name_, version_, requires_,     \
+                              interface_, init_, done_, get_interface_)      \
+    clazz->root.module_flags       = flags_;                                 \
+    clazz->root.module_size        = size_;                                  \
+    clazz->root.module_name        = name_;                                  \
+    clazz->root.module_version     = version_;                               \
+    clazz->root.module_requires    = requires_;                              \
+                                                                             \
+    clazz->root.module_interface   = interface_;                             \
+                                                                             \
+    clazz->root.module_init        = init_;                                  \
+    clazz->root.module_done        = done_;                                  \
+    clazz->root.get_interface      = get_interface_;               
+
+#define FT_DEFINE_MODULE(class_, flags_, size_, name_, version_, requires_,  \
+                         interface_, init_, done_, get_interface_)           \
+  void class_##_pic_free( FT_Library library );                              \
+  FT_Error class_##_pic_init( FT_Library library );                          \
+                                                                             \
+  void                                                                       \
+  FT_Destroy_Class_##class_( FT_Library library,                             \
+                             FT_Module_Class*  clazz )                       \
+  {                                                                          \
+    FT_Memory memory = library->memory;                                      \
+    class_##_pic_free( library );                                            \
+    if ( clazz )                                                             \
+      FT_FREE( clazz );                                                      \
+  }                                                                          \
+                                                                             \
+  FT_Error                                                                   \
+  FT_Create_Class_##class_( FT_Library library,                              \
+                            FT_Module_Class**  output_class )                \
+  {                                                                          \
+    FT_Memory memory = library->memory;                                      \
+    FT_Module_Class*  clazz;                                                 \
+    FT_Error          error;                                                 \
+                                                                             \
+    if ( FT_ALLOC( clazz, sizeof(*clazz) ) )                                 \
+      return error;                                                          \
+    error = class_##_pic_init( library );                                    \
+    if(error)                                                                \
+    {                                                                        \
+      FT_FREE( clazz );                                                      \
+      return error;                                                          \
+    }                                                                        \
+                                                                             \
+    clazz->module_flags       = flags_;                                      \
+    clazz->module_size        = size_;                                       \
+    clazz->module_name        = name_;                                       \
+    clazz->module_version     = version_;                                    \
+    clazz->module_requires    = requires_;                                   \
+                                                                             \
+    clazz->module_interface   = interface_;                                  \
+                                                                             \
+    clazz->module_init        = init_;                                       \
+    clazz->module_done        = done_;                                       \
+    clazz->get_interface      = get_interface_;                              \
+                                                                             \
+    *output_class = clazz;                                                   \
+    return FT_Err_Ok;                                                        \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
 
 FT_END_HEADER
 
diff --git a/include/freetype/internal/ftpic.h b/include/freetype/internal/ftpic.h
new file mode 100644
index 0000000..1b31957
--- /dev/null
+++ b/include/freetype/internal/ftpic.h
@@ -0,0 +1,67 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftpic.h                                                                */
+/*                                                                         */
+/*    The FreeType position independent code services (declaration).       */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /*  Modules that ordinarily have const global data that need address     */
+  /*  can instead define pointers here.                                    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef __FTPIC_H__
+#define __FTPIC_H__
+
+  
+FT_BEGIN_HEADER
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  typedef struct FT_PIC_Container_
+  {
+    /* pic containers for base */
+    void* base;
+    /* pic containers for modules */
+    void* autofit;   
+    void* cff;    
+    void* pshinter;    
+    void* psnames;    
+    void* raster;     
+    void* sfnt;     
+    void* smooth;     
+    void* truetype;     
+  } FT_PIC_Container;
+
+  /* Initialize the various function tables, structs, etc. stored in the container. */
+  FT_BASE( FT_Error )
+  ft_pic_container_init( FT_Library library );
+
+
+  /* Destroy the contents of the container. */
+  FT_BASE( void )
+  ft_pic_container_destroy( FT_Library library );
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __FTPIC_H__ */
+
+
+/* END */
diff --git a/include/freetype/internal/ftserv.h b/include/freetype/internal/ftserv.h
index 2db3e87..569b9f7 100644
--- a/include/freetype/internal/ftserv.h
+++ b/include/freetype/internal/ftserv.h
@@ -163,6 +163,298 @@
 
   typedef const FT_ServiceDescRec*  FT_ServiceDesc;
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Macro>                                                               */
+  /*    FT_DEFINE_SERVICEDESCREC1 .. FT_DEFINE_SERVICEDESCREC6             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Used to initialize an array of FT_ServiceDescRec structs.          */
+  /*                                                                       */
+  /*    When FT_CONFIG_OPTION_PIC is defined a Create funtion will need    */
+  /*    to called with a pointer where the allocated array is returned.    */
+  /*    And when it is no longer needed a Destroy function needs           */
+  /*    to be called to release that allocation.                           */
+  /*                                                                       */
+  /*    These functions should be manyally called from the pic_init and    */
+  /*    pic_free functions of your module (see FT_DEFINE_MODULE)           */
+  /*                                                                       */
+  /*    When FT_CONFIG_OPTION_PIC is not defined the array will be         */
+  /*    allocated in the global scope (or the scope where the macro        */
+  /*    is used).                                                          */
+  /*                                                                       */
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1)            \
+  static const FT_ServiceDescRec class_[] =                                  \
+  {                                                                          \
+  {serv_id_1, serv_data_1},                                                  \
+  {NULL, NULL}                                                               \
+  };
+#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2)                                              \
+  static const FT_ServiceDescRec class_[] =                                  \
+  {                                                                          \
+  {serv_id_1, serv_data_1},                                                  \
+  {serv_id_2, serv_data_2},                                                  \
+  {NULL, NULL}                                                               \
+  };
+#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2, serv_id_3, serv_data_3)                      \
+  static const FT_ServiceDescRec class_[] =                                  \
+  {                                                                          \
+  {serv_id_1, serv_data_1},                                                  \
+  {serv_id_2, serv_data_2},                                                  \
+  {serv_id_3, serv_data_3},                                                  \
+  {NULL, NULL}                                                               \
+  };
+#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
+        serv_id_4, serv_data_4)                                              \
+  static const FT_ServiceDescRec class_[] =                                  \
+  {                                                                          \
+  {serv_id_1, serv_data_1},                                                  \
+  {serv_id_2, serv_data_2},                                                  \
+  {serv_id_3, serv_data_3},                                                  \
+  {serv_id_4, serv_data_4},                                                  \
+  {NULL, NULL}                                                               \
+  };
+#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
+        serv_id_4, serv_data_4, serv_id_5, serv_data_5)                      \
+  static const FT_ServiceDescRec class_[] =                                  \
+  {                                                                          \
+  {serv_id_1, serv_data_1},                                                  \
+  {serv_id_2, serv_data_2},                                                  \
+  {serv_id_3, serv_data_3},                                                  \
+  {serv_id_4, serv_data_4},                                                  \
+  {serv_id_5, serv_data_5},                                                  \
+  {NULL, NULL}                                                               \
+  };
+#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
+        serv_id_4, serv_data_4, serv_id_5, serv_data_5,                      \
+        serv_id_6, serv_data_6)                                              \
+  static const FT_ServiceDescRec class_[] =                                  \
+  {                                                                          \
+  {serv_id_1, serv_data_1},                                                  \
+  {serv_id_2, serv_data_2},                                                  \
+  {serv_id_3, serv_data_3},                                                  \
+  {serv_id_4, serv_data_4},                                                  \
+  {serv_id_5, serv_data_5},                                                  \
+  {serv_id_6, serv_data_6},                                                  \
+  {NULL, NULL}                                                               \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICEDESCREC1(class_, serv_id_1, serv_data_1)            \
+  void                                                                       \
+  FT_Destroy_Class_##class_( FT_Library library,                             \
+                             FT_ServiceDescRec* clazz )                      \
+  {                                                                          \
+    FT_Memory memory = library->memory;                                      \
+    if ( clazz )                                                             \
+      FT_FREE( clazz );                                                      \
+  }                                                                          \
+                                                                             \
+  FT_Error                                                                   \
+  FT_Create_Class_##class_( FT_Library library,                              \
+                            FT_ServiceDescRec** output_class)                \
+  {                                                                          \
+    FT_ServiceDescRec*  clazz;                                               \
+    FT_Error          error;                                                 \
+    FT_Memory memory = library->memory;                                      \
+                                                                             \
+    if ( FT_ALLOC( clazz, sizeof(*clazz)*2 ) )                               \
+      return error;                                                          \
+    clazz[0].serv_id = serv_id_1;                                            \
+    clazz[0].serv_data = serv_data_1;                                        \
+    clazz[1].serv_id = NULL;                                                 \
+    clazz[1].serv_data = NULL;                                               \
+    *output_class = clazz;                                                   \
+    return FT_Err_Ok;                                                        \
+  } 
+
+#define FT_DEFINE_SERVICEDESCREC2(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2)                                              \
+  void                                                                       \
+  FT_Destroy_Class_##class_( FT_Library library,                             \
+                             FT_ServiceDescRec* clazz )                      \
+  {                                                                          \
+    FT_Memory memory = library->memory;                                      \
+    if ( clazz )                                                             \
+      FT_FREE( clazz );                                                      \
+  }                                                                          \
+                                                                             \
+  FT_Error                                                                   \
+  FT_Create_Class_##class_( FT_Library library,                              \
+                            FT_ServiceDescRec** output_class)                \
+  {                                                                          \
+    FT_ServiceDescRec*  clazz;                                               \
+    FT_Error          error;                                                 \
+    FT_Memory memory = library->memory;                                      \
+                                                                             \
+    if ( FT_ALLOC( clazz, sizeof(*clazz)*3 ) )                               \
+      return error;                                                          \
+    clazz[0].serv_id = serv_id_1;                                            \
+    clazz[0].serv_data = serv_data_1;                                        \
+    clazz[1].serv_id = serv_id_2;                                            \
+    clazz[1].serv_data = serv_data_2;                                        \
+    clazz[2].serv_id = NULL;                                                 \
+    clazz[2].serv_data = NULL;                                               \
+    *output_class = clazz;                                                   \
+    return FT_Err_Ok;                                                        \
+  } 
+
+#define FT_DEFINE_SERVICEDESCREC3(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2, serv_id_3, serv_data_3)                      \
+  void                                                                       \
+  FT_Destroy_Class_##class_( FT_Library library,                             \
+                             FT_ServiceDescRec* clazz )                      \
+  {                                                                          \
+    FT_Memory memory = library->memory;                                      \
+    if ( clazz )                                                             \
+      FT_FREE( clazz );                                                      \
+  }                                                                          \
+                                                                             \
+  FT_Error                                                                   \
+  FT_Create_Class_##class_( FT_Library library,                              \
+                            FT_ServiceDescRec** output_class)                \
+  {                                                                          \
+    FT_ServiceDescRec*  clazz;                                               \
+    FT_Error          error;                                                 \
+    FT_Memory memory = library->memory;                                      \
+                                                                             \
+    if ( FT_ALLOC( clazz, sizeof(*clazz)*4 ) )                               \
+      return error;                                                          \
+    clazz[0].serv_id = serv_id_1;                                            \
+    clazz[0].serv_data = serv_data_1;                                        \
+    clazz[1].serv_id = serv_id_2;                                            \
+    clazz[1].serv_data = serv_data_2;                                        \
+    clazz[2].serv_id = serv_id_3;                                            \
+    clazz[2].serv_data = serv_data_3;                                        \
+    clazz[3].serv_id = NULL;                                                 \
+    clazz[3].serv_data = NULL;                                               \
+    *output_class = clazz;                                                   \
+    return FT_Err_Ok;                                                        \
+  } 
+
+#define FT_DEFINE_SERVICEDESCREC4(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
+        serv_id_4, serv_data_4)                                              \
+  void                                                                       \
+  FT_Destroy_Class_##class_( FT_Library library,                             \
+                             FT_ServiceDescRec* clazz )                      \
+  {                                                                          \
+    FT_Memory memory = library->memory;                                      \
+    if ( clazz )                                                             \
+      FT_FREE( clazz );                                                      \
+  }                                                                          \
+                                                                             \
+  FT_Error                                                                   \
+  FT_Create_Class_##class_( FT_Library library,                              \
+                            FT_ServiceDescRec** output_class)                \
+  {                                                                          \
+    FT_ServiceDescRec*  clazz;                                               \
+    FT_Error          error;                                                 \
+    FT_Memory memory = library->memory;                                      \
+                                                                             \
+    if ( FT_ALLOC( clazz, sizeof(*clazz)*5 ) )                               \
+      return error;                                                          \
+    clazz[0].serv_id = serv_id_1;                                            \
+    clazz[0].serv_data = serv_data_1;                                        \
+    clazz[1].serv_id = serv_id_2;                                            \
+    clazz[1].serv_data = serv_data_2;                                        \
+    clazz[2].serv_id = serv_id_3;                                            \
+    clazz[2].serv_data = serv_data_3;                                        \
+    clazz[3].serv_id = serv_id_4;                                            \
+    clazz[3].serv_data = serv_data_4;                                        \
+    clazz[4].serv_id = NULL;                                                 \
+    clazz[4].serv_data = NULL;                                               \
+    *output_class = clazz;                                                   \
+    return FT_Err_Ok;                                                        \
+  } 
+
+#define FT_DEFINE_SERVICEDESCREC5(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2, serv_id_3, serv_data_3, serv_id_4,           \
+        serv_data_4, serv_id_5, serv_data_5)                                 \
+  void                                                                       \
+  FT_Destroy_Class_##class_( FT_Library library,                             \
+                             FT_ServiceDescRec* clazz )                      \
+  {                                                                          \
+    FT_Memory memory = library->memory;                                      \
+    if ( clazz )                                                             \
+      FT_FREE( clazz );                                                      \
+  }                                                                          \
+                                                                             \
+  FT_Error                                                                   \
+  FT_Create_Class_##class_( FT_Library library,                              \
+                            FT_ServiceDescRec** output_class)                \
+  {                                                                          \
+    FT_ServiceDescRec*  clazz;                                               \
+    FT_Error          error;                                                 \
+    FT_Memory memory = library->memory;                                      \
+                                                                             \
+    if ( FT_ALLOC( clazz, sizeof(*clazz)*6 ) )                               \
+      return error;                                                          \
+    clazz[0].serv_id = serv_id_1;                                            \
+    clazz[0].serv_data = serv_data_1;                                        \
+    clazz[1].serv_id = serv_id_2;                                            \
+    clazz[1].serv_data = serv_data_2;                                        \
+    clazz[2].serv_id = serv_id_3;                                            \
+    clazz[2].serv_data = serv_data_3;                                        \
+    clazz[3].serv_id = serv_id_4;                                            \
+    clazz[3].serv_data = serv_data_4;                                        \
+    clazz[4].serv_id = serv_id_5;                                            \
+    clazz[4].serv_data = serv_data_5;                                        \
+    clazz[5].serv_id = NULL;                                                 \
+    clazz[5].serv_data = NULL;                                               \
+    *output_class = clazz;                                                   \
+    return FT_Err_Ok;                                                        \
+  } 
+
+#define FT_DEFINE_SERVICEDESCREC6(class_, serv_id_1, serv_data_1,            \
+        serv_id_2, serv_data_2, serv_id_3, serv_data_3,                      \
+        serv_id_4, serv_data_4, serv_id_5, serv_data_5,                      \
+        serv_id_6, serv_data_6)                                              \
+  void                                                                       \
+  FT_Destroy_Class_##class_( FT_Library library,                             \
+                             FT_ServiceDescRec* clazz )                      \
+  {                                                                          \
+    FT_Memory memory = library->memory;                                      \
+    if ( clazz )                                                             \
+      FT_FREE( clazz );                                                      \
+  }                                                                          \
+                                                                             \
+  FT_Error                                                                   \
+  FT_Create_Class_##class_( FT_Library library,                              \
+                            FT_ServiceDescRec** output_class)                \
+  {                                                                          \
+    FT_ServiceDescRec*  clazz;                                               \
+    FT_Error          error;                                                 \
+    FT_Memory memory = library->memory;                                      \
+                                                                             \
+    if ( FT_ALLOC( clazz, sizeof(*clazz)*7 ) )                               \
+      return error;                                                          \
+    clazz[0].serv_id = serv_id_1;                                            \
+    clazz[0].serv_data = serv_data_1;                                        \
+    clazz[1].serv_id = serv_id_2;                                            \
+    clazz[1].serv_data = serv_data_2;                                        \
+    clazz[2].serv_id = serv_id_3;                                            \
+    clazz[2].serv_data = serv_data_3;                                        \
+    clazz[3].serv_id = serv_id_4;                                            \
+    clazz[3].serv_data = serv_data_4;                                        \
+    clazz[4].serv_id = serv_id_5;                                            \
+    clazz[4].serv_data = serv_data_5;                                        \
+    clazz[5].serv_id = serv_id_6;                                            \
+    clazz[5].serv_data = serv_data_6;                                        \
+    clazz[6].serv_id = NULL;                                                 \
+    clazz[6].serv_data = NULL;                                               \
+    *output_class = clazz;                                                   \
+    return FT_Err_Ok;                                                        \
+  } 
+#endif /* FT_CONFIG_OPTION_PIC */ 
 
   /*
    *  Parse a list of FT_ServiceDescRec descriptors and look for
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index 4d38a46..e9b383a 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -31,16 +31,19 @@
 FT_TRACE_DEF( objs )      /* base objects            (ftobjs.c)   */
 FT_TRACE_DEF( outline )   /* outline management      (ftoutln.c)  */
 FT_TRACE_DEF( glyph )     /* glyph management        (ftglyph.c)  */
+FT_TRACE_DEF( gloader )   /* glyph loader            (ftgloadr.c) */
 
 FT_TRACE_DEF( raster )    /* monochrome rasterizer   (ftraster.c) */
 FT_TRACE_DEF( smooth )    /* anti-aliasing raster    (ftgrays.c)  */
 FT_TRACE_DEF( mm )        /* MM interface            (ftmm.c)     */
 FT_TRACE_DEF( raccess )   /* resource fork accessor  (ftrfork.c)  */
+FT_TRACE_DEF( synth )     /* bold/slant synthesizer  (ftsynth.c)  */
 
   /* Cache sub-system */
 FT_TRACE_DEF( cache )     /* cache sub-system        (ftcache.c, etc.) */
 
   /* SFNT driver components */
+FT_TRACE_DEF( sfdriver )  /* SFNT font driver        (sfdriver.c) */
 FT_TRACE_DEF( sfobjs )    /* SFNT object handler     (sfobjs.c)   */
 FT_TRACE_DEF( ttcmap )    /* charmap handler         (ttcmap.c)   */
 FT_TRACE_DEF( ttkern )    /* kerning handler         (ttkern.c)   */
@@ -48,6 +51,7 @@
 FT_TRACE_DEF( ttmtx )     /* metrics-related tables  (ttmtx.c)    */
 FT_TRACE_DEF( ttpost )    /* PS table processing     (ttpost.c)   */
 FT_TRACE_DEF( ttsbit )    /* TrueType sbit handling  (ttsbit.c)   */
+FT_TRACE_DEF( ttbdf )     /* TrueType embedded BDF   (ttbdf.c)    */
 
   /* TrueType driver components */
 FT_TRACE_DEF( ttdriver )  /* TT font driver          (ttdriver.c) */
@@ -58,6 +62,7 @@
 FT_TRACE_DEF( ttgxvar )   /* TrueType GX var handler (ttgxvar.c)  */
 
   /* Type 1 driver components */
+FT_TRACE_DEF( t1afm )
 FT_TRACE_DEF( t1driver )
 FT_TRACE_DEF( t1gload )
 FT_TRACE_DEF( t1hint )
diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h
index 27d5dc5..f500a65 100644
--- a/include/freetype/internal/internal.h
+++ b/include/freetype/internal/internal.h
@@ -25,6 +25,7 @@
 
 
 #define FT_INTERNAL_OBJECTS_H             <freetype/internal/ftobjs.h>
+#define FT_INTERNAL_PIC_H                 <freetype/internal/ftpic.h>
 #define FT_INTERNAL_STREAM_H              <freetype/internal/ftstream.h>
 #define FT_INTERNAL_MEMORY_H              <freetype/internal/ftmemory.h>
 #define FT_INTERNAL_DEBUG_H               <freetype/internal/ftdebug.h>
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index 7fb4c99..a96e0df 100644
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -360,7 +360,7 @@
     FT_Error
     (*to_bytes)( PS_Parser  parser,
                  FT_Byte*   bytes,
-                 FT_Long    max_bytes,
+                 FT_Offset  max_bytes,
                  FT_Long*   pnum_bytes,
                  FT_Bool    delimiters );
 
@@ -533,8 +533,6 @@
   /*                                                                       */
   /*    max_contours :: Maximal number of contours in builder outline.     */
   /*                                                                       */
-  /*    last         :: The last point position.                           */
-  /*                                                                       */
   /*    pos_x        :: The horizontal translation (if composite glyph).   */
   /*                                                                       */
   /*    pos_y        :: The vertical translation (if composite glyph).     */
@@ -567,8 +565,6 @@
     FT_Outline*     base;
     FT_Outline*     current;
 
-    FT_Vector       last;
-
     FT_Pos          pos_x;
     FT_Pos          pos_y;
 
@@ -579,7 +575,6 @@
     T1_ParseState   parse_state;
     FT_Bool         load_points;
     FT_Bool         no_recurse;
-    FT_Bool         shift;
 
     FT_Bool         metrics_only;
 
@@ -694,9 +689,11 @@
     T1_Decoder_Callback  parse_callback;
     T1_Decoder_FuncsRec  funcs;
 
-    FT_Int*              buildchar;
+    FT_Long*             buildchar;
     FT_UInt              len_buildchar;
 
+    FT_Bool              seac;
+
   } T1_DecoderRec;
 
 
@@ -758,7 +755,7 @@
 
     FT_Int
     (*get_index)( const char*  name,
-                  FT_UInt      len,
+                  FT_Offset    len,
                   void*        user_data );
 
     void*         user_data;
diff --git a/include/freetype/internal/pshints.h b/include/freetype/internal/pshints.h
index 48452c0..0c35765 100644
--- a/include/freetype/internal/pshints.h
+++ b/include/freetype/internal/pshints.h
@@ -6,7 +6,7 @@
 /*    recorders (specification only).  These are used to support native    */
 /*    T1/T2 hints in the `type1', `cid', and `cff' font drivers.           */
 /*                                                                         */
-/*  Copyright 2001, 2002, 2003, 2005, 2006, 2007 by                        */
+/*  Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 by                  */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -157,7 +157,8 @@
    *     0 for horizontal stems (hstem), 1 for vertical ones (vstem).
    *
    *   coords ::
-   *     Array of 2 integers, used as (position,length) stem descriptor.
+   *     Array of 2 coordinates in 16.16 format, used as (position,length)
+   *     stem descriptor.
    *
    * @note:
    *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use
@@ -175,9 +176,9 @@
    *
    */
   typedef void
-  (*T1_Hints_SetStemFunc)( T1_Hints  hints,
-                           FT_UInt   dimension,
-                           FT_Long*  coords );
+  (*T1_Hints_SetStemFunc)( T1_Hints   hints,
+                           FT_UInt    dimension,
+                           FT_Fixed*  coords );
 
 
   /*************************************************************************
@@ -197,8 +198,8 @@
    *     0 for horizontal stems, 1 for vertical ones.
    *
    *   coords ::
-   *     An array of 6 integers, holding 3 (position,length) pairs for the
-   *     counter-controlled stems.
+   *     An array of 6 values in 16.16 format, holding 3 (position,length)
+   *     pairs for the counter-controlled stems.
    *
    * @note:
    *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use
@@ -209,9 +210,9 @@
    *
    */
   typedef void
-  (*T1_Hints_SetStem3Func)( T1_Hints  hints,
-                            FT_UInt   dimension,
-                            FT_Long*  coords );
+  (*T1_Hints_SetStem3Func)( T1_Hints   hints,
+                            FT_UInt    dimension,
+                            FT_Fixed*  coords );
 
 
   /*************************************************************************
@@ -446,7 +447,7 @@
    *     The number of stems.
    *
    *   coords ::
-   *     An array of `count' (position,length) pairs.
+   *     An array of `count' (position,length) pairs in 16.16 format.
    *
    * @note:
    *   Use vertical coordinates (y) for horizontal stems (dim=0).  Use
@@ -678,6 +679,30 @@
 
   typedef PSHinter_Interface*  PSHinter_Service;
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_,             \
+                                     get_t1_funcs_, get_t2_funcs_)           \
+  static const PSHinter_Interface class_ =                                   \
+  {                                                                          \
+    get_globals_funcs_, get_t1_funcs_, get_t2_funcs_                         \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_PSHINTER_INTERFACE(class_, get_globals_funcs_,             \
+                                     get_t1_funcs_, get_t2_funcs_)           \
+  void                                                                       \
+  FT_Init_Class_##class_( FT_Library library,                                \
+                          PSHinter_Interface*  clazz)                        \
+  {                                                                          \
+    FT_UNUSED(library);                                                      \
+    clazz->get_globals_funcs = get_globals_funcs_;                           \
+    clazz->get_t1_funcs = get_t1_funcs_;                                     \
+    clazz->get_t2_funcs = get_t2_funcs_;                                     \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
 
 FT_END_HEADER
 
diff --git a/include/freetype/internal/services/svbdf.h b/include/freetype/internal/services/svbdf.h
index 0f7fc61..9264239 100644
--- a/include/freetype/internal/services/svbdf.h
+++ b/include/freetype/internal/services/svbdf.h
@@ -45,6 +45,26 @@
     FT_BDF_GetPropertyFunc   get_property;
   };
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \
+  static const FT_Service_BDFRec class_ =                                \
+  {                                                                      \
+    get_charset_id_, get_property_                                       \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_BDFRec(class_, get_charset_id_, get_property_) \
+  void                                                                   \
+  FT_Init_Class_##class_( FT_Service_BDFRec*  clazz )                    \
+  {                                                                      \
+    clazz->get_charset_id = get_charset_id_;                             \
+    clazz->get_property = get_property_;                                 \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/services/svcid.h b/include/freetype/internal/services/svcid.h
index 2e391f2..9b874b5 100644
--- a/include/freetype/internal/services/svcid.h
+++ b/include/freetype/internal/services/svcid.h
@@ -46,6 +46,31 @@
     FT_CID_GetCIDFromGlyphIndexFunc           get_cid_from_glyph_index;
   };
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_,                           \
+        get_is_cid_, get_cid_from_glyph_index_ )                             \
+  static const FT_Service_CIDRec class_ =                                    \
+  {                                                                          \
+    get_ros_, get_is_cid_, get_cid_from_glyph_index_                         \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_CIDREC(class_, get_ros_,                           \
+        get_is_cid_, get_cid_from_glyph_index_ )                             \
+  void                                                                       \
+  FT_Init_Class_##class_( FT_Library library,                                \
+                          FT_Service_CIDRec* clazz)                          \
+  {                                                                          \
+    FT_UNUSED(library);                                                      \
+    clazz->get_ros = get_ros_;                                               \
+    clazz->get_is_cid = get_is_cid_;                                         \
+    clazz->get_cid_from_glyph_index = get_cid_from_glyph_index_;             \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/services/svgldict.h b/include/freetype/internal/services/svgldict.h
index e5e56b2..d66a41d 100644
--- a/include/freetype/internal/services/svgldict.h
+++ b/include/freetype/internal/services/svgldict.h
@@ -51,6 +51,28 @@
     FT_GlyphDict_NameIndexFunc  name_index;  /* optional */
   };
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \
+  static const FT_Service_GlyphDictRec class_ =                        \
+  {                                                                    \
+    get_name_, name_index_                                             \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_GLYPHDICTREC(class_, get_name_, name_index_) \
+  void                                                                 \
+  FT_Init_Class_##class_( FT_Library library,                          \
+                          FT_Service_GlyphDictRec* clazz)              \
+  {                                                                    \
+    FT_UNUSED(library);                                                \
+    clazz->get_name = get_name_;                                       \
+    clazz->name_index = name_index_;                                   \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h
index 8a99ec4..66e1da2 100644
--- a/include/freetype/internal/services/svmm.h
+++ b/include/freetype/internal/services/svmm.h
@@ -68,6 +68,31 @@
     FT_Set_Var_Design_Func  set_var_design;
   };
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_,   \
+        set_mm_blend_, get_mm_var_, set_var_design_)                         \
+  static const FT_Service_MultiMastersRec class_ =                           \
+  {                                                                          \
+    get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_     \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_MULTIMASTERSREC(class_, get_mm_, set_mm_design_,   \
+        set_mm_blend_, get_mm_var_, set_var_design_)                         \
+  void                                                                       \
+  FT_Init_Class_##class_( FT_Service_MultiMastersRec*  clazz )               \
+  {                                                                          \
+    clazz->get_mm = get_mm_;                                                 \
+    clazz->set_mm_design = set_mm_design_;                                   \
+    clazz->set_mm_blend = set_mm_blend_;                                     \
+    clazz->get_mm_var = get_mm_var_;                                         \
+    clazz->set_var_design = set_var_design_;                                 \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/services/svpostnm.h b/include/freetype/internal/services/svpostnm.h
index 282da68..106c54f 100644
--- a/include/freetype/internal/services/svpostnm.h
+++ b/include/freetype/internal/services/svpostnm.h
@@ -46,6 +46,27 @@
     FT_PsName_GetFunc  get_ps_font_name;
   };
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \
+  static const FT_Service_PsFontNameRec class_ =                   \
+  {                                                                \
+    get_ps_font_name_                                              \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_PSFONTNAMEREC(class_, get_ps_font_name_) \
+  void                                                             \
+  FT_Init_Class_##class_( FT_Library library,                      \
+                          FT_Service_PsFontNameRec* clazz)         \
+  {                                                                \
+    FT_UNUSED(library);                                            \
+    clazz->get_ps_font_name = get_ps_font_name_;                   \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/services/svpscmap.h b/include/freetype/internal/services/svpscmap.h
index c4e25ed..961030c 100644
--- a/include/freetype/internal/services/svpscmap.h
+++ b/include/freetype/internal/services/svpscmap.h
@@ -98,7 +98,7 @@
   (*PS_Unicodes_CharIndexFunc)( PS_Unicodes  unicodes,
                                 FT_UInt32    unicode );
 
-  typedef FT_ULong
+  typedef FT_UInt32
   (*PS_Unicodes_CharNextFunc)( PS_Unicodes  unicodes,
                                FT_UInt32   *unicode );
 
@@ -117,6 +117,41 @@
     const unsigned short*      adobe_expert_encoding;
   };
 
+
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \
+        unicodes_char_index_, unicodes_char_next_, macintosh_name_,          \
+        adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_)     \
+  static const FT_Service_PsCMapsRec class_ =                                \
+  {                                                                          \
+    unicode_value_, unicodes_init_,                                          \
+    unicodes_char_index_, unicodes_char_next_, macintosh_name_,              \
+    adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_          \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_PSCMAPSREC(class_, unicode_value_, unicodes_init_, \
+        unicodes_char_index_, unicodes_char_next_, macintosh_name_,          \
+        adobe_std_strings_, adobe_std_encoding_, adobe_expert_encoding_)     \
+  void                                                                       \
+  FT_Init_Class_##class_( FT_Library library,                                \
+                          FT_Service_PsCMapsRec* clazz)                      \
+  {                                                                          \
+    FT_UNUSED(library);                                                      \
+    clazz->unicode_value = unicode_value_;                                   \
+    clazz->unicodes_init = unicodes_init_;                                   \
+    clazz->unicodes_char_index = unicodes_char_index_;                       \
+    clazz->unicodes_char_next = unicodes_char_next_;                         \
+    clazz->macintosh_name = macintosh_name_;                                 \
+    clazz->adobe_std_strings = adobe_std_strings_;                           \
+    clazz->adobe_std_encoding = adobe_std_encoding_;                         \
+    clazz->adobe_expert_encoding = adobe_expert_encoding_;                   \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/services/svpsinfo.h b/include/freetype/internal/services/svpsinfo.h
index 124c6f9..91ba91e 100644
--- a/include/freetype/internal/services/svpsinfo.h
+++ b/include/freetype/internal/services/svpsinfo.h
@@ -53,6 +53,33 @@
     PS_GetFontPrivateFunc  ps_get_font_private;
   };
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_,      \
+        ps_get_font_extra_, has_glyph_names_, get_font_private_) \
+  static const FT_Service_PsInfoRec class_ =                     \
+  {                                                              \
+    get_font_info_, ps_get_font_extra_, has_glyph_names_,        \
+    get_font_private_                                            \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_,      \
+        ps_get_font_extra_, has_glyph_names_, get_font_private_) \
+  void                                                           \
+  FT_Init_Class_##class_( FT_Library library,                    \
+                          FT_Service_PsInfoRec*  clazz)          \
+  {                                                              \
+    FT_UNUSED(library);                                          \
+    clazz->ps_get_font_info = get_font_info_;                    \
+    clazz->ps_get_font_extra = ps_get_font_extra_;               \
+    clazz->ps_has_glyph_names = has_glyph_names_;                \
+    clazz->ps_get_font_private = get_font_private_;              \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/services/svsfnt.h b/include/freetype/internal/services/svsfnt.h
index b4a85d9..30bb162 100644
--- a/include/freetype/internal/services/svsfnt.h
+++ b/include/freetype/internal/services/svsfnt.h
@@ -58,6 +58,7 @@
   (*FT_SFNT_TableInfoFunc)( FT_Face    face,
                             FT_UInt    idx,
                             FT_ULong  *tag,
+                            FT_ULong  *offset,
                             FT_ULong  *length );
 
 
@@ -68,6 +69,27 @@
     FT_SFNT_TableInfoFunc  table_info;
   };
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_)  \
+  static const FT_Service_SFNT_TableRec class_ =                     \
+  {                                                                  \
+    load_, get_, info_                                               \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_SFNT_TABLEREC(class_, load_, get_, info_) \
+  void                                                              \
+  FT_Init_Class_##class_( FT_Service_SFNT_TableRec*  clazz )        \
+  {                                                                 \
+    clazz->load_table = load_;                                      \
+    clazz->get_table = get_;                                        \
+    clazz->table_info = info_;                                      \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/services/svttcmap.h b/include/freetype/internal/services/svttcmap.h
index 553ecb0..8af0035 100644
--- a/include/freetype/internal/services/svttcmap.h
+++ b/include/freetype/internal/services/svttcmap.h
@@ -1,6 +1,6 @@
 /***************************************************************************/
 /*                                                                         */
-/*  svsttcmap.h                                                            */
+/*  svttcmap.h                                                             */
 /*                                                                         */
 /*    The FreeType TrueType/sfnt cmap extra information service.           */
 /*                                                                         */
@@ -74,6 +74,27 @@
     TT_CMap_Info_GetFunc  get_cmap_info;
   };
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_)  \
+  static const FT_Service_TTCMapsRec class_ =                 \
+  {                                                           \
+    get_cmap_info_                                            \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_TTCMAPSREC(class_, get_cmap_info_) \
+  void                                                       \
+  FT_Init_Class_##class_( FT_Library library,                \
+                          FT_Service_TTCMapsRec*  clazz)     \
+  {                                                          \
+    FT_UNUSED(library);                                      \
+    clazz->get_cmap_info = get_cmap_info_;                   \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/services/svttglyf.h b/include/freetype/internal/services/svttglyf.h
index e57d484..ab2dc9a 100644
--- a/include/freetype/internal/services/svttglyf.h
+++ b/include/freetype/internal/services/svttglyf.h
@@ -37,6 +37,25 @@
     TT_Glyf_GetLocationFunc  get_location;
   };
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ )   \
+  static const FT_Service_TTGlyfRec class_ =                  \
+  {                                                           \
+    get_location_                                             \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_SERVICE_TTGLYFREC(class_, get_location_ )   \
+  void                                                        \
+  FT_Init_Class_##class_( FT_Service_TTGlyfRec*  clazz )      \
+  {                                                           \
+    clazz->get_location = get_location_;                      \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
+
   /* */
 
 
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 7e8f684..6326deb 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -753,6 +753,141 @@
   /* transitional */
   typedef SFNT_Interface*   SFNT_Service;
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a) \
+  a, 
+#else
+  #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a)
+#endif
+#define FT_INTERNAL(a) \
+  a, 
+
+#define FT_DEFINE_SFNT_INTERFACE(class_,                                     \
+    goto_table_, init_face_, load_face_, done_face_, get_interface_,         \
+    load_any_, load_sfnt_header_, load_directory_, load_head_,               \
+    load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_,               \
+    load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_,                \
+    load_kern_, load_gasp_, load_pclt_, load_bhed_,                          \
+    set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_,               \
+    load_sbit_metrics_, load_sbit_image_, free_sbits_stub_,                  \
+    get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_,      \
+    get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_,        \
+    set_sbit_strike_, load_strike_metrics_, get_metrics_ )                   \
+  static const SFNT_Interface class_ =                                       \
+  {                                                                          \
+    FT_INTERNAL(goto_table_) \
+    FT_INTERNAL(init_face_) \
+    FT_INTERNAL(load_face_) \
+    FT_INTERNAL(done_face_) \
+    FT_INTERNAL(get_interface_) \
+    FT_INTERNAL(load_any_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory_) \
+    FT_INTERNAL(load_head_) \
+    FT_INTERNAL(load_hhea_) \
+    FT_INTERNAL(load_cmap_) \
+    FT_INTERNAL(load_maxp_) \
+    FT_INTERNAL(load_os2_) \
+    FT_INTERNAL(load_post_) \
+    FT_INTERNAL(load_name_) \
+    FT_INTERNAL(free_name_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub_) \
+    FT_INTERNAL(load_kern_) \
+    FT_INTERNAL(load_gasp_) \
+    FT_INTERNAL(load_pclt_) \
+    FT_INTERNAL(load_bhed_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics_) \
+    FT_INTERNAL(load_sbit_image_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub_) \
+    FT_INTERNAL(get_psname_) \
+    FT_INTERNAL(free_psnames_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub_) \
+    FT_INTERNAL(get_kerning_) \
+    FT_INTERNAL(load_font_dir_) \
+    FT_INTERNAL(load_hmtx_) \
+    FT_INTERNAL(load_eblc_) \
+    FT_INTERNAL(free_eblc_) \
+    FT_INTERNAL(set_sbit_strike_) \
+    FT_INTERNAL(load_strike_metrics_) \
+    FT_INTERNAL(get_metrics_) \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
+#define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_) \
+  clazz->a = a_;
+#else
+  #define FT_DEFINE_DRIVERS_OLD_INTERNAL(a, a_)
+#endif
+#define FT_INTERNAL(a, a_) \
+  clazz->a = a_;
+
+#define FT_DEFINE_SFNT_INTERFACE(class_,                                     \
+    goto_table_, init_face_, load_face_, done_face_, get_interface_,         \
+    load_any_, load_sfnt_header_, load_directory_, load_head_,               \
+    load_hhea_, load_cmap_, load_maxp_, load_os2_, load_post_,               \
+    load_name_, free_name_, load_hdmx_stub_, free_hdmx_stub_,                \
+    load_kern_, load_gasp_, load_pclt_, load_bhed_,                          \
+    set_sbit_strike_stub_, load_sbits_stub_, find_sbit_image_,               \
+    load_sbit_metrics_, load_sbit_image_, free_sbits_stub_,                  \
+    get_psname_, free_psnames_, load_charmap_stub_, free_charmap_stub_,      \
+    get_kerning_, load_font_dir_, load_hmtx_, load_eblc_, free_eblc_,        \
+    set_sbit_strike_, load_strike_metrics_, get_metrics_ )                   \
+  void                                                                       \
+  FT_Init_Class_##class_( FT_Library library, SFNT_Interface*  clazz )       \
+  {                                                                          \
+    FT_UNUSED(library);                                                      \
+    FT_INTERNAL(goto_table,goto_table_) \
+    FT_INTERNAL(init_face,init_face_) \
+    FT_INTERNAL(load_face,load_face_) \
+    FT_INTERNAL(done_face,done_face_) \
+    FT_INTERNAL(get_interface,get_interface_) \
+    FT_INTERNAL(load_any,load_any_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sfnt_header,load_sfnt_header_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_directory,load_directory_) \
+    FT_INTERNAL(load_head,load_head_) \
+    FT_INTERNAL(load_hhea,load_hhea_) \
+    FT_INTERNAL(load_cmap,load_cmap_) \
+    FT_INTERNAL(load_maxp,load_maxp_) \
+    FT_INTERNAL(load_os2,load_os2_) \
+    FT_INTERNAL(load_post,load_post_) \
+    FT_INTERNAL(load_name,load_name_) \
+    FT_INTERNAL(free_name,free_name_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_hdmx_stub,load_hdmx_stub_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_hdmx_stub,free_hdmx_stub_) \
+    FT_INTERNAL(load_kern,load_kern_) \
+    FT_INTERNAL(load_gasp,load_gasp_) \
+    FT_INTERNAL(load_pclt,load_pclt_) \
+    FT_INTERNAL(load_bhed,load_bhed_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(set_sbit_strike_stub,set_sbit_strike_stub_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbits_stub,load_sbits_stub_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(find_sbit_image,find_sbit_image_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_sbit_metrics,load_sbit_metrics_) \
+    FT_INTERNAL(load_sbit_image,load_sbit_image_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_sbits_stub,free_sbits_stub_) \
+    FT_INTERNAL(get_psname,get_psname_) \
+    FT_INTERNAL(free_psnames,free_psnames_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(load_charmap_stub,load_charmap_stub_) \
+    FT_DEFINE_DRIVERS_OLD_INTERNAL(free_charmap_stub,free_charmap_stub_) \
+    FT_INTERNAL(get_kerning,get_kerning_) \
+    FT_INTERNAL(load_font_dir,load_font_dir_) \
+    FT_INTERNAL(load_hmtx,load_hmtx_) \
+    FT_INTERNAL(load_eblc,load_eblc_) \
+    FT_INTERNAL(free_eblc,free_eblc_) \
+    FT_INTERNAL(set_sbit_strike,set_sbit_strike_) \
+    FT_INTERNAL(load_strike_metrics,load_strike_metrics_) \
+    FT_INTERNAL(get_metrics,get_metrics_) \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
 
 FT_END_HEADER
 
diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h
index ff021b0..5f73063 100644
--- a/include/freetype/internal/t1types.h
+++ b/include/freetype/internal/t1types.h
@@ -58,7 +58,9 @@
   /*                                                                       */
   /*    code_first :: The lowest valid character code in the encoding.     */
   /*                                                                       */
-  /*    code_last  :: The highest valid character code in the encoding.    */
+  /*    code_last  :: The highest valid character code in the encoding     */
+  /*                  + 1. When equal to code_first there are no valid     */
+  /*                  character codes.                                     */
   /*                                                                       */
   /*    char_index :: An array of corresponding glyph indices.             */
   /*                                                                       */
@@ -230,7 +232,7 @@
     /* undocumented, optional: has the same meaning as len_buildchar */
     /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25    */
     FT_UInt          len_buildchar;
-    FT_Int*          buildchar;
+    FT_Long*         buildchar;
 
     /* since version 2.1 - interface to PostScript hinter */
     const void*     pshinter;
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 85fc27f..acbb863 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -902,7 +902,7 @@
     FT_Byte*   table;
     FT_Byte*   table_end;
     FT_Byte*   strings;
-    FT_UInt32  strings_size;
+    FT_ULong   strings_size;
     FT_UInt    num_strikes;
     FT_Bool    loaded;
 
@@ -1401,7 +1401,7 @@
     FT_Byte*              vert_metrics;
     FT_ULong              vert_metrics_size;
 
-    FT_UInt               num_locations;
+    FT_ULong              num_locations; /* in broken TTF, gid > 0xFFFF */ 
     FT_Byte*              glyph_locations;
 
     FT_Byte*              hdmx_table;
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index de3ce11..ae64422 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for CJK script (body).                  */
 /*                                                                         */
-/*  Copyright 2006, 2007, 2008 by                                          */
+/*  Copyright 2006, 2007, 2008, 2009 by                                    */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -58,9 +58,12 @@
 
     if ( FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
       face->charmap = NULL;
-
+    else
+    {
     /* latin's version would suffice */
     af_latin_metrics_init_widths( metrics, face, 0x7530 );
+      af_latin_metrics_check_digits( metrics, face );
+    }
 
     FT_Set_Charmap( face, oldmap );
 
@@ -1017,7 +1020,7 @@
     AF_AxisHints  axis       = &hints->axis[dim];
     AF_Edge       edges      = axis->edges;
     AF_Edge       edge_limit = edges + axis->num_edges;
-    FT_Int        n_edges;
+    FT_PtrDist    n_edges;
     AF_Edge       edge;
     AF_Edge       anchor   = 0;
     FT_Pos        delta    = 0;
@@ -1441,35 +1444,33 @@
   static const AF_Script_UniRangeRec  af_cjk_uniranges[] =
   {
 #if 0
-    {  0x0100UL,  0xFFFFUL },  /* why this? */
+    AF_UNIRANGE_REC(  0x0100UL,  0xFFFFUL ),  /* why this? */
 #endif
-    {  0x2E80UL,  0x2EFFUL },  /* CJK Radicals Supplement                 */
-    {  0x2F00UL,  0x2FDFUL },  /* Kangxi Radicals                         */
-    {  0x3000UL,  0x303FUL },  /* CJK Symbols and Punctuation             */
-    {  0x3040UL,  0x309FUL },  /* Hiragana                                */
-    {  0x30A0UL,  0x30FFUL },  /* Katakana                                */
-    {  0x3100UL,  0x312FUL },  /* Bopomofo                                */
-    {  0x3130UL,  0x318FUL },  /* Hangul Compatibility Jamo               */
-    {  0x31A0UL,  0x31BFUL },  /* Bopomofo Extended                       */
-    {  0x31C0UL,  0x31EFUL },  /* CJK Strokes                             */
-    {  0x31F0UL,  0x31FFUL },  /* Katakana Phonetic Extensions            */
-    {  0x3200UL,  0x32FFUL },  /* Enclosed CJK Letters and Months         */
-    {  0x3300UL,  0x33FFUL },  /* CJK Compatibility                       */
-    {  0x3400UL,  0x4DBFUL },  /* CJK Unified Ideographs Extension A      */
-    {  0x4DC0UL,  0x4DFFUL },  /* Yijing Hexagram Symbols                 */
-    {  0x4E00UL,  0x9FFFUL },  /* CJK Unified Ideographs                  */
-    {  0xF900UL,  0xFAFFUL },  /* CJK Compatibility Ideographs            */
-    {  0xFE30UL,  0xFE4FUL },  /* CJK Compatibility Forms                 */
-    {  0xFF00UL,  0xFFEFUL },  /* Halfwidth and Fullwidth Forms           */
-    { 0x20000UL, 0x2A6DFUL },  /* CJK Unified Ideographs Extension B      */
-    { 0x2F800UL, 0x2FA1FUL },  /* CJK Compatibility Ideographs Supplement */
-    {       0UL,       0UL }
+    AF_UNIRANGE_REC(  0x2E80UL,  0x2EFFUL ),  /* CJK Radicals Supplement                 */
+    AF_UNIRANGE_REC(  0x2F00UL,  0x2FDFUL ),  /* Kangxi Radicals                         */
+    AF_UNIRANGE_REC(  0x3000UL,  0x303FUL ),  /* CJK Symbols and Punctuation             */
+    AF_UNIRANGE_REC(  0x3040UL,  0x309FUL ),  /* Hiragana                                */
+    AF_UNIRANGE_REC(  0x30A0UL,  0x30FFUL ),  /* Katakana                                */
+    AF_UNIRANGE_REC(  0x3100UL,  0x312FUL ),  /* Bopomofo                                */
+    AF_UNIRANGE_REC(  0x3130UL,  0x318FUL ),  /* Hangul Compatibility Jamo               */
+    AF_UNIRANGE_REC(  0x31A0UL,  0x31BFUL ),  /* Bopomofo Extended                       */
+    AF_UNIRANGE_REC(  0x31C0UL,  0x31EFUL ),  /* CJK Strokes                             */
+    AF_UNIRANGE_REC(  0x31F0UL,  0x31FFUL ),  /* Katakana Phonetic Extensions            */
+    AF_UNIRANGE_REC(  0x3200UL,  0x32FFUL ),  /* Enclosed CJK Letters and Months         */
+    AF_UNIRANGE_REC(  0x3300UL,  0x33FFUL ),  /* CJK Compatibility                       */
+    AF_UNIRANGE_REC(  0x3400UL,  0x4DBFUL ),  /* CJK Unified Ideographs Extension A      */
+    AF_UNIRANGE_REC(  0x4DC0UL,  0x4DFFUL ),  /* Yijing Hexagram Symbols                 */
+    AF_UNIRANGE_REC(  0x4E00UL,  0x9FFFUL ),  /* CJK Unified Ideographs                  */
+    AF_UNIRANGE_REC(  0xF900UL,  0xFAFFUL ),  /* CJK Compatibility Ideographs            */
+    AF_UNIRANGE_REC(  0xFE30UL,  0xFE4FUL ),  /* CJK Compatibility Forms                 */
+    AF_UNIRANGE_REC(  0xFF00UL,  0xFFEFUL ),  /* Halfwidth and Fullwidth Forms           */
+    AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ),  /* CJK Unified Ideographs Extension B      */
+    AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ),  /* CJK Compatibility Ideographs Supplement */
+    AF_UNIRANGE_REC(       0UL,       0UL )
   };
 
 
-  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
-  af_cjk_script_class =
-  {
+  AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class,
     AF_SCRIPT_CJK,
     af_cjk_uniranges,
 
@@ -1481,19 +1482,17 @@
 
     (AF_Script_InitHintsFunc)   af_cjk_hints_init,
     (AF_Script_ApplyHintsFunc)  af_cjk_hints_apply
-  };
+  )
 
 #else /* !AF_CONFIG_OPTION_CJK */
 
   static const AF_Script_UniRangeRec  af_cjk_uniranges[] =
   {
-    { 0, 0 }
+    AF_UNIRANGE_REC( 0UL, 0UL )
   };
 
 
-  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
-  af_cjk_script_class =
-  {
+  AF_DEFINE_SCRIPT_CLASS(af_cjk_script_class,
     AF_SCRIPT_CJK,
     af_cjk_uniranges,
 
@@ -1505,7 +1504,7 @@
 
     (AF_Script_InitHintsFunc)   NULL,
     (AF_Script_ApplyHintsFunc)  NULL
-  };
+  )
 
 #endif /* !AF_CONFIG_OPTION_CJK */
 
diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h
index 9f77fda..0b20d4a 100644
--- a/src/autofit/afcjk.h
+++ b/src/autofit/afcjk.h
@@ -27,8 +27,7 @@
 
   /* the CJK-specific script class */
 
-  FT_CALLBACK_TABLE const AF_ScriptClassRec
-  af_cjk_script_class;
+  AF_DECLARE_SCRIPT_CLASS(af_cjk_script_class)
 
 
   FT_LOCAL( FT_Error )
diff --git a/src/autofit/afdummy.c b/src/autofit/afdummy.c
index ed96e96..42b2fcb 100644
--- a/src/autofit/afdummy.c
+++ b/src/autofit/afdummy.c
@@ -42,9 +42,7 @@
   }
 
 
-  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
-  af_dummy_script_class =
-  {
+  AF_DEFINE_SCRIPT_CLASS(af_dummy_script_class,
     AF_SCRIPT_NONE,
     NULL,
 
@@ -56,7 +54,7 @@
 
     (AF_Script_InitHintsFunc)   af_dummy_hints_init,
     (AF_Script_ApplyHintsFunc)  af_dummy_hints_apply
-  };
+  )
 
 
 /* END */
diff --git a/src/autofit/afdummy.h b/src/autofit/afdummy.h
index 2a5faf8..b69ef43 100644
--- a/src/autofit/afdummy.h
+++ b/src/autofit/afdummy.h
@@ -29,8 +29,7 @@
   *  be performed.  This is the default for non-latin glyphs!
   */
 
-  FT_CALLBACK_TABLE const AF_ScriptClassRec
-  af_dummy_script_class;
+  AF_DECLARE_SCRIPT_CLASS(af_dummy_script_class)
 
 /* */
 
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index bfb9091..ac29361 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter routines to compute global hinting values (body).        */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008 by                        */
+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by                  */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -21,6 +21,7 @@
 #include "aflatin.h"
 #include "afcjk.h"
 #include "afindic.h"
+#include "afpic.h"
 
 #include "aferrors.h"
 
@@ -28,6 +29,11 @@
 #include "aflatin2.h"
 #endif
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+/* when updating this table, don't forget to update 
+  AF_SCRIPT_CLASSES_COUNT and autofit_module_class_pic_init */
+
   /* populate this list when you add new scripts */
   static AF_ScriptClass const  af_script_classes[] =
   {
@@ -41,10 +47,14 @@
     NULL  /* do not remove */
   };
 
+#endif /* FT_CONFIG_OPTION_PIC */
+
   /* index of default script in `af_script_classes' */
 #define AF_SCRIPT_LIST_DEFAULT  2
-  /* indicates an uncovered glyph                   */
-#define AF_SCRIPT_LIST_NONE   255
+  /* a bit mask indicating an uncovered glyph       */
+#define AF_SCRIPT_LIST_NONE     0x7F
+  /* if this flag is set, we have an ASCII digit    */
+#define AF_DIGIT                0x80
 
 
   /*
@@ -55,7 +65,7 @@
   typedef struct  AF_FaceGlobalsRec_
   {
     FT_Face           face;
-    FT_UInt           glyph_count;    /* same as face->num_glyphs */
+    FT_Long           glyph_count;    /* same as face->num_glyphs */
     FT_Byte*          glyph_scripts;
 
     AF_ScriptMetrics  metrics[AF_SCRIPT_MAX];
@@ -72,7 +82,7 @@
     FT_Face     face        = globals->face;
     FT_CharMap  old_charmap = face->charmap;
     FT_Byte*    gscripts    = globals->glyph_scripts;
-    FT_UInt     ss;
+    FT_UInt     ss, i;
 
 
     /* the value 255 means `uncovered glyph' */
@@ -92,9 +102,9 @@
     }
 
     /* scan each script in a Unicode charmap */
-    for ( ss = 0; af_script_classes[ss]; ss++ )
+    for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ )
     {
-      AF_ScriptClass      clazz = af_script_classes[ss];
+      AF_ScriptClass      clazz = AF_SCRIPT_CLASSES_GET[ss];
       AF_Script_UniRange  range;
 
 
@@ -114,7 +124,7 @@
         gindex = FT_Get_Char_Index( face, charcode );
 
         if ( gindex != 0                             &&
-             gindex < globals->glyph_count           &&
+             gindex < (FT_ULong)globals->glyph_count &&
              gscripts[gindex] == AF_SCRIPT_LIST_NONE )
         {
           gscripts[gindex] = (FT_Byte)ss;
@@ -127,7 +137,7 @@
           if ( gindex == 0 || charcode > range->last )
             break;
 
-          if ( gindex < globals->glyph_count           &&
+          if ( gindex < (FT_ULong)globals->glyph_count &&
                gscripts[gindex] == AF_SCRIPT_LIST_NONE )
           {
             gscripts[gindex] = (FT_Byte)ss;
@@ -136,13 +146,23 @@
       }
     }
 
+    /* mark ASCII digits */
+    for ( i = 0x30; i <= 0x39; i++ )
+    {
+      FT_UInt  gindex = FT_Get_Char_Index( face, i );
+
+
+      if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count )
+        gscripts[gindex] |= AF_DIGIT;
+    }
+
   Exit:
     /*
      *  By default, all uncovered glyphs are set to the latin script.
      *  XXX: Shouldn't we disable hinting or do something similar?
      */
     {
-      FT_UInt  nn;
+      FT_Long  nn;
 
 
       for ( nn = 0; nn < globals->glyph_count; nn++ )
@@ -201,7 +221,7 @@
       {
         if ( globals->metrics[nn] )
         {
-          AF_ScriptClass  clazz = af_script_classes[nn];
+          AF_ScriptClass  clazz = AF_SCRIPT_CLASSES_GET[nn];
 
 
           FT_ASSERT( globals->metrics[nn]->clazz == clazz );
@@ -232,12 +252,12 @@
     FT_UInt           gidx;
     AF_ScriptClass    clazz;
     FT_UInt           script     = options & 15;
-    const FT_UInt     script_max = sizeof ( af_script_classes ) /
-                                     sizeof ( af_script_classes[0] );
+    const FT_Offset   script_max = sizeof ( AF_SCRIPT_CLASSES_GET ) /
+                                     sizeof ( AF_SCRIPT_CLASSES_GET[0] );
     FT_Error          error      = AF_Err_Ok;
 
 
-    if ( gindex >= globals->glyph_count )
+    if ( gindex >= (FT_ULong)globals->glyph_count )
     {
       error = AF_Err_Invalid_Argument;
       goto Exit;
@@ -245,9 +265,9 @@
 
     gidx = script;
     if ( gidx == 0 || gidx + 1 >= script_max )
-      gidx = globals->glyph_scripts[gindex];
+      gidx = globals->glyph_scripts[gindex] & AF_SCRIPT_LIST_NONE;
 
-    clazz = af_script_classes[gidx];
+    clazz = AF_SCRIPT_CLASSES_GET[gidx];
     if ( script == 0 )
       script = clazz->script;
 
@@ -286,4 +306,15 @@
   }
 
 
+  FT_LOCAL_DEF( FT_Bool )
+  af_face_globals_is_digit( AF_FaceGlobals  globals,
+                            FT_UInt         gindex )
+  {
+    if ( gindex < (FT_ULong)globals->glyph_count )
+      return (FT_Bool)( globals->glyph_scripts[gindex] & AF_DIGIT );
+
+    return (FT_Bool)0;
+  }
+
+
 /* END */
diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h
index cf52c08..0d8fb5f 100644
--- a/src/autofit/afglobal.h
+++ b/src/autofit/afglobal.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter routines to compute global hinting values                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2005, 2007 by                                    */
+/*  Copyright 2003, 2004, 2005, 2007, 2009 by                              */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -56,6 +56,10 @@
   FT_LOCAL( void )
   af_face_globals_free( AF_FaceGlobals  globals );
 
+  FT_LOCAL_DEF( FT_Bool )
+  af_face_globals_is_digit( AF_FaceGlobals  globals,
+                            FT_UInt         gindex );
+
  /* */
 
 
diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
index 8ab1761..a5aec80 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -34,7 +34,7 @@
     {
       FT_Int  old_max = axis->max_segments;
       FT_Int  new_max = old_max;
-      FT_Int  big_max = FT_INT_MAX / sizeof ( *segment );
+      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) );
 
 
       if ( old_max >= big_max )
@@ -77,7 +77,7 @@
     {
       FT_Int  old_max = axis->max_edges;
       FT_Int  new_max = old_max;
-      FT_Int  big_max = FT_INT_MAX / sizeof ( *edge );
+      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) );
 
 
       if ( old_max >= big_max )
@@ -645,6 +645,7 @@
         FT_Int      contour_index = 0;
 
 
+        FT_UNUSED( first );
         for ( point = points; point < point_limit; point++, vec++, tag++ )
         {
           point->fx = (FT_Short)vec->x;
@@ -940,7 +941,7 @@
         }
 
         {
-          FT_UInt  min, max, mid;
+          FT_PtrDist  min, max, mid;
           FT_Pos   fpos;
 
 
@@ -952,7 +953,7 @@
           /* for small edge counts, a linear search is better */
           if ( max <= 8 )
           {
-            FT_UInt  nn;
+            FT_PtrDist  nn;
 
             for ( nn = 0; nn < max; nn++ )
               if ( edges[nn].fpos >= u )
diff --git a/src/autofit/afindic.c b/src/autofit/afindic.c
index 3d27f52..1d9e9ea 100644
--- a/src/autofit/afindic.c
+++ b/src/autofit/afindic.c
@@ -81,16 +81,14 @@
   static const AF_Script_UniRangeRec  af_indic_uniranges[] =
   {
 #if 0
-    { 0x0100,  0xFFFF },  /* why this? */
+    AF_UNIRANGE_REC( 0x0100UL, 0xFFFFUL ),  /* why this? */
 #endif
-    { 0x0900, 0x0DFF},    /* Indic Range */
-    { 0,       0 }
+    AF_UNIRANGE_REC( 0x0900UL, 0x0DFFUL),    /* Indic Range */
+    AF_UNIRANGE_REC(      0UL,      0UL)
   };
 
 
-  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
-  af_indic_script_class =
-  {
+  AF_DEFINE_SCRIPT_CLASS(af_indic_script_class,
     AF_SCRIPT_INDIC,
     af_indic_uniranges,
 
@@ -102,7 +100,7 @@
 
     (AF_Script_InitHintsFunc)   af_indic_hints_init,
     (AF_Script_ApplyHintsFunc)  af_indic_hints_apply
-  };
+  )
 
 #else /* !AF_CONFIG_OPTION_INDIC */
 
@@ -112,9 +110,7 @@
   };
 
 
-  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
-  af_indic_script_class =
-  {
+  AF_DEFINE_SCRIPT_CLASS(af_indic_script_class,
     AF_SCRIPT_INDIC,
     af_indic_uniranges,
 
@@ -126,7 +122,7 @@
 
     (AF_Script_InitHintsFunc)   NULL,
     (AF_Script_ApplyHintsFunc)  NULL
-  };
+  )
 
 #endif /* !AF_CONFIG_OPTION_INDIC */
 
diff --git a/src/autofit/afindic.h b/src/autofit/afindic.h
index b242b26..662a982 100644
--- a/src/autofit/afindic.h
+++ b/src/autofit/afindic.h
@@ -27,8 +27,7 @@
 
   /* the Indic-specific script class */
 
-  FT_CALLBACK_TABLE const AF_ScriptClassRec
-  af_indic_script_class;
+  AF_DECLARE_SCRIPT_CLASS(af_indic_script_class)
 
 
 /* */
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index ba59e5b..e6882d5 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for latin script (body).                */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008 by                        */
+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by                  */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,6 +16,9 @@
 /***************************************************************************/
 
 
+#include <ft2build.h>
+#include FT_ADVANCES_H
+
 #include "aflatin.h"
 #include "aferrors.h"
 
@@ -146,7 +149,8 @@
 #define AF_LATIN_MAX_TEST_CHARACTERS  12
 
 
-  static const char* const  af_latin_blue_chars[AF_LATIN_MAX_BLUES] =
+  static const char af_latin_blue_chars[AF_LATIN_MAX_BLUES]
+                                       [AF_LATIN_MAX_TEST_CHARACTERS + 1] =
   {
     "THEZOCQS",
     "HEZLOCUS",
@@ -195,7 +199,8 @@
       for ( ; p < limit && *p; p++ )
       {
         FT_UInt     glyph_index;
-        FT_Int      best_point, best_y, best_first, best_last;
+        FT_Pos      best_y; /* same as points.y */
+        FT_Int      best_point, best_first, best_last;
         FT_Vector*  points;
         FT_Bool     round = 0;
 
@@ -328,7 +333,7 @@
          *  we couldn't find a single glyph to compute this blue zone,
          *  we will simply ignore it then
          */
-        AF_LOG(( "empty!\n" ));
+        AF_LOG(( "empty\n" ));
         continue;
       }
 
@@ -379,7 +384,7 @@
         blue->flags |= AF_LATIN_BLUE_TOP;
 
       /*
-       * The following flags is used later to adjust the y and x scales
+       * The following flag is used later to adjust the y and x scales
        * in order to optimize the pixel grid alignment of the top of small
        * letters.
        */
@@ -393,6 +398,52 @@
   }
 
 
+  FT_LOCAL_DEF( void )
+  af_latin_metrics_check_digits( AF_LatinMetrics  metrics,
+                                 FT_Face          face )
+  {
+    FT_UInt   i;
+    FT_Bool   started = 0, same_width = 1;
+    FT_Fixed  advance, old_advance = 0;
+
+
+    /* check whether all ASCII digits have the same advance width; */
+    /* digit `0' is 0x30 in all supported charmaps                 */
+    for ( i = 0x30; i <= 0x39; i++ )
+    {
+      FT_UInt  glyph_index;
+
+
+      glyph_index = FT_Get_Char_Index( face, i );
+      if ( glyph_index == 0 )
+        continue;
+
+      if ( FT_Get_Advance( face, glyph_index,
+                           FT_LOAD_NO_SCALE         |
+                           FT_LOAD_NO_HINTING       |
+                           FT_LOAD_IGNORE_TRANSFORM,
+                           &advance ) )
+        continue;
+
+      if ( started )
+      {
+        if ( advance != old_advance )
+        {
+          same_width = 0;
+          break;
+        }
+      }
+      else
+      {
+        old_advance = advance;
+        started     = 1;
+      }
+    }
+
+    metrics->root.digits_have_same_width = same_width;
+  }
+
+
   FT_LOCAL_DEF( FT_Error )
   af_latin_metrics_init( AF_LatinMetrics  metrics,
                          FT_Face          face )
@@ -426,6 +477,7 @@
       /* For now, compute the standard width and height from the `o'. */
       af_latin_metrics_init_widths( metrics, face, 'o' );
       af_latin_metrics_init_blues( metrics, face );
+      af_latin_metrics_check_digits( metrics, face );
     }
 
     FT_Set_Charmap( face, oldmap );
@@ -1567,7 +1619,7 @@
             /* not hinted, appear a lot bolder or thinner than the    */
             /* vertical stems.                                        */
 
-            FT_Int  delta;
+            FT_Pos  delta;
 
 
             dist = ( dist + 22 ) & ~63;
@@ -1651,7 +1703,7 @@
     AF_AxisHints  axis       = &hints->axis[dim];
     AF_Edge       edges      = axis->edges;
     AF_Edge       edge_limit = edges + axis->num_edges;
-    FT_Int        n_edges;
+    FT_PtrDist    n_edges;
     AF_Edge       edge;
     AF_Edge       anchor     = 0;
     FT_Int        has_serifs = 0;
@@ -2127,39 +2179,37 @@
 
   static const AF_Script_UniRangeRec  af_latin_uniranges[] =
   {
-    {  0x0020  ,  0x007F   },  /* Basic Latin (no control chars) */
-    {  0x00A0  ,  0x00FF   },  /* Latin-1 Supplement (no control chars) */
-    {  0x0100  ,  0x017F   },  /* Latin Extended-A */
-    {  0x0180  ,  0x024F   },  /* Latin Extended-B */
-    {  0x0250  ,  0x02AF   },  /* IPA Extensions */
-    {  0x02B0  ,  0x02FF   },  /* Spacing Modifier Letters */
-    {  0x0300  ,  0x036F   },  /* Combining Diacritical Marks */
-    {  0x0370  ,  0x03FF   },  /* Greek and Coptic */
-    {  0x0400  ,  0x04FF   },  /* Cyrillic */
-    {  0x0500  ,  0x052F   },  /* Cyrillic Supplement */
-    {  0x1D00  ,  0x1D7F   },  /* Phonetic Extensions */
-    {  0x1D80  ,  0x1DBF   },  /* Phonetic Extensions Supplement */
-    {  0x1DC0  ,  0x1DFF   },  /* Combining Diacritical Marks Supplement */
-    {  0x1E00  ,  0x1EFF   },  /* Latin Extended Additional */
-    {  0x1F00  ,  0x1FFF   },  /* Greek Extended */
-    {  0x2000  ,  0x206F   },  /* General Punctuation */
-    {  0x2070  ,  0x209F   },  /* Superscripts and Subscripts */
-    {  0x20A0  ,  0x20CF   },  /* Currency Symbols */
-    {  0x2150  ,  0x218F   },  /* Number Forms */
-    {  0x2460  ,  0x24FF   },  /* Enclosed Alphanumerics */
-    {  0x2C60  ,  0x2C7F   },  /* Latin Extended-C */
-    {  0x2DE0  ,  0x2DFF   },  /* Cyrillic Extended-A */
-    {  0xA640U ,  0xA69FU  },  /* Cyrillic Extended-B */
-    {  0xA720U ,  0xA7FFU  },  /* Latin Extended-D */
-    {  0xFB00U ,  0xFB06U  },  /* Alphab. Present. Forms (Latin Ligs) */
-    { 0x1D400UL, 0x1D7FFUL },  /* Mathematical Alphanumeric Symbols */
-    { 0        , 0         }
+    AF_UNIRANGE_REC(  0x0020UL,  0x007FUL ),  /* Basic Latin (no control chars) */
+    AF_UNIRANGE_REC(  0x00A0UL,  0x00FFUL ),  /* Latin-1 Supplement (no control chars) */
+    AF_UNIRANGE_REC(  0x0100UL,  0x017FUL ),  /* Latin Extended-A */
+    AF_UNIRANGE_REC(  0x0180UL,  0x024FUL ),  /* Latin Extended-B */
+    AF_UNIRANGE_REC(  0x0250UL,  0x02AFUL ),  /* IPA Extensions */
+    AF_UNIRANGE_REC(  0x02B0UL,  0x02FFUL ),  /* Spacing Modifier Letters */
+    AF_UNIRANGE_REC(  0x0300UL,  0x036FUL ),  /* Combining Diacritical Marks */
+    AF_UNIRANGE_REC(  0x0370UL,  0x03FFUL ),  /* Greek and Coptic */
+    AF_UNIRANGE_REC(  0x0400UL,  0x04FFUL ),  /* Cyrillic */
+    AF_UNIRANGE_REC(  0x0500UL,  0x052FUL ),  /* Cyrillic Supplement */
+    AF_UNIRANGE_REC(  0x1D00UL,  0x1D7FUL ),  /* Phonetic Extensions */
+    AF_UNIRANGE_REC(  0x1D80UL,  0x1DBFUL ),  /* Phonetic Extensions Supplement */
+    AF_UNIRANGE_REC(  0x1DC0UL,  0x1DFFUL ),  /* Combining Diacritical Marks Supplement */
+    AF_UNIRANGE_REC(  0x1E00UL,  0x1EFFUL ),  /* Latin Extended Additional */
+    AF_UNIRANGE_REC(  0x1F00UL,  0x1FFFUL ),  /* Greek Extended */
+    AF_UNIRANGE_REC(  0x2000UL,  0x206FUL ),  /* General Punctuation */
+    AF_UNIRANGE_REC(  0x2070UL,  0x209FUL ),  /* Superscripts and Subscripts */
+    AF_UNIRANGE_REC(  0x20A0UL,  0x20CFUL ),  /* Currency Symbols */
+    AF_UNIRANGE_REC(  0x2150UL,  0x218FUL ),  /* Number Forms */
+    AF_UNIRANGE_REC(  0x2460UL,  0x24FFUL ),  /* Enclosed Alphanumerics */
+    AF_UNIRANGE_REC(  0x2C60UL,  0x2C7FUL ),  /* Latin Extended-C */
+    AF_UNIRANGE_REC(  0x2DE0UL,  0x2DFFUL ),  /* Cyrillic Extended-A */
+    AF_UNIRANGE_REC(  0xA640UL,  0xA69FUL ),  /* Cyrillic Extended-B */
+    AF_UNIRANGE_REC(  0xA720UL,  0xA7FFUL ),  /* Latin Extended-D */
+    AF_UNIRANGE_REC(  0xFB00UL,  0xFB06UL ),  /* Alphab. Present. Forms (Latin Ligs) */
+    AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ),  /* Mathematical Alphanumeric Symbols */
+    AF_UNIRANGE_REC(       0UL,       0UL )
   };
 
 
-  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
-  af_latin_script_class =
-  {
+  AF_DEFINE_SCRIPT_CLASS(af_latin_script_class,  
     AF_SCRIPT_LATIN,
     af_latin_uniranges,
 
@@ -2171,7 +2221,7 @@
 
     (AF_Script_InitHintsFunc)   af_latin_hints_init,
     (AF_Script_ApplyHintsFunc)  af_latin_hints_apply
-  };
+  )
 
 
 /* END */
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index 3251d37..660b10c 100644
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for latin script (specification).       */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2005, 2006, 2007 by                              */
+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2009 by                        */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -27,8 +27,7 @@
 
   /* the latin-specific script class */
 
-  FT_CALLBACK_TABLE const AF_ScriptClassRec
-  af_latin_script_class;
+  AF_DECLARE_SCRIPT_CLASS(af_latin_script_class)
 
 
 /* constants are given with units_per_em == 2048 in mind */
@@ -138,6 +137,10 @@
                                 FT_Face          face,
                                 FT_ULong         charcode );
 
+  FT_LOCAL( void )
+  af_latin_metrics_check_digits( AF_LatinMetrics  metrics,
+                                 FT_Face          face );
+
 
   /*************************************************************************/
   /*************************************************************************/
diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
index 14327b1..f58ef38 100644
--- a/src/autofit/aflatin2.c
+++ b/src/autofit/aflatin2.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for latin script (body).                */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008 by                        */
+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by                  */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -16,6 +16,8 @@
 /***************************************************************************/
 
 
+#include FT_ADVANCES_H
+
 #include "aflatin.h"
 #include "aflatin2.h"
 #include "aferrors.h"
@@ -154,7 +156,7 @@
 #define AF_LATIN_MAX_TEST_CHARACTERS  12
 
 
-  static const char* const  af_latin2_blue_chars[AF_LATIN_MAX_BLUES] =
+  static const char af_latin2_blue_chars[AF_LATIN_MAX_BLUES][AF_LATIN_MAX_TEST_CHARACTERS+1] =
   {
     "THEZOCQS",
     "HEZLOCUS",
@@ -336,7 +338,7 @@
          *  we couldn't find a single glyph to compute this blue zone,
          *  we will simply ignore it then
          */
-        AF_LOG(( "empty!\n" ));
+        AF_LOG(( "empty\n" ));
         continue;
       }
 
@@ -401,6 +403,52 @@
   }
 
 
+  FT_LOCAL_DEF( void )
+  af_latin2_metrics_check_digits( AF_LatinMetrics  metrics,
+                                  FT_Face          face )
+  {
+    FT_UInt   i;
+    FT_Bool   started = 0, same_width = 1;
+    FT_Fixed  advance, old_advance = 0;
+
+
+    /* check whether all ASCII digits have the same advance width; */
+    /* digit `0' is 0x30 in all supported charmaps                 */
+    for ( i = 0x30; i <= 0x39; i++ )
+    {
+      FT_UInt  glyph_index;
+
+
+      glyph_index = FT_Get_Char_Index( face, i );
+      if ( glyph_index == 0 )
+        continue;
+
+      if ( FT_Get_Advance( face, glyph_index,
+                           FT_LOAD_NO_SCALE         |
+                           FT_LOAD_NO_HINTING       |
+                           FT_LOAD_IGNORE_TRANSFORM,
+                           &advance ) )
+        continue;
+
+      if ( started )
+      {
+        if ( advance != old_advance )
+        {
+          same_width = 0;
+          break;
+        }
+      }
+      else
+      {
+        old_advance = advance;
+        started     = 1;
+      }
+    }
+
+    metrics->root.digits_have_same_width = same_width;
+  }
+
+
   FT_LOCAL_DEF( FT_Error )
   af_latin2_metrics_init( AF_LatinMetrics  metrics,
                          FT_Face          face )
@@ -434,6 +482,7 @@
       /* For now, compute the standard width and height from the `o'. */
       af_latin2_metrics_init_widths( metrics, face, 'o' );
       af_latin2_metrics_init_blues( metrics, face );
+      af_latin2_metrics_check_digits( metrics, face );
     }
 
     FT_Set_Charmap( face, oldmap );
@@ -1739,7 +1788,6 @@
     AF_AxisHints  axis       = &hints->axis[dim];
     AF_Edge       edges      = axis->edges;
     AF_Edge       edge_limit = edges + axis->num_edges;
-    FT_Int        n_edges;
     AF_Edge       edge;
     AF_Edge       anchor     = 0;
     FT_Int        has_serifs = 0;
@@ -2050,8 +2098,12 @@
     /* We don't handle horizontal edges since we can't easily assure that */
     /* the third (lowest) stem aligns with the base line; it might end up */
     /* one pixel higher or lower.                                         */
+
 #if 0
-    n_edges = edge_limit - edges;
+    {
+      FT_Int  n_edges = edge_limit - edges;
+
+
     if ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) )
     {
       AF_Edge  edge1, edge2, edge3;
@@ -2097,7 +2149,9 @@
           edge3->link->flags |= AF_EDGE_DONE;
       }
     }
+    }
 #endif
+
     if ( has_serifs || !anchor )
     {
       /*
@@ -2266,15 +2320,13 @@
 
   static const AF_Script_UniRangeRec  af_latin2_uniranges[] =
   {
-    { 32,  127 },    /* XXX: TODO: Add new Unicode ranges here! */
-    { 160, 255 },
-    { 0,   0 }
+    AF_UNIRANGE_REC( 32UL,  127UL ),    /* XXX: TODO: Add new Unicode ranges here! */
+    AF_UNIRANGE_REC( 160UL, 255UL ),
+    AF_UNIRANGE_REC( 0UL,   0UL )
   };
 
 
-  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec
-  af_latin2_script_class =
-  {
+  AF_DEFINE_SCRIPT_CLASS(af_latin2_script_class,
     AF_SCRIPT_LATIN2,
     af_latin2_uniranges,
 
@@ -2286,7 +2338,7 @@
 
     (AF_Script_InitHintsFunc)   af_latin2_hints_init,
     (AF_Script_ApplyHintsFunc)  af_latin2_hints_apply
-  };
+  )
 
 
 /* END */
diff --git a/src/autofit/aflatin2.h b/src/autofit/aflatin2.h
index 34eda05..925c621 100644
--- a/src/autofit/aflatin2.h
+++ b/src/autofit/aflatin2.h
@@ -27,8 +27,7 @@
 
   /* the latin-specific script class */
 
-  FT_CALLBACK_TABLE const AF_ScriptClassRec
-  af_latin2_script_class;
+  AF_DECLARE_SCRIPT_CLASS(af_latin2_script_class)
 
 /* */
 
diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c
index 4e48c2f..bf25cd1 100644
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter glyph loading routines (body).                           */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008 by                        */
+/*  Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 by                  */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -19,7 +19,6 @@
 #include "afloader.h"
 #include "afhints.h"
 #include "afglobal.h"
-#include "aflatin.h"
 #include "aferrors.h"
 
 
@@ -220,6 +219,7 @@
           FT_Pos   pp1x = loader->pp1.x;
           FT_Pos   pp2x = loader->pp2.x;
 
+
           loader->pp1.x = FT_PIX_ROUND( pp1x );
           loader->pp2.x = FT_PIX_ROUND( pp2x );
 
@@ -232,6 +232,7 @@
         FT_Pos   pp1x = loader->pp1.x;
         FT_Pos   pp2x = loader->pp2.x;
 
+
         loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );
         loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );
 
@@ -413,7 +414,8 @@
       slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y );
 
       /* for mono-width fonts (like Andale, Courier, etc.) we need */
-      /* to keep the original rounded advance width                */
+      /* to keep the original rounded advance width; ditto for     */
+      /* digits if all have the same advance width                 */
 #if 0
       if ( !FT_IS_FIXED_WIDTH( slot->face ) )
         slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
@@ -421,13 +423,9 @@
         slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
                                                x_scale );
 #else
-      if ( !FT_IS_FIXED_WIDTH( slot->face ) )
-      {
-        /* non-spacing glyphs must stay as-is */
-        if ( slot->metrics.horiAdvance )
-          slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
-      }
-      else
+      if ( FT_IS_FIXED_WIDTH( slot->face )                              ||
+           ( af_face_globals_is_digit( loader->globals, glyph_index ) &&
+             metrics->digits_have_same_width                          ) )
       {
         slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
                                                metrics->scaler.x_scale );
@@ -437,6 +435,12 @@
         slot->lsb_delta = 0;
         slot->rsb_delta = 0;
       }
+      else
+      {
+        /* non-spacing glyphs must stay as-is */
+        if ( slot->metrics.horiAdvance )
+          slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
+      }
 #endif
 
       slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c
index cd5e1cc..ec2d707 100644
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -18,6 +18,7 @@
 
 #include "afmodule.h"
 #include "afloader.h"
+#include "afpic.h"
 
 #ifdef AF_DEBUG
   int    _af_debug;
@@ -66,19 +67,15 @@
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_AutoHinter_ServiceRec  af_autofitter_service =
-  {
+  FT_DEFINE_AUTOHINTER_SERVICE(af_autofitter_service,
     NULL,
     NULL,
     NULL,
     (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph
-  };
+  )
 
+  FT_DEFINE_MODULE(autofit_module_class,
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Module_Class  autofit_module_class =
-  {
     FT_MODULE_HINTER,
     sizeof ( FT_AutofitterRec ),
 
@@ -86,12 +83,12 @@
     0x10000L,   /* version 1.0 of the autofitter  */
     0x20000L,   /* requires FreeType 2.0 or above */
 
-    (const void*)&af_autofitter_service,
+    (const void*)&AF_AF_AUTOFITTER_SERVICE_GET,
 
     (FT_Module_Constructor)af_autofitter_init,
     (FT_Module_Destructor) af_autofitter_done,
     (FT_Module_Requester)  NULL
-  };
+  )
 
 
 /* END */
diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h
index 36268a0..d979239 100644
--- a/src/autofit/afmodule.h
+++ b/src/autofit/afmodule.h
@@ -20,13 +20,13 @@
 #define __AFMODULE_H__
 
 #include <ft2build.h>
+#include FT_INTERNAL_OBJECTS_H
 #include FT_MODULE_H
 
 
 FT_BEGIN_HEADER
 
-  FT_CALLBACK_TABLE
-  const FT_Module_Class  autofit_module_class;
+FT_DECLARE_MODULE(autofit_module_class)
 
 
 FT_END_HEADER
diff --git a/src/autofit/afpic.c b/src/autofit/afpic.c
new file mode 100644
index 0000000..76822c3
--- /dev/null
+++ b/src/autofit/afpic.c
@@ -0,0 +1,92 @@
+/***************************************************************************/
+/*                                                                         */
+/*  afpic.c                                                                */
+/*                                                                         */
+/*    The FreeType position independent code services for autofit module.  */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include "afpic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  /* forward declaration of PIC init functions from afmodule.c */
+  void FT_Init_Class_af_autofitter_service( FT_Library, FT_AutoHinter_ServiceRec*);
+
+  /* forward declaration of PIC init functions from script classes */
+#include "aflatin.h"
+#include "aflatin2.h"
+#include "afcjk.h"
+#include "afdummy.h"
+#include "afindic.h"
+
+  void
+  autofit_module_class_pic_free( FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Memory memory = library->memory;
+    if ( pic_container->autofit )
+    {
+      FT_FREE( pic_container->autofit );
+      pic_container->autofit = NULL;
+    }
+  }
+
+  FT_Error
+  autofit_module_class_pic_init( FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_UInt         ss;
+    FT_Error        error = FT_Err_Ok;
+    AFModulePIC*  container;
+    FT_Memory memory = library->memory;
+
+    /* allocate pointer, clear and set global container pointer */
+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+      return error;
+    FT_MEM_SET( container, 0, sizeof(*container) );
+    pic_container->autofit = container;
+
+    /* initialize pointer table - this is how the module usually expects this data */
+    for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ )
+    {
+      container->af_script_classes[ss] = &container->af_script_classes_rec[ss];
+    }
+    container->af_script_classes[AF_SCRIPT_CLASSES_COUNT-1] = NULL;
+    
+    /* add call to initialization function when you add new scripts */
+    ss = 0;
+    FT_Init_Class_af_dummy_script_class(&container->af_script_classes_rec[ss++]);
+#ifdef FT_OPTION_AUTOFIT2
+    FT_Init_Class_af_latin2_script_class(&container->af_script_classes_rec[ss++]);
+#endif
+    FT_Init_Class_af_latin_script_class(&container->af_script_classes_rec[ss++]);
+    FT_Init_Class_af_cjk_script_class(&container->af_script_classes_rec[ss++]);
+    FT_Init_Class_af_indic_script_class(&container->af_script_classes_rec[ss++]);    
+
+    FT_Init_Class_af_autofitter_service(library, &container->af_autofitter_service);
+
+/*Exit:*/
+    if(error)
+      autofit_module_class_pic_free(library);
+    return error;
+  }
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
+/* END */
diff --git a/src/autofit/afpic.h b/src/autofit/afpic.h
new file mode 100644
index 0000000..80e62d3
--- /dev/null
+++ b/src/autofit/afpic.h
@@ -0,0 +1,64 @@
+/***************************************************************************/
+/*                                                                         */
+/*  afpic.h                                                                */
+/*                                                                         */
+/*    The FreeType position independent code services for autofit module.  */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __AFPIC_H__
+#define __AFPIC_H__
+
+  
+FT_BEGIN_HEADER
+
+#include FT_INTERNAL_PIC_H
+
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define AF_SCRIPT_CLASSES_GET         af_script_classes
+#define AF_AF_AUTOFITTER_SERVICE_GET  af_autofitter_service
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#include "aftypes.h"
+
+/* increase these when you add new scripts, and update autofit_module_class_pic_init */
+#ifdef FT_OPTION_AUTOFIT2
+  #define AF_SCRIPT_CLASSES_COUNT     6
+#else
+  #define AF_SCRIPT_CLASSES_COUNT     5  
+#endif
+#define AF_SCRIPT_CLASSES_REC_COUNT  (AF_SCRIPT_CLASSES_COUNT-1)    
+
+  typedef struct AFModulePIC_
+  {
+    AF_ScriptClass    af_script_classes[AF_SCRIPT_CLASSES_COUNT];
+    AF_ScriptClassRec af_script_classes_rec[AF_SCRIPT_CLASSES_REC_COUNT];
+    FT_AutoHinter_ServiceRec af_autofitter_service;
+  } AFModulePIC;
+
+#define GET_PIC(lib)                  ((AFModulePIC*)((lib)->pic_container.autofit))
+#define AF_SCRIPT_CLASSES_GET         (GET_PIC(FT_FACE_LIBRARY(globals->face))->af_script_classes)
+#define AF_AF_AUTOFITTER_SERVICE_GET  (GET_PIC(library)->af_autofitter_service)
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __AFPIC_H__ */
+
+
+/* END */
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index 626a388..5574f0c 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -285,6 +285,7 @@
   {
     AF_ScriptClass  clazz;
     AF_ScalerRec    scaler;
+    FT_Bool         digits_have_same_width;
 
   } AF_ScriptMetricsRec, *AF_ScriptMetrics;
 
@@ -321,6 +322,8 @@
 
   } AF_Script_UniRangeRec;
 
+#define AF_UNIRANGE_REC( a, b ) { (FT_UInt32)(a), (FT_UInt32)(b) }
+
   typedef const AF_Script_UniRangeRec  *AF_Script_UniRange;
 
 
@@ -329,7 +332,7 @@
     AF_Script                   script;
     AF_Script_UniRange          script_uni_ranges; /* last must be { 0, 0 } */
 
-    FT_UInt                     script_metrics_size;
+    FT_Offset                   script_metrics_size;
     AF_Script_InitMetricsFunc   script_metrics_init;
     AF_Script_ScaleMetricsFunc  script_metrics_scale;
     AF_Script_DoneMetricsFunc   script_metrics_done;
@@ -339,6 +342,56 @@
 
   } AF_ScriptClassRec;
 
+/* Declare and define vtables for classes */
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define AF_DECLARE_SCRIPT_CLASS(script_class)                                \
+  FT_CALLBACK_TABLE const AF_ScriptClassRec                                  \
+  script_class;
+
+#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size,        \
+                               m_init, m_scale, m_done, h_init, h_apply)     \
+  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec                              \
+  script_class =                                                             \
+  {                                                                          \
+    script_,                                                                 \
+    ranges,                                                                  \
+                                                                             \
+    m_size,                                                                  \
+                                                                             \
+    m_init,                                                                  \
+    m_scale,                                                                 \
+    m_done,                                                                  \
+                                                                             \
+    h_init,                                                                  \
+    h_apply                                                                  \
+  };
+
+#else 
+
+#define AF_DECLARE_SCRIPT_CLASS(script_class)                                \
+  FT_LOCAL(void)                                                             \
+  FT_Init_Class_##script_class(AF_ScriptClassRec* ac);
+
+#define AF_DEFINE_SCRIPT_CLASS(script_class, script_, ranges, m_size,        \
+                               m_init, m_scale, m_done, h_init, h_apply)     \
+  FT_LOCAL_DEF(void)                                                         \
+  FT_Init_Class_##script_class(AF_ScriptClassRec* ac)                        \
+  {                                                                          \
+    ac->script                = script_;                                     \
+    ac->script_uni_ranges     = ranges;                                      \
+                                                                             \
+    ac->script_metrics_size   = m_size;                                      \
+                                                                             \
+    ac->script_metrics_init   = m_init;                                      \
+    ac->script_metrics_scale  = m_scale;                                     \
+    ac->script_metrics_done   = m_done;                                      \
+                                                                             \
+    ac->script_hints_init     = h_init;                                      \
+    ac->script_hints_apply    = h_apply;                                     \
+  }
+#endif
+
 
 /* */
 
diff --git a/src/autofit/autofit.c b/src/autofit/autofit.c
index 2fe66a9..83b613e 100644
--- a/src/autofit/autofit.c
+++ b/src/autofit/autofit.c
@@ -18,6 +18,7 @@
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
 #include <ft2build.h>
+#include "afpic.c"
 #include "afangles.c"
 #include "afglobal.c"
 #include "afhints.c"
diff --git a/src/base/basepic.c b/src/base/basepic.c
new file mode 100644
index 0000000..c0bccb6
--- /dev/null
+++ b/src/base/basepic.c
@@ -0,0 +1,83 @@
+/***************************************************************************/
+/*                                                                         */
+/*  basepic.c                                                              */
+/*                                                                         */
+/*    The FreeType position independent code services for base.            */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include "basepic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  /* forward declaration of PIC init functions from ftglyph.c */
+  void FT_Init_Class_ft_outline_glyph_class(FT_Glyph_Class*);
+  void FT_Init_Class_ft_bitmap_glyph_class(FT_Glyph_Class*);
+
+  /* forward declaration of PIC init functions from ftinit.c */
+  FT_Error ft_create_default_module_classes(FT_Library);
+  void ft_destroy_default_module_classes(FT_Library);
+
+  void
+  ft_base_pic_free( FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Memory    memory = library->memory;
+    if ( pic_container->base )
+    {
+      /* Destroy default module classes (in case FT_Add_Default_Modules was used) */
+      ft_destroy_default_module_classes( library );
+
+      FT_FREE( pic_container->base );
+      pic_container->base = NULL;
+    }
+  }
+
+
+  FT_Error
+  ft_base_pic_init( FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Error        error = FT_Err_Ok;
+    BasePIC*     container;
+    FT_Memory    memory = library->memory;
+
+    /* allocate pointer, clear and set global container pointer */
+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+      return error;
+    FT_MEM_SET( container, 0, sizeof(*container) );
+    pic_container->base = container;
+
+    /* initialize default modules list and pointers */
+    error = ft_create_default_module_classes( library );
+    if ( error )
+      goto Exit;
+
+    /* initialize pointer table - this is how the module usually expects this data */
+    FT_Init_Class_ft_outline_glyph_class(&container->ft_outline_glyph_class);
+    FT_Init_Class_ft_bitmap_glyph_class(&container->ft_bitmap_glyph_class);
+
+Exit:
+    if(error)
+      ft_base_pic_free(library);
+    return error;
+  }
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
+/* END */
diff --git a/src/base/basepic.h b/src/base/basepic.h
new file mode 100644
index 0000000..bb17745
--- /dev/null
+++ b/src/base/basepic.h
@@ -0,0 +1,62 @@
+/***************************************************************************/
+/*                                                                         */
+/*  basepic.h                                                              */
+/*                                                                         */
+/*    The FreeType position independent code services for base.            */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __BASEPIC_H__
+#define __BASEPIC_H__
+
+  
+FT_BEGIN_HEADER
+
+#include FT_INTERNAL_PIC_H
+
+#ifndef FT_CONFIG_OPTION_PIC
+#define FT_OUTLINE_GLYPH_CLASS_GET &ft_outline_glyph_class
+#define FT_BITMAP_GLYPH_CLASS_GET  &ft_bitmap_glyph_class
+#define FT_DEFAULT_MODULES_GET     ft_default_modules
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#include FT_GLYPH_H
+
+  typedef struct BasePIC_
+  {
+    FT_Module_Class** default_module_classes;
+    FT_Glyph_Class ft_outline_glyph_class;
+    FT_Glyph_Class ft_bitmap_glyph_class;
+  } BasePIC;
+
+#define GET_PIC(lib)                  ((BasePIC*)((lib)->pic_container.base))
+#define FT_OUTLINE_GLYPH_CLASS_GET    (&GET_PIC(library)->ft_outline_glyph_class)
+#define FT_BITMAP_GLYPH_CLASS_GET     (&GET_PIC(library)->ft_bitmap_glyph_class)
+#define FT_DEFAULT_MODULES_GET        (GET_PIC(library)->default_module_classes)
+
+  void
+  ft_base_pic_free( FT_Library library );
+
+  FT_Error
+  ft_base_pic_init( FT_Library library );
+
+#endif /* FT_CONFIG_OPTION_PIC */
+ /* */
+
+FT_END_HEADER
+
+#endif /* __BASEPIC_H__ */
+
+
+/* END */
diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c
index 504f9d2..8ab7fcb 100644
--- a/src/base/ftadvanc.c
+++ b/src/base/ftadvanc.c
@@ -140,7 +140,7 @@
     if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
       return FT_Err_Unimplemented_Feature;
 
-    flags |= FT_LOAD_ADVANCE_ONLY;
+    flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
     for ( nn = 0; nn < count; nn++ )
     {
       error = FT_Load_Glyph( face, start + nn, flags );
diff --git a/src/base/ftbase.c b/src/base/ftbase.c
index d1fe6e6..6a27ea9 100644
--- a/src/base/ftbase.c
+++ b/src/base/ftbase.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Single object library component (body only).                         */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by             */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by       */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,14 +20,16 @@
 
 #define  FT_MAKE_OPTION_SINGLE_OBJECT
 
+#include "ftpic.c"
+#include "basepic.c"
 #include "ftadvanc.c"
 #include "ftcalc.c"
 #include "ftdbgmem.c"
 #include "ftgloadr.c"
-#include "ftnames.c"
 #include "ftobjs.c"
 #include "ftoutln.c"
 #include "ftrfork.c"
+#include "ftsnames.c"
 #include "ftstream.c"
 #include "fttrigon.c"
 #include "ftutil.c"
diff --git a/src/base/ftbase.h b/src/base/ftbase.h
index 9cae85d..1dc49f3 100644
--- a/src/base/ftbase.h
+++ b/src/base/ftbase.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private functions used in base module (specification).  */
 /*                                                                         */
-/*  Copyright 2008 by                                                      */
+/*  Copyright 2008, 2010 by                                                */
 /*  David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya.      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -29,7 +29,7 @@
 
   /* Assume the stream is sfnt-wrapped PS Type1 or sfnt-wrapped CID-keyed */
   /* font, and try to load a face specified by the face_index.            */
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL( FT_Error )
   open_face_PS_from_sfnt_stream( FT_Library     library,
                                  FT_Stream      stream,
                                  FT_Long        face_index,
@@ -40,7 +40,7 @@
 
   /* Create a new FT_Face given a buffer and a driver name. */
   /* From ftmac.c.                                          */
-  FT_LOCAL_DEF( FT_Error )
+  FT_LOCAL( FT_Error )
   open_face_from_buffer( FT_Library   library,
                          FT_Byte*     base,
                          FT_ULong     size,
diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c
index 532ab13..2de592d 100644
--- a/src/base/ftbbox.c
+++ b/src/base/ftbbox.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType bbox computation (body).                                    */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2004, 2006 by                               */
+/*  Copyright 1996-2001, 2002, 2004, 2006, 2010 by                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
@@ -29,6 +29,7 @@
 #include FT_IMAGE_H
 #include FT_OUTLINE_H
 #include FT_INTERNAL_CALC_H
+#include FT_INTERNAL_OBJECTS_H
 
 
   typedef struct  TBBox_Rec_
@@ -139,7 +140,7 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    This function is used as a `conic_to' emitter during               */
-  /*    FT_Raster_Decompose().  It checks a conic Bezier curve with the    */
+  /*    FT_Outline_Decompose().  It checks a conic Bezier curve with the   */
   /*    current bounding box, and computes its extrema if necessary to     */
   /*    update it.                                                         */
   /*                                                                       */
@@ -506,7 +507,7 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    This function is used as a `cubic_to' emitter during               */
-  /*    FT_Raster_Decompose().  It checks a cubic Bezier curve with the    */
+  /*    FT_Outline_Decompose().  It checks a cubic Bezier curve with the   */
   /*    current bounding box, and computes its extrema if necessary to     */
   /*    update it.                                                         */
   /*                                                                       */
@@ -559,6 +560,13 @@
     return 0;
   }
 
+FT_DEFINE_OUTLINE_FUNCS(bbox_interface,
+        (FT_Outline_MoveTo_Func) BBox_Move_To,
+        (FT_Outline_LineTo_Func) BBox_Move_To,
+        (FT_Outline_ConicTo_Func)BBox_Conic_To,
+        (FT_Outline_CubicTo_Func)BBox_Cubic_To,
+        0, 0
+  )
 
   /* documentation is in ftbbox.h */
 
@@ -628,18 +636,13 @@
       /* the two boxes are different, now walk over the outline to */
       /* get the Bezier arc extrema.                               */
 
-      static const FT_Outline_Funcs  bbox_interface =
-      {
-        (FT_Outline_MoveTo_Func) BBox_Move_To,
-        (FT_Outline_LineTo_Func) BBox_Move_To,
-        (FT_Outline_ConicTo_Func)BBox_Conic_To,
-        (FT_Outline_CubicTo_Func)BBox_Cubic_To,
-        0, 0
-      };
-
       FT_Error   error;
       TBBox_Rec  user;
 
+#ifdef FT_CONFIG_OPTION_PIC
+      FT_Outline_Funcs bbox_interface;
+      Init_Class_bbox_interface(&bbox_interface);
+#endif
 
       user.bbox = bbox;
 
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index 8810cfa..46fcce6 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -228,8 +228,12 @@
     if ( !bitmap || !bitmap->buffer )
       return FT_Err_Invalid_Argument;
 
-    xstr = FT_PIX_ROUND( xStrength ) >> 6;
-    ystr = FT_PIX_ROUND( yStrength ) >> 6;
+    if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
+         ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
+      return FT_Err_Invalid_Argument;
+       
+    xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
+    ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;
 
     if ( xstr == 0 && ystr == 0 )
       return FT_Err_Ok;
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index 04295a6..3892fab 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -110,12 +110,12 @@
   FT_EXPORT_DEF( FT_Int32 )
   FT_Sqrt32( FT_Int32  x )
   {
-    FT_ULong  val, root, newroot, mask;
+    FT_UInt32  val, root, newroot, mask;
 
 
     root = 0;
-    mask = 0x40000000L;
-    val  = (FT_ULong)x;
+    mask = (FT_UInt32)0x40000000UL;
+    val  = (FT_UInt32)x;
 
     do
     {
@@ -362,6 +362,7 @@
     long  s;
 
 
+    /* XXX: this function does not allow 64-bit arguments */
     if ( a == 0 || b == c )
       return a;
 
@@ -377,12 +378,12 @@
       FT_Int64  temp, temp2;
 
 
-      ft_multo64( a, b, &temp );
+      ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );
 
       temp2.hi = 0;
       temp2.lo = (FT_UInt32)(c >> 1);
       FT_Add64( &temp, &temp2, &temp );
-      a = ft_div64by32( temp.hi, temp.lo, c );
+      a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );
     }
     else
       a = 0x7FFFFFFFL;
@@ -416,8 +417,8 @@
       FT_Int64  temp;
 
 
-      ft_multo64( a, b, &temp );
-      a = ft_div64by32( temp.hi, temp.lo, c );
+      ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );
+      a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );
     }
     else
       a = 0x7FFFFFFFL;
@@ -539,13 +540,14 @@
     FT_UInt32  q;
 
 
-    s  = a; a = FT_ABS( a );
-    s ^= b; b = FT_ABS( b );
+    /* XXX: this function does not allow 64-bit arguments */
+    s  = (FT_Int32)a; a = FT_ABS( a );
+    s ^= (FT_Int32)b; b = FT_ABS( b );
 
     if ( b == 0 )
     {
       /* check for division by 0 */
-      q = 0x7FFFFFFFL;
+      q = (FT_UInt32)0x7FFFFFFFL;
     }
     else if ( ( a >> 16 ) == 0 )
     {
@@ -562,7 +564,7 @@
       temp2.hi = 0;
       temp2.lo = (FT_UInt32)( b >> 1 );
       FT_Add64( &temp, &temp2, &temp );
-      q = ft_div64by32( temp.hi, temp.lo, b );
+      q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b );
     }
 
     return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
@@ -840,7 +842,7 @@
                          FT_Pos  out_x,
                          FT_Pos  out_y )
   {
-    FT_Int  result;
+    FT_Long  result; /* avoid overflow on 16-bit system */
 
 
     /* deal with the trivial cases quickly */
@@ -889,8 +891,9 @@
       FT_Int64  z1, z2;
 
 
-      ft_multo64( in_x, out_y, &z1 );
-      ft_multo64( in_y, out_x, &z2 );
+      /* XXX: this function does not allow 64-bit arguments */
+      ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 );
+      ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 );
 
       if ( z1.hi > z2.hi )
         result = +1;
@@ -906,7 +909,8 @@
 #endif
     }
 
-    return result;
+    /* XXX: only the sign of return value, +1/0/-1 must be used */
+    return (FT_Int)result;
   }
 
 
diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c
index 8b2a330..160269d 100644
--- a/src/base/ftdbgmem.c
+++ b/src/base/ftdbgmem.c
@@ -421,7 +421,7 @@
           "FreeType: %ld bytes of memory leaked in %ld blocks\n",
           leaks, leak_count );
 
-      printf( "FreeType: No memory leaks detected!\n" );
+      printf( "FreeType: no memory leaks detected\n" );
     }
   }
 
@@ -989,7 +989,7 @@
 #else  /* !FT_DEBUG_MEMORY */
 
   /* ANSI C doesn't like empty source files */
-  static const FT_Byte  _debug_mem_dummy = 0;
+  typedef int  _debug_mem_dummy;
 
 #endif /* !FT_DEBUG_MEMORY */
 
diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c
index ab52621..ac0010d 100644
--- a/src/base/ftgloadr.c
+++ b/src/base/ftgloadr.c
@@ -218,6 +218,9 @@
     {
       new_max = FT_PAD_CEIL( new_max, 8 );
 
+      if ( new_max > FT_OUTLINE_POINTS_MAX )
+        return FT_Err_Array_Too_Large;
+
       if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
            FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )
         goto Exit;
@@ -246,6 +249,10 @@
     if ( new_max > old_max )
     {
       new_max = FT_PAD_CEIL( new_max, 4 );
+
+      if ( new_max > FT_OUTLINE_CONTOURS_MAX )
+        return FT_Err_Array_Too_Large;
+
       if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
         goto Exit;
 
diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c
index 4130cb1..3505d6d 100644
--- a/src/base/ftglyph.c
+++ b/src/base/ftglyph.c
@@ -34,6 +34,7 @@
 #include FT_BITMAP_H
 #include FT_INTERNAL_OBJECTS_H
 
+#include "basepic.h"
 
   /*************************************************************************/
   /*                                                                       */
@@ -129,9 +130,7 @@
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Glyph_Class  ft_bitmap_glyph_class =
-  {
+  FT_DEFINE_GLYPH(ft_bitmap_glyph_class,
     sizeof ( FT_BitmapGlyphRec ),
     FT_GLYPH_FORMAT_BITMAP,
 
@@ -141,7 +140,7 @@
     0,                          /* FT_Glyph_TransformFunc */
     ft_bitmap_glyph_bbox,
     0                           /* FT_Glyph_PrepareFunc   */
-  };
+  )
 
 
   /*************************************************************************/
@@ -255,9 +254,7 @@
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Glyph_Class  ft_outline_glyph_class =
-  {
+  FT_DEFINE_GLYPH( ft_outline_glyph_class, 
     sizeof ( FT_OutlineGlyphRec ),
     FT_GLYPH_FORMAT_OUTLINE,
 
@@ -267,7 +264,7 @@
     ft_outline_glyph_transform,
     ft_outline_glyph_bbox,
     ft_outline_glyph_prepare
-  };
+  )
 
 
   /*************************************************************************/
@@ -373,11 +370,11 @@
 
     /* if it is a bitmap, that's easy :-) */
     if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
-      clazz = &ft_bitmap_glyph_class;
+      clazz = FT_BITMAP_GLYPH_CLASS_GET;
 
-    /* it it is an outline too */
+    /* if it is an outline */
     else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
-      clazz = &ft_outline_glyph_class;
+      clazz = FT_OUTLINE_GLYPH_CLASS_GET;
 
     else
     {
@@ -518,6 +515,10 @@
 
     const FT_Glyph_Class*     clazz;
 
+#ifdef FT_CONFIG_OPTION_PIC
+    FT_Library                library = FT_GLYPH( glyph )->library;
+#endif
+
 
     /* check argument */
     if ( !the_glyph )
@@ -533,7 +534,7 @@
     clazz = glyph->clazz;
 
     /* when called with a bitmap glyph, do nothing and return successfully */
-    if ( clazz == &ft_bitmap_glyph_class )
+    if ( clazz == FT_BITMAP_GLYPH_CLASS_GET )
       goto Exit;
 
     if ( !clazz || !clazz->glyph_prepare )
@@ -546,7 +547,7 @@
     dummy.format   = clazz->glyph_format;
 
     /* create result bitmap glyph */
-    error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class,
+    error = ft_new_glyph( glyph->library, FT_BITMAP_GLYPH_CLASS_GET,
                           (FT_Glyph*)(void*)&bitmap );
     if ( error )
       goto Exit;
diff --git a/src/base/ftinit.c b/src/base/ftinit.c
index dac30b0..1914228 100644
--- a/src/base/ftinit.c
+++ b/src/base/ftinit.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType initialization layer (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2005, 2007 by                               */
+/*  Copyright 1996-2001, 2002, 2005, 2007, 2009 by                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -42,6 +42,7 @@
 #include FT_INTERNAL_OBJECTS_H
 #include FT_INTERNAL_DEBUG_H
 #include FT_MODULE_H
+#include "basepic.h"
 
 
   /*************************************************************************/
@@ -53,6 +54,8 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_init
 
+#ifndef FT_CONFIG_OPTION_PIC
+
 #undef  FT_USE_MODULE
 #ifdef __cplusplus
 #define FT_USE_MODULE( type, x )  extern "C" const type  x;
@@ -74,6 +77,99 @@
     0
   };
 
+#else /* FT_CONFIG_OPTION_PIC */
+
+#ifdef __cplusplus
+#define FT_EXTERNC  extern "C"
+#else
+#define FT_EXTERNC  extern
+#endif
+
+  /* declare the module's class creation/destruction functions */
+#undef  FT_USE_MODULE
+#define FT_USE_MODULE( type, x )  \
+  FT_EXTERNC FT_Error FT_Create_Class_##x( FT_Library library, FT_Module_Class** output_class ); \
+  FT_EXTERNC void     FT_Destroy_Class_##x( FT_Library library, FT_Module_Class*  clazz );
+
+#include FT_CONFIG_MODULES_H
+
+
+  /* count all module classes */
+#undef  FT_USE_MODULE
+#define FT_USE_MODULE( type, x )  MODULE_CLASS_##x,
+
+  enum {
+#include FT_CONFIG_MODULES_H
+    FT_NUM_MODULE_CLASSES
+  };
+
+  /* destroy all module classes */  
+#undef  FT_USE_MODULE
+#define FT_USE_MODULE( type, x )  \
+  if ( classes[i] ) { FT_Destroy_Class_##x(library, classes[i]); } \
+  i++;                                                             \
+
+  FT_BASE_DEF( void )
+  ft_destroy_default_module_classes( FT_Library  library )
+  {
+    FT_Module_Class** classes;
+    FT_Memory         memory;
+    FT_UInt           i;
+    BasePIC*          pic_container = (BasePIC*)library->pic_container.base;
+
+    if ( !pic_container->default_module_classes )
+      return;
+
+    memory = library->memory;
+    classes = pic_container->default_module_classes;
+    i = 0;
+
+#include FT_CONFIG_MODULES_H
+
+    FT_FREE( classes );
+    pic_container->default_module_classes = 0;
+  }
+
+  /* initialize all module classes and the pointer table */
+#undef  FT_USE_MODULE
+#define FT_USE_MODULE( type, x )                \
+  error = FT_Create_Class_##x(library, &clazz); \
+  if (error) goto Exit;                         \
+  classes[i++] = clazz;
+
+  FT_BASE_DEF( FT_Error )
+  ft_create_default_module_classes( FT_Library  library )
+  {
+    FT_Error          error;
+    FT_Memory         memory;
+    FT_Module_Class** classes;
+    FT_Module_Class*  clazz;
+    FT_UInt           i;
+    BasePIC*          pic_container = (BasePIC*)library->pic_container.base;
+
+    memory = library->memory;  
+    pic_container->default_module_classes = 0;
+
+    if ( FT_ALLOC(classes, sizeof(FT_Module_Class*) * (FT_NUM_MODULE_CLASSES + 1) ) )
+      return error;
+    /* initialize all pointers to 0, especially the last one */
+    for (i = 0; i < FT_NUM_MODULE_CLASSES; i++)
+      classes[i] = 0;
+    classes[FT_NUM_MODULE_CLASSES] = 0;
+
+    i = 0;
+
+#include FT_CONFIG_MODULES_H
+
+Exit:    
+    if (error) ft_destroy_default_module_classes( library );
+    else pic_container->default_module_classes = classes;
+
+    return error;    
+  }
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
 
   /* documentation is in ftmodapi.h */
 
@@ -86,16 +182,15 @@
 
     /* test for valid `library' delayed to FT_Add_Module() */
 
-    cur = ft_default_modules;
+    cur = FT_DEFAULT_MODULES_GET;
     while ( *cur )
     {
       error = FT_Add_Module( library, *cur );
       /* notify errors, but don't stop */
       if ( error )
-      {
-        FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = 0x%x\n",
+        FT_TRACE0(( "FT_Add_Default_Module:"
+                    " Cannot install `%s', error = 0x%x\n",
                    (*cur)->module_name, error ));
-      }
       cur++;
     }
   }
@@ -127,13 +222,7 @@
     if ( error )
       FT_Done_Memory( memory );
     else
-    {
-      (*alibrary)->version_major = FREETYPE_MAJOR;
-      (*alibrary)->version_minor = FREETYPE_MINOR;
-      (*alibrary)->version_patch = FREETYPE_PATCH;
-
       FT_Add_Default_Modules( *alibrary );
-    }
 
     return error;
   }
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 72dea33..a32b2cd 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    The FreeType private base classes (body).                            */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
+/*            2010 by                                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -37,7 +38,9 @@
 #include FT_SERVICE_KERNING_H
 #include FT_SERVICE_TRUETYPE_ENGINE_H
 
+#ifdef FT_CONFIG_OPTION_MAC_FONTS
 #include "ftbase.h"
+#endif
 
 #define GRID_FIT_METRICS
 
@@ -348,6 +351,9 @@
     /* free bitmap buffer if needed */
     ft_glyphslot_free_bitmap( slot );
 
+    /* slot->internal might be NULL in out-of-memory situations */
+    if ( slot->internal )
+    {
     /* free glyph loader */
     if ( FT_DRIVER_USES_OUTLINES( driver ) )
     {
@@ -356,6 +362,7 @@
     }
 
     FT_FREE( slot->internal );
+    }
   }
 
 
@@ -588,17 +595,17 @@
      * Determine whether we need to auto-hint or not.
      * The general rules are:
      *
-     * - Do only auto-hinting if we have a hinter module,
-     *   a scalable font format dealing with outlines,
-     *   and no transforms except simple slants.
+     * - Do only auto-hinting if we have a hinter module, a scalable font
+     *   format dealing with outlines, and no transforms except simple
+     *   slants and/or rotations by integer multiples of 90 degrees.
      *
-     * - Then, autohint if FT_LOAD_FORCE_AUTOHINT is set
-     *   or if we don't have a native font hinter.
+     * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
+     *   have a native font hinter.
      *
      * - Otherwise, auto-hint for LIGHT hinting mode.
      *
-     * - Exception: The font is `tricky' and requires
-     *   the native hinter to load properly.
+     * - Exception: The font is `tricky' and requires the native hinter to
+     *   load properly.
      */
 
     if ( hinter                                   &&
@@ -607,8 +614,10 @@
          FT_DRIVER_IS_SCALABLE( driver )          &&
          FT_DRIVER_USES_OUTLINES( driver )        &&
          !FT_IS_TRICKY( face )                    &&
-         face->internal->transform_matrix.yy > 0  &&
-         face->internal->transform_matrix.yx == 0 )
+         ( ( face->internal->transform_matrix.yx == 0 &&
+             face->internal->transform_matrix.xx != 0 ) ||
+           ( face->internal->transform_matrix.xx == 0 &&
+             face->internal->transform_matrix.yx != 0 ) ) )
     {
       if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||
            !FT_DRIVER_HAS_HINTER( driver )         )
@@ -733,11 +742,30 @@
                                      renderer, slot,
                                      &internal->transform_matrix,
                                      &internal->transform_delta );
+        else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
+        {
+          /* apply `standard' transformation if no renderer is available */
+          if ( &internal->transform_matrix )
+            FT_Outline_Transform( &slot->outline,
+                                  &internal->transform_matrix );
+
+          if ( &internal->transform_delta )
+            FT_Outline_Translate( &slot->outline,
+                                  internal->transform_delta.x,
+                                  internal->transform_delta.y );
+        }
+
         /* transform advance */
         FT_Vector_Transform( &slot->advance, &internal->transform_matrix );
       }
     }
 
+    FT_TRACE5(( "  x advance: %d\n" , slot->advance.x ));
+    FT_TRACE5(( "  y advance: %d\n" , slot->advance.y ));
+
+    FT_TRACE5(( "  linear x advance: %d\n" , slot->linearHoriAdvance ));
+    FT_TRACE5(( "  linear y advance: %d\n" , slot->linearVertAdvance ));
+
     /* do we need to render the image now? */
     if ( !error                                    &&
          slot->format != FT_GLYPH_FORMAT_BITMAP    &&
@@ -2398,12 +2426,24 @@
   ft_synthesize_vertical_metrics( FT_Glyph_Metrics*  metrics,
                                   FT_Pos             advance )
   {
+    FT_Pos  height = metrics->height;
+
+
+    /* compensate for glyph with bbox above/below the baseline */
+    if ( metrics->horiBearingY < 0 )
+    {
+      if ( height < metrics->horiBearingY )
+        height = metrics->horiBearingY;
+    }
+    else if ( metrics->horiBearingY > 0 )
+      height -= metrics->horiBearingY;
+
     /* the factor 1.2 is a heuristical value */
     if ( !advance )
-      advance = metrics->height * 12 / 10;
+      advance = height * 12 / 10;
 
-    metrics->vertBearingX = -( metrics->width / 2 );
-    metrics->vertBearingY = ( advance - metrics->height ) / 2;
+    metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2;
+    metrics->vertBearingY = ( advance - height ) / 2;
     metrics->vertAdvance  = advance;
   }
 
@@ -3048,7 +3088,12 @@
       FT_CMap  cmap = FT_CMAP( face->charmap );
 
 
-      result = cmap->clazz->char_index( cmap, charcode );
+      if ( charcode > 0xFFFFFFFFUL )
+      {
+        FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
+        FT_TRACE1(( " 0x%x is truncated\n", charcode ));
+      }
+      result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode );
     }
     return  result;
   }
@@ -3128,8 +3173,20 @@
         FT_CMap  vcmap = FT_CMAP( charmap );
 
 
-        result = vcmap->clazz->char_var_index( vcmap, ucmap, charcode,
-                                               variantSelector );
+        if ( charcode > 0xFFFFFFFFUL )
+        {
+          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
+          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
+        }
+        if ( variantSelector > 0xFFFFFFFFUL )
+        {
+          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
+          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
+        }
+
+        result = vcmap->clazz->char_var_index( vcmap, ucmap,
+                                               (FT_UInt32)charcode,
+                                               (FT_UInt32)variantSelector );
       }
     }
 
@@ -3157,8 +3214,20 @@
         FT_CMap  vcmap = FT_CMAP( charmap );
 
 
-        result = vcmap->clazz->char_var_default( vcmap, charcode,
-                                                 variantSelector );
+        if ( charcode > 0xFFFFFFFFUL )
+        {
+          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
+          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
+        }
+        if ( variantSelector > 0xFFFFFFFFUL )
+        {
+          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
+          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
+        }
+
+        result = vcmap->clazz->char_var_default( vcmap,
+                                                 (FT_UInt32)charcode,
+                                                 (FT_UInt32)variantSelector );
       }
     }
 
@@ -3213,7 +3282,14 @@
         FT_Memory  memory = FT_FACE_MEMORY( face );
 
 
-        result = vcmap->clazz->charvariant_list( vcmap, memory, charcode );
+        if ( charcode > 0xFFFFFFFFUL )
+        {
+          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
+          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
+        }
+
+        result = vcmap->clazz->charvariant_list( vcmap, memory,
+                                                 (FT_UInt32)charcode );
       }
     }
     return result;
@@ -3240,8 +3316,14 @@
         FT_Memory  memory = FT_FACE_MEMORY( face );
 
 
+        if ( variantSelector > 0xFFFFFFFFUL )
+        {
+          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
+          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
+        }
+
         result = vcmap->clazz->variantchar_list( vcmap, memory,
-                                                 variantSelector );
+                                                 (FT_UInt32)variantSelector );
       }
     }
 
@@ -3291,7 +3373,7 @@
       ((FT_Byte*)buffer)[0] = 0;
 
     if ( face                                     &&
-         glyph_index <= (FT_UInt)face->num_glyphs &&
+         (FT_Long)glyph_index <= face->num_glyphs &&
          FT_HAS_GLYPH_NAMES( face )               )
     {
       FT_Service_GlyphDict  service;
@@ -3391,6 +3473,7 @@
                       FT_ULong  *length )
   {
     FT_Service_SFNT_Table  service;
+    FT_ULong               offset;
 
 
     if ( !face || !FT_IS_SFNT( face ) )
@@ -3400,7 +3483,7 @@
     if ( service == NULL )
       return FT_Err_Unimplemented_Feature;
 
-    return service->table_info( face, table_index, tag, length );
+    return service->table_info( face, table_index, tag, &offset, length );
   }
 
 
@@ -4123,6 +4206,13 @@
 
     library->memory = memory;
 
+#ifdef FT_CONFIG_OPTION_PIC
+    /* initialize position independent code containers */
+    error = ft_pic_container_init( library );
+    if ( error )
+      goto Fail;
+#endif
+
     /* allocate the render pool */
     library->raster_pool_size = FT_RENDER_POOL_SIZE;
 #if FT_RENDER_POOL_SIZE > 0
@@ -4130,12 +4220,19 @@
       goto Fail;
 #endif
 
+    library->version_major = FREETYPE_MAJOR;
+    library->version_minor = FREETYPE_MINOR;
+    library->version_patch = FREETYPE_PATCH;
+
     /* That's ok now */
     *alibrary = library;
 
     return FT_Err_Ok;
 
   Fail:
+#ifdef FT_CONFIG_OPTION_PIC
+    ft_pic_container_destroy( library );
+#endif
     FT_FREE( library );
     return error;
   }
@@ -4216,7 +4313,7 @@
         {
           FT_Done_Face( FT_FACE( faces->head->data ) );
           if ( faces->head )
-            FT_ERROR(( "FT_Done_Library: failed to free some faces\n" ));
+            FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" ));
         }
       }
     }
@@ -4252,6 +4349,11 @@
     FT_FREE( library->raster_pool );
     library->raster_pool_size = 0;
 
+#ifdef FT_CONFIG_OPTION_PIC
+    /* Destroy pic container contents */
+    ft_pic_container_destroy( library );
+#endif
+
     FT_FREE( library );
     return FT_Err_Ok;
   }
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 49ef82e..5bb6ef3 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType outline management (body).                                  */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -304,7 +304,7 @@
 
     *anoutline = null_outline;
 
-    if ( FT_NEW_ARRAY( anoutline->points,   numPoints * 2L ) ||
+    if ( FT_NEW_ARRAY( anoutline->points,   numPoints   ) ||
          FT_NEW_ARRAY( anoutline->tags,     numPoints      ) ||
          FT_NEW_ARRAY( anoutline->contours, numContours    ) )
       goto Fail;
diff --git a/src/base/ftpatent.c b/src/base/ftpatent.c
index 9f129d8..af29786 100644
--- a/src/base/ftpatent.c
+++ b/src/base/ftpatent.c
@@ -5,7 +5,7 @@
 /*    FreeType API for checking patented TrueType bytecode instructions    */
 /*    (body).                                                              */
 /*                                                                         */
-/*  Copyright 2007, 2008 by David Turner.                                  */
+/*  Copyright 2007, 2008, 2010 by David Turner.                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
 /*  modified, and distributed under the terms of the FreeType project      */
@@ -103,6 +103,7 @@
     }
 
   Exit:
+    FT_UNUSED( error );
     FT_FRAME_EXIT();
     return result;
   }
@@ -113,7 +114,7 @@
                               FT_ULong  tag )
   {
     FT_Stream              stream = face->stream;
-    FT_Error               error;
+    FT_Error               error  = FT_Err_Ok;
     FT_Service_SFNT_Table  service;
     FT_Bool                result = FALSE;
 
@@ -122,15 +123,19 @@
 
     if ( service )
     {
-      FT_ULong  offset, size;
+      FT_UInt   i = 0;
+      FT_ULong  tag_i = 0, offset_i = 0, length_i = 0;
 
 
-      error = service->table_info( face, tag, &offset, &size );
+      for ( i = 0; !error && tag_i != tag ; i++ )
+        error = service->table_info( face, i,
+                                     &tag_i, &offset_i, &length_i );
+
       if ( error                    ||
-           FT_STREAM_SEEK( offset ) )
+           FT_STREAM_SEEK( offset_i ) )
         goto Exit;
 
-      result = _tt_check_patents_in_range( stream, size );
+      result = _tt_check_patents_in_range( stream, length_i );
     }
 
   Exit:
diff --git a/src/base/ftpic.c b/src/base/ftpic.c
new file mode 100644
index 0000000..d5271a9
--- /dev/null
+++ b/src/base/ftpic.c
@@ -0,0 +1,54 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftpic.c                                                                */
+/*                                                                         */
+/*    The FreeType position independent code services (body).              */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include "basepic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  /* documentation is in ftpic.h */
+
+  FT_BASE_DEF( FT_Error )
+  ft_pic_container_init( FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Error error = FT_Err_Ok;
+
+    FT_MEM_SET( pic_container, 0, sizeof(*pic_container) );
+
+    error = ft_base_pic_init( library );
+    if(error)
+      return error;
+
+    return FT_Err_Ok;
+  }
+
+
+  /* Destroy the contents of the container. */
+  FT_BASE_DEF( void )
+  ft_pic_container_destroy( FT_Library library )
+  {
+    ft_base_pic_free( library );
+  }
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
+/* END */
diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c
index d59a076..133c2de 100644
--- a/src/base/ftrfork.c
+++ b/src/base/ftrfork.c
@@ -752,9 +752,9 @@
                           const char  *insertion )
   {
     char*        new_name;
-    char*        tmp;
+    const char*  tmp;
     const char*  slash;
-    unsigned     new_length;
+    size_t       new_length;
     FT_Error     error = FT_Err_Ok;
 
     FT_UNUSED( error );
diff --git a/src/base/ftnames.c b/src/base/ftsnames.c
similarity index 91%
rename from src/base/ftnames.c
rename to src/base/ftsnames.c
index 7fde5c4..3447888 100644
--- a/src/base/ftnames.c
+++ b/src/base/ftsnames.c
@@ -1,13 +1,13 @@
 /***************************************************************************/
 /*                                                                         */
-/*  ftnames.c                                                              */
+/*  ftsnames.c                                                             */
 /*                                                                         */
 /*    Simple interface to access SFNT name tables (which are used          */
 /*    to hold font names, copyright info, notices, etc.) (body).           */
 /*                                                                         */
 /*    This is _not_ used to retrieve glyph names!                          */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002 by                                           */
+/*  Copyright 1996-2001, 2002, 2009 by                                     */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -28,16 +28,16 @@
 #ifdef TT_CONFIG_OPTION_SFNT_NAMES
 
 
-  /* documentation is in ftnames.h */
+  /* documentation is in ftsnames.h */
 
   FT_EXPORT_DEF( FT_UInt )
   FT_Get_Sfnt_Name_Count( FT_Face  face )
   {
-    return (face && FT_IS_SFNT( face )) ? ((TT_Face)face)->num_names : 0;
+    return ( face && FT_IS_SFNT( face ) ) ? ((TT_Face)face)->num_names : 0;
   }
 
 
-  /* documentation is in ftnames.h */
+  /* documentation is in ftsnames.h */
 
   FT_EXPORT_DEF( FT_Error )
   FT_Get_Sfnt_Name( FT_Face       face,
diff --git a/src/base/ftstream.c b/src/base/ftstream.c
index cff67e0..b638599 100644
--- a/src/base/ftstream.c
+++ b/src/base/ftstream.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    I/O stream support (body).                                           */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008 by                   */
+/*  Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008, 2009 by             */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -60,13 +60,12 @@
     FT_Error  error = FT_Err_Ok;
 
 
-    stream->pos = pos;
-
     if ( stream->read )
     {
       if ( stream->read( stream, pos, 0, 0 ) )
       {
-        FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+        FT_ERROR(( "FT_Stream_Seek:"
+                   " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                    pos, stream->size ));
 
         error = FT_Err_Invalid_Stream_Operation;
@@ -75,12 +74,16 @@
     /* note that seeking to the first position after the file is valid */
     else if ( pos > stream->size )
     {
-      FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+      FT_ERROR(( "FT_Stream_Seek:"
+                 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                  pos, stream->size ));
 
       error = FT_Err_Invalid_Stream_Operation;
     }
 
+    if ( !error )
+      stream->pos = pos;
+
     return error;
   }
 
@@ -124,7 +127,8 @@
 
     if ( pos >= stream->size )
     {
-      FT_ERROR(( "FT_Stream_ReadAt: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+      FT_ERROR(( "FT_Stream_ReadAt:"
+                 " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                  pos, stream->size ));
 
       return FT_Err_Invalid_Stream_Operation;
@@ -145,8 +149,8 @@
 
     if ( read_bytes < count )
     {
-      FT_ERROR(( "FT_Stream_ReadAt:" ));
-      FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n",
+      FT_ERROR(( "FT_Stream_ReadAt:"
+                 " invalid read; expected %lu bytes, got %lu\n",
                  count, read_bytes ));
 
       error = FT_Err_Invalid_Stream_Operation;
@@ -211,7 +215,7 @@
   FT_Stream_ReleaseFrame( FT_Stream  stream,
                           FT_Byte**  pbytes )
   {
-    if ( stream->read )
+    if ( stream && stream->read )
     {
       FT_Memory  memory = stream->memory;
 
@@ -256,8 +260,8 @@
                                  stream->base, count );
       if ( read_bytes < count )
       {
-        FT_ERROR(( "FT_Stream_EnterFrame:" ));
-        FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n",
+        FT_ERROR(( "FT_Stream_EnterFrame:"
+                   " invalid read; expected %lu bytes, got %lu\n",
                    count, read_bytes ));
 
         FT_FREE( stream->base );
@@ -273,8 +277,8 @@
       if ( stream->pos >= stream->size        ||
            stream->pos + count > stream->size )
       {
-        FT_ERROR(( "FT_Stream_EnterFrame:" ));
-        FT_ERROR(( " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
+        FT_ERROR(( "FT_Stream_EnterFrame:"
+                   " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n",
                    stream->pos, count, stream->size ));
 
         error = FT_Err_Invalid_Stream_Operation;
@@ -459,7 +463,8 @@
 
   Fail:
     *error = FT_Err_Invalid_Stream_Operation;
-    FT_ERROR(( "FT_Stream_ReadChar: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+    FT_ERROR(( "FT_Stream_ReadChar:"
+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
     return 0;
@@ -505,8 +510,8 @@
 
   Fail:
     *error = FT_Err_Invalid_Stream_Operation;
-    FT_ERROR(( "FT_Stream_ReadShort:" ));
-    FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+    FT_ERROR(( "FT_Stream_ReadShort:"
+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
     return 0;
@@ -552,8 +557,8 @@
 
   Fail:
     *error = FT_Err_Invalid_Stream_Operation;
-    FT_ERROR(( "FT_Stream_ReadShortLE:" ));
-    FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+    FT_ERROR(( "FT_Stream_ReadShortLE:"
+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
     return 0;
@@ -599,8 +604,8 @@
 
   Fail:
     *error = FT_Err_Invalid_Stream_Operation;
-    FT_ERROR(( "FT_Stream_ReadOffset:" ));
-    FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+    FT_ERROR(( "FT_Stream_ReadOffset:"
+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
                stream->pos, stream->size ));
 
     return 0;
@@ -645,9 +650,10 @@
     return result;
 
   Fail:
-    FT_ERROR(( "FT_Stream_ReadLong: invalid i/o; pos = 0x%lx, size = 0x%lx\n",
-               stream->pos, stream->size ));
     *error = FT_Err_Invalid_Stream_Operation;
+    FT_ERROR(( "FT_Stream_ReadLong:"
+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+               stream->pos, stream->size ));
 
     return 0;
   }
@@ -691,10 +697,10 @@
     return result;
 
   Fail:
-    FT_ERROR(( "FT_Stream_ReadLongLE:" ));
-    FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
-               stream->pos, stream->size ));
     *error = FT_Err_Invalid_Stream_Operation;
+    FT_ERROR(( "FT_Stream_ReadLongLE:"
+               " invalid i/o; pos = 0x%lx, size = 0x%lx\n",
+               stream->pos, stream->size ));
 
     return 0;
   }
diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c
index 3f5421f..75bcbde 100644
--- a/src/base/ftstroke.c
+++ b/src/base/ftstroke.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType path stroker (body).                                        */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009 by                  */
+/*  Copyright 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010 by            */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -706,7 +706,7 @@
 
     FT_Bool              valid;
     FT_StrokeBorderRec   borders[2];
-    FT_Memory            memory;
+    FT_Library           library;
 
   } FT_StrokerRec;
 
@@ -729,7 +729,7 @@
 
     if ( !FT_NEW( stroker ) )
     {
-      stroker->memory = memory;
+      stroker->library = library;
 
       ft_stroke_border_init( &stroker->borders[0], memory );
       ft_stroke_border_init( &stroker->borders[1], memory );
@@ -777,13 +777,13 @@
   {
     if ( stroker )
     {
-      FT_Memory  memory = stroker->memory;
+      FT_Memory  memory = stroker->library->memory;
 
 
       ft_stroke_border_done( &stroker->borders[0] );
       ft_stroke_border_done( &stroker->borders[1] );
 
-      stroker->memory = NULL;
+      stroker->library = NULL;
       FT_FREE( stroker );
     }
   }
@@ -859,6 +859,31 @@
 
       error = ft_stroke_border_lineto( border, &delta, FALSE );
     }
+    else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT )
+    {
+      /* add a butt ending */
+      FT_Vector        delta;
+      FT_Angle         rotate = FT_SIDE_TO_ROTATE( side );
+      FT_Fixed         radius = stroker->radius;
+      FT_StrokeBorder  border = stroker->borders + side;
+
+
+      FT_Vector_From_Polar( &delta, radius, angle + rotate );
+
+      delta.x += stroker->center.x;
+      delta.y += stroker->center.y;
+
+      error = ft_stroke_border_lineto( border, &delta, FALSE );
+      if ( error )
+        goto Exit;
+
+      FT_Vector_From_Polar( &delta, radius, angle - rotate );
+
+      delta.x += stroker->center.x;
+      delta.y += stroker->center.y;
+
+      error = ft_stroke_border_lineto( border, &delta, FALSE );   
+    }
 
   Exit:
     return error;
@@ -954,7 +979,8 @@
       thcos = FT_Cos( theta );
       sigma = FT_MulFix( stroker->miter_limit, thcos );
 
-      if ( sigma >= 0x10000L )
+      /* FT_Sin(x) = 0 for x <= 57 */
+      if ( sigma >= 0x10000L || ft_pos_abs( theta ) <= 57 )
         miter = FALSE;
 
       if ( miter )  /* this is a miter (broken angle) */
@@ -1335,7 +1361,7 @@
         phi1    = (angle_mid + angle_in ) / 2;
         phi2    = (angle_mid + angle_out ) / 2;
         length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) );
-        length2 = FT_DivFix( stroker->radius, FT_Cos(theta2) );
+        length2 = FT_DivFix( stroker->radius, FT_Cos( theta2 ) );
 
         for ( side = 0; side <= 1; side++ )
         {
@@ -1710,13 +1736,10 @@
         }
         else
         {
-          /* if both first and last points are conic,         */
-          /* start at their middle and record its position    */
-          /* for closure                                      */
+          /* if both first and last points are conic, */
+          /* start at their middle                    */
           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--;
@@ -1844,8 +1867,13 @@
     return FT_Err_Invalid_Outline;
   }
 
-
+/* declare an extern to access ft_outline_glyph_class global allocated 
+   in ftglyph.c, and use the FT_OUTLINE_GLYPH_CLASS_GET macro to access 
+   it when FT_CONFIG_OPTION_PIC is defined */
+#ifndef FT_CONFIG_OPTION_PIC
   extern const FT_Glyph_Class  ft_outline_glyph_class;
+#endif
+#include "basepic.h"
 
 
   /* documentation is in ftstroke.h */
@@ -1857,13 +1885,14 @@
   {
     FT_Error  error = FT_Err_Invalid_Argument;
     FT_Glyph  glyph = NULL;
-
+    FT_Library library = stroker->library;
+    FT_UNUSED(library);
 
     if ( pglyph == NULL )
       goto Exit;
 
     glyph = *pglyph;
-    if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class )
+    if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET )
       goto Exit;
 
     {
@@ -1930,13 +1959,14 @@
   {
     FT_Error  error = FT_Err_Invalid_Argument;
     FT_Glyph  glyph = NULL;
-
+    FT_Library library = stroker->library;
+    FT_UNUSED(library);
 
     if ( pglyph == NULL )
       goto Exit;
 
     glyph = *pglyph;
-    if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class )
+    if ( glyph == NULL || glyph->clazz != FT_OUTLINE_GLYPH_CLASS_GET )
       goto Exit;
 
     {
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index 443d272..ba3c633 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType synthesizing code for emboldening and slanting (body).      */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by                   */
+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2010 by             */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -18,12 +18,22 @@
 
 #include <ft2build.h>
 #include FT_SYNTHESIS_H
+#include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_OUTLINE_H
 #include FT_BITMAP_H
 
 
   /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_synth
+
+  /*************************************************************************/
   /*************************************************************************/
   /****                                                                 ****/
   /****   EXPERIMENTAL OBLIQUING SUPPORT                                ****/
@@ -90,8 +100,8 @@
 
     if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
     {
-      error = FT_Outline_Embolden( &slot->outline, xstr );
       /* ignore error */
+      (void)FT_Outline_Embolden( &slot->outline, xstr );
 
       /* this is more than enough for most glyphs; if you need accurate */
       /* values, you have to call FT_Outline_Get_CBox                   */
@@ -106,6 +116,18 @@
         xstr = 1 << 6;
       ystr &= ~63;
 
+      /*
+       * XXX: overflow check for 16-bit system, for compatibility
+       *      with FT_GlyphSlot_Embolden() since freetype-2.1.10.
+       *      unfortunately, this function return no informations
+       *      about the cause of error.
+       */
+      if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN )
+      {
+        FT_TRACE1(( "FT_GlyphSlot_Embolden:" ));
+        FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr ));
+        return;
+      }
       error = FT_GlyphSlot_Own_Bitmap( slot );
       if ( error )
         return;
@@ -129,8 +151,9 @@
     slot->metrics.vertBearingY += ystr;
     slot->metrics.vertAdvance  += ystr;
 
+    /* XXX: 16-bit overflow case must be excluded before here */
     if ( slot->format == FT_GLYPH_FORMAT_BITMAP )
-      slot->bitmap_top += ystr >> 6;
+      slot->bitmap_top += (FT_Int)( ystr >> 6 );
   }
 
 
diff --git a/src/base/ftsystem.c b/src/base/ftsystem.c
index f64908f..4d06d6d 100644
--- a/src/base/ftsystem.c
+++ b/src/base/ftsystem.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    ANSI-specific FreeType low-level system interface (body).            */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2006, 2008 by                               */
+/*  Copyright 1996-2001, 2002, 2006, 2008, 2009 by                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -205,7 +205,8 @@
 
     file = STREAM_FILE( stream );
 
-    ft_fseek( file, offset, SEEK_SET );
+    if ( stream->pos != offset )
+      ft_fseek( file, offset, SEEK_SET );
 
     return (unsigned long)ft_fread( buffer, 1, count, file );
   }
@@ -226,8 +227,8 @@
     file = ft_fopen( filepathname, "rb" );
     if ( !file )
     {
-      FT_ERROR(( "FT_Stream_Open:" ));
-      FT_ERROR(( " could not open `%s'\n", filepathname ));
+      FT_ERROR(( "FT_Stream_Open:"
+                 " could not open `%s'\n", filepathname ));
 
       return FT_Err_Cannot_Open_Resource;
     }
diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c
index 9f51394..fdf433a 100644
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -72,10 +72,10 @@
     val = ( val >= 0 ) ? val : -val;
 
     v1 = (FT_UInt32)val >> 16;
-    v2 = (FT_UInt32)val & 0xFFFFL;
+    v2 = (FT_UInt32)(val & 0xFFFFL);
 
-    k1 = FT_TRIG_SCALE >> 16;       /* constant */
-    k2 = FT_TRIG_SCALE & 0xFFFFL;   /* constant */
+    k1 = (FT_UInt32)FT_TRIG_SCALE >> 16;       /* constant */
+    k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL);   /* constant */
 
     hi   = k1 * v1;
     lo1  = k1 * v2 + k2 * v1;       /* can't overflow */
@@ -86,7 +86,7 @@
 
     hi  += lo1 >> 16;
     if ( lo1 < lo3 )
-      hi += 0x10000UL;
+      hi += (FT_UInt32)0x10000UL;
 
     val  = (FT_Fixed)hi;
 
@@ -433,7 +433,7 @@
 
       if ( shift > 0 )
       {
-        FT_Int32  half = 1L << ( shift - 1 );
+        FT_Int32  half = (FT_Int32)1L << ( shift - 1 );
 
 
         vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;
diff --git a/src/cff/cff.c b/src/cff/cff.c
index e6d8954..fccfd44 100644
--- a/src/cff/cff.c
+++ b/src/cff/cff.c
@@ -19,6 +19,7 @@
 #define FT_MAKE_OPTION_SINGLE_OBJECT
 
 #include <ft2build.h>
+#include "cffpic.c"
 #include "cffdrivr.c"
 #include "cffparse.c"
 #include "cffload.c"
diff --git a/src/cff/cffcmap.c b/src/cff/cffcmap.c
index 578d048..46d603e 100644
--- a/src/cff/cffcmap.c
+++ b/src/cff/cffcmap.c
@@ -65,7 +65,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   cff_cmap_encoding_char_next( CFF_CMapStd   cmap,
                                FT_UInt32    *pchar_code )
   {
@@ -99,9 +99,7 @@
   }
 
 
-  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
-  cff_cmap_encoding_class_rec =
-  {
+  FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec,
     sizeof ( CFF_CMapStdRec ),
 
     (FT_CMap_InitFunc)     cff_cmap_encoding_init,
@@ -110,7 +108,7 @@
     (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next,
 
     NULL, NULL, NULL, NULL, NULL
-  };
+  )
 
 
   /*************************************************************************/
@@ -194,7 +192,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   cff_cmap_unicode_char_next( PS_Unicodes  unicodes,
                               FT_UInt32   *pchar_code )
   {
@@ -207,9 +205,7 @@
   }
 
 
-  FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec
-  cff_cmap_unicode_class_rec =
-  {
+  FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec,
     sizeof ( PS_UnicodesRec ),
 
     (FT_CMap_InitFunc)     cff_cmap_unicode_init,
@@ -218,7 +214,6 @@
     (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next,
 
     NULL, NULL, NULL, NULL, NULL
-  };
-
+  )
 
 /* END */
diff --git a/src/cff/cffcmap.h b/src/cff/cffcmap.h
index 3809b85..3f7f67b 100644
--- a/src/cff/cffcmap.h
+++ b/src/cff/cffcmap.h
@@ -43,8 +43,7 @@
   } CFF_CMapStdRec;
 
 
-  FT_CALLBACK_TABLE const FT_CMap_ClassRec
-  cff_cmap_encoding_class_rec;
+  FT_DECLARE_CMAP_CLASS(cff_cmap_encoding_class_rec)
 
 
   /*************************************************************************/
@@ -57,8 +56,7 @@
 
   /* unicode (synthetic) cmaps */
 
-  FT_CALLBACK_TABLE const FT_CMap_ClassRec
-  cff_cmap_unicode_class_rec;
+  FT_DECLARE_CMAP_CLASS(cff_cmap_unicode_class_rec)
 
 
 FT_END_HEADER
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 3dd86f2..dad0b65 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -21,7 +21,6 @@
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_SFNT_H
-#include FT_TRUETYPE_IDS_H
 #include FT_SERVICE_CID_H
 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
 #include FT_SERVICE_POSTSCRIPT_INFO_H
@@ -32,8 +31,10 @@
 #include "cffgload.h"
 #include "cffload.h"
 #include "cffcmap.h"
+#include "cffparse.h"
 
 #include "cfferrs.h"
+#include "cffpic.h"
 
 #include FT_SERVICE_XFREE86_NAME_H
 #include FT_SERVICE_GLYPH_DICT_H
@@ -199,7 +200,7 @@
     FT_GlyphSlot  slot  = face->glyph;
 
 
-    flags |= FT_LOAD_ADVANCE_ONLY;
+    flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
 
     for ( nn = 0; nn < count; nn++ )
     {
@@ -238,10 +239,10 @@
     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
     if ( !psnames )
     {
-      FT_ERROR(( "cff_get_glyph_name:" ));
-      FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" ));
-      FT_ERROR(( "                   " ));
-      FT_ERROR(( " without the `PSNames' module\n" ));
+      FT_ERROR(( "cff_get_glyph_name:"
+                 " cannot get glyph name from CFF & CEF fonts\n"
+                 "                   "
+                 " without the `PSNames' module\n" ));
       error = CFF_Err_Unknown_File_Format;
       goto Exit;
     }
@@ -309,11 +310,10 @@
   }
 
 
-  static const FT_Service_GlyphDictRec  cff_service_glyph_dict =
-  {
+  FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict,
     (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,
-    (FT_GlyphDict_NameIndexFunc)cff_get_name_index,
-  };
+    (FT_GlyphDict_NameIndexFunc)cff_get_name_index
+  )
 
 
   /*
@@ -378,13 +378,12 @@
   }
 
 
-  static const FT_Service_PsInfoRec  cff_service_ps_info =
-  {
+  FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info,
     (PS_GetFontInfoFunc)   cff_ps_get_font_info,
     (PS_GetFontExtraFunc)  NULL,
     (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
     (PS_GetFontPrivateFunc)NULL         /* unsupported with CFF fonts */
-  };
+  )
 
 
   /*
@@ -402,10 +401,9 @@
   }
 
 
-  static const FT_Service_PsFontNameRec  cff_service_ps_name =
-  {
+  FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name,
     (FT_PsName_GetFunc)cff_get_ps_name
-  };
+  )
 
 
   /*
@@ -424,16 +422,16 @@
   {
     FT_CMap   cmap  = FT_CMAP( charmap );
     FT_Error  error = CFF_Err_Ok;
+    FT_Face    face    = FT_CMAP_FACE( cmap );
+    FT_Library library = FT_FACE_LIBRARY( face );
 
 
     cmap_info->language = 0;
     cmap_info->format   = 0;
 
-    if ( cmap->clazz != &cff_cmap_encoding_class_rec &&
-         cmap->clazz != &cff_cmap_unicode_class_rec  )
+    if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET &&
+         cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET  )
     {
-      FT_Face             face    = FT_CMAP_FACE( cmap );
-      FT_Library          library = FT_FACE_LIBRARY( face );
       FT_Module           sfnt    = FT_Get_Module( library, "sfnt" );
       FT_Service_TTCMaps  service =
         (FT_Service_TTCMaps)ft_module_get_service( sfnt,
@@ -448,10 +446,9 @@
   }
 
 
-  static const FT_Service_TTCMapsRec  cff_service_get_cmap_info =
-  {
+  FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info,
     (TT_CMap_Info_GetFunc)cff_get_cmap_info
-  };
+  )
 
 
   /*
@@ -498,8 +495,19 @@
         *ordering = cff->ordering;
       }
 
+      /*
+       * XXX: According to Adobe TechNote #5176, the supplement in CFF
+       *      can be a real number. We truncate it to fit public API
+       *      since freetype-2.3.6.
+       */
       if ( supplement )
-        *supplement = dict->cid_supplement;
+      {
+        if ( dict->cid_supplement < FT_INT_MIN ||
+             dict->cid_supplement > FT_INT_MAX )
+          FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
+                      dict->cid_supplement ));
+        *supplement = (FT_Int)dict->cid_supplement;
+      }
     }
       
   Fail:
@@ -570,12 +578,11 @@
   }
 
 
-  static const FT_Service_CIDRec  cff_service_cid_info =
-  {
+  FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info,
     (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,
     (FT_CID_GetIsInternallyCIDKeyedFunc)      cff_get_is_cid,
     (FT_CID_GetCIDFromGlyphIndexFunc)         cff_get_cid_from_glyph_index
-  };
+  )
 
 
   /*************************************************************************/
@@ -589,20 +596,24 @@
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
-
-  static const FT_ServiceDescRec  cff_services[] =
-  {
-    { FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF },
-    { FT_SERVICE_ID_POSTSCRIPT_INFO,      &cff_service_ps_info },
-    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name },
 #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
-    { FT_SERVICE_ID_GLYPH_DICT,           &cff_service_glyph_dict },
+  FT_DEFINE_SERVICEDESCREC6(cff_services,
+    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
+    FT_SERVICE_ID_POSTSCRIPT_INFO,      &FT_CFF_SERVICE_PS_INFO_GET,
+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
+    FT_SERVICE_ID_GLYPH_DICT,           &FT_CFF_SERVICE_GLYPH_DICT_GET,
+    FT_SERVICE_ID_TT_CMAP,              &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
+    FT_SERVICE_ID_CID,                  &FT_CFF_SERVICE_CID_INFO_GET
+  )
+#else
+  FT_DEFINE_SERVICEDESCREC5(cff_services,
+    FT_SERVICE_ID_XF86_NAME,            FT_XF86_FORMAT_CFF,
+    FT_SERVICE_ID_POSTSCRIPT_INFO,      &FT_CFF_SERVICE_PS_INFO_GET,
+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
+    FT_SERVICE_ID_TT_CMAP,              &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
+    FT_SERVICE_ID_CID,                  &FT_CFF_SERVICE_CID_INFO_GET
+  )
 #endif
-    { FT_SERVICE_ID_TT_CMAP,              &cff_service_get_cmap_info },
-    { FT_SERVICE_ID_CID,                  &cff_service_cid_info },
-    { NULL, NULL }
-  };
-
 
   FT_CALLBACK_DEF( FT_Module_Interface )
   cff_get_interface( FT_Module    driver,       /* CFF_Driver */
@@ -612,10 +623,13 @@
     FT_Module_Interface  result;
 
 
-    result = ft_service_list_lookup( cff_services, module_interface );
+    result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface );
     if ( result != NULL )
       return  result;
 
+    if ( !driver )
+      return NULL;
+
     /* we pass our request to the `sfnt' module */
     sfnt = FT_Get_Module( driver->library, "sfnt" );
 
@@ -625,11 +639,13 @@
 
   /* The FT_DriverInterface structure is defined in ftdriver.h. */
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Driver_ClassRec  cff_driver_class =
-  {
-    /* begin with the FT_Module_Class fields */
-    {
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#define CFF_SIZE_SELECT cff_size_select
+#else
+#define CFF_SIZE_SELECT 0
+#endif
+
+  FT_DEFINE_DRIVER(cff_driver_class,
       FT_MODULE_FONT_DRIVER       |
       FT_MODULE_DRIVER_SCALABLE   |
       FT_MODULE_DRIVER_HAS_HINTER,
@@ -644,7 +660,6 @@
       cff_driver_init,
       cff_driver_done,
       cff_get_interface,
-    },
 
     /* now the specific driver fields */
     sizeof( TT_FaceRec ),
@@ -658,10 +673,8 @@
     cff_slot_init,
     cff_slot_done,
 
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-    ft_stub_set_char_sizes,
-    ft_stub_set_pixel_sizes,
-#endif
+    ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+    ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
 
     Load_Glyph,
 
@@ -671,12 +684,8 @@
 
     cff_size_request,
 
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-    cff_size_select
-#else
-    0                       /* FT_Size_SelectFunc      */
-#endif
-  };
+    CFF_SIZE_SELECT
+  )
 
 
 /* END */
diff --git a/src/cff/cffdrivr.h b/src/cff/cffdrivr.h
index 553848c..50e8138 100644
--- a/src/cff/cffdrivr.h
+++ b/src/cff/cffdrivr.h
@@ -27,8 +27,7 @@
 FT_BEGIN_HEADER
 
 
-  FT_CALLBACK_TABLE
-  const FT_Driver_ClassRec  cff_driver_class;
+  FT_DECLARE_DRIVER( cff_driver_class )
 
 
 FT_END_HEADER
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 2718a27..9330c05 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (body).                                        */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
+/*            2010 by                                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -18,11 +19,9 @@
 
 #include <ft2build.h>
 #include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_CALC_H
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_SFNT_H
 #include FT_OUTLINE_H
-#include FT_TRUETYPE_TAGS_H
 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
 
 #include "cffobjs.h"
@@ -115,6 +114,9 @@
     cff_op_closepath,
     cff_op_callothersubr,
     cff_op_pop,
+    cff_op_seac,
+    cff_op_sbw,
+    cff_op_setcurrentpoint,
 
     /* do not remove */
     cff_op_max
@@ -203,7 +205,10 @@
     2, /* hsbw */
     0,
     0,
-    0
+    0,
+    5, /* seac */
+    4, /* sbw */
+    2  /* setcurrentpoint */
   };
 
 
@@ -321,17 +326,23 @@
   /*    subroutines.                                                       */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    num_subrs :: The number of glyph subroutines.                      */
+  /*    in_charstring_type :: The `CharstringType' value of the top DICT   */
+  /*                          dictionary.                                  */
+  /*                                                                       */
+  /*    num_subrs          :: The number of glyph subroutines.             */
   /*                                                                       */
   /* <Return>                                                              */
   /*    The bias value.                                                    */
   static FT_Int
-  cff_compute_bias( FT_UInt  num_subrs )
+  cff_compute_bias( FT_Int   in_charstring_type,
+                    FT_UInt  num_subrs )
   {
     FT_Int  result;
 
 
-    if ( num_subrs < 1240 )
+    if ( in_charstring_type == 1 )
+      result = 0;
+    else if ( num_subrs < 1240 )
       result = 107;
     else if ( num_subrs < 33900U )
       result = 1131;
@@ -382,9 +393,12 @@
     cff_builder_init( &decoder->builder, face, size, slot, hinting );
 
     /* initialize Type2 decoder */
+    decoder->cff          = cff;
     decoder->num_globals  = cff->num_global_subrs;
     decoder->globals      = cff->global_subrs;
-    decoder->globals_bias = cff_compute_bias( decoder->num_globals );
+    decoder->globals_bias = cff_compute_bias(
+                              cff->top_font.font_dict.charstring_type,
+                              decoder->num_globals );
 
     decoder->hint_mode    = hint_mode;
   }
@@ -436,7 +450,9 @@
 
     decoder->num_locals    = sub->num_local_subrs;
     decoder->locals        = sub->local_subrs;
-    decoder->locals_bias   = cff_compute_bias( decoder->num_locals );
+    decoder->locals_bias   = cff_compute_bias(
+                               decoder->cff->top_font.font_dict.charstring_type,
+                               decoder->num_locals );
 
     decoder->glyph_width   = sub->private_dict.default_width;
     decoder->nominal_width = sub->private_dict.nominal_width;
@@ -474,8 +490,6 @@
       point->x = x >> 16;
       point->y = y >> 16;
       *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
-
-      builder->last = *point;
     }
 
     outline->n_points++;
@@ -554,27 +568,24 @@
   cff_builder_close_contour( CFF_Builder*  builder )
   {
     FT_Outline*  outline = builder->current;
+    FT_Int       first;
 
 
     if ( !outline )
       return;
 
-    /* XXXX: We must not include the last point in the path if it */
-    /*       is located on the first point.                       */
+    first = outline->n_contours <= 1
+            ? 0 : outline->contours[outline->n_contours - 2] + 1;
+
+    /* We must not include the last point in the path if it */
+    /* is located on the first point.                       */
     if ( outline->n_points > 1 )
     {
-      FT_Int      first   = 0;
       FT_Vector*  p1      = outline->points + first;
       FT_Vector*  p2      = outline->points + outline->n_points - 1;
       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points - 1;
 
 
-      if ( outline->n_contours > 1 )
-      {
-        first = outline->contours[outline->n_contours - 2] + 1;
-        p1    = outline->points + first;
-      }
-
       /* `delete' last point only if it coincides with the first    */
       /* point and if it is not a control point (which can happen). */
       if ( p1->x == p2->x && p1->y == p2->y )
@@ -583,8 +594,18 @@
     }
 
     if ( outline->n_contours > 0 )
-      outline->contours[outline->n_contours - 1] =
-        (short)( outline->n_points - 1 );
+    {
+      /* Don't add contours only consisting of one point, i.e., */
+      /* check whether begin point and last point are the same. */
+      if ( first == outline->n_points - 1 )
+      {
+        outline->n_contours--;
+        outline->n_points--;
+      }
+      else
+        outline->contours[outline->n_contours - 1] =
+          (short)( outline->n_points - 1 );
+    }
   }
 
 
@@ -674,7 +695,7 @@
       data.length  = length;
 
       face->root.internal->incremental_interface->funcs->free_glyph_data(
-        face->root.internal->incremental_interface->object,&data );
+        face->root.internal->incremental_interface->object, &data );
     }
     else
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
@@ -690,6 +711,7 @@
 
   static FT_Error
   cff_operator_seac( CFF_Decoder*  decoder,
+                     FT_Pos        asb,
                      FT_Pos        adx,
                      FT_Pos        ady,
                      FT_Int        bchar,
@@ -702,8 +724,18 @@
     FT_Vector     left_bearing, advance;
     FT_Byte*      charstring;
     FT_ULong      charstring_len;
+    FT_Pos        glyph_width;
 
 
+    if ( decoder->seac )
+    {
+      FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
+      return CFF_Err_Syntax_Error;
+    }
+
+    adx += decoder->builder.left_bearing.x;
+    ady += decoder->builder.left_bearing.y;
+
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     /* Incremental fonts don't necessarily have valid charsets.        */
     /* They use the character code, not the glyph index, in this case. */
@@ -724,8 +756,8 @@
 
     if ( bchar_index < 0 || achar_index < 0 )
     {
-      FT_ERROR(( "cff_operator_seac:" ));
-      FT_ERROR(( " invalid seac character code arguments\n" ));
+      FT_ERROR(( "cff_operator_seac:"
+                 " invalid seac character code arguments\n" ));
       return CFF_Err_Syntax_Error;
     }
 
@@ -774,8 +806,11 @@
                                 &charstring, &charstring_len );
     if ( !error )
     {
+      /* the seac operator must not be nested */
+      decoder->seac = TRUE;
       error = cff_decoder_parse_charstrings( decoder, charstring,
                                              charstring_len );
+      decoder->seac = FALSE;
 
       if ( error )
         goto Exit;
@@ -783,16 +818,17 @@
       cff_free_glyph_data( face, &charstring, charstring_len );
     }
 
-    /* Save the left bearing and width of the base character */
-    /* as they will be erased by the next load.              */
+    /* Save the left bearing, advance and glyph width of the base */
+    /* character as they will be erased by the next load.         */
 
     left_bearing = builder->left_bearing;
     advance      = builder->advance;
+    glyph_width  = decoder->glyph_width;
 
     builder->left_bearing.x = 0;
     builder->left_bearing.y = 0;
 
-    builder->pos_x = adx;
+    builder->pos_x = adx - asb;
     builder->pos_y = ady;
 
     /* Now load `achar' on top of the base outline. */
@@ -800,8 +836,11 @@
                                 &charstring, &charstring_len );
     if ( !error )
     {
+      /* the seac operator must not be nested */
+      decoder->seac = TRUE;
       error = cff_decoder_parse_charstrings( decoder, charstring,
                                              charstring_len );
+      decoder->seac = FALSE;
 
       if ( error )
         goto Exit;
@@ -809,10 +848,11 @@
       cff_free_glyph_data( face, &charstring, charstring_len );
     }
 
-    /* Restore the left side bearing and advance width */
-    /* of the base character.                          */
+    /* Restore the left side bearing, advance and glyph width */
+    /* of the base character.                                 */
     builder->left_bearing = left_bearing;
     builder->advance      = advance;
+    decoder->glyph_width  = glyph_width;
 
     builder->pos_x = 0;
     builder->pos_y = 0;
@@ -854,6 +894,8 @@
     FT_Pos             x, y;
     FT_Fixed           seed;
     FT_Fixed*          stack;
+    FT_Int             charstring_type =
+                         decoder->cff->top_font.font_dict.charstring_type;
 
     T2_Hints_Funcs     hinter;
 
@@ -863,9 +905,10 @@
     decoder->read_width = 1;
 
     /* compute random seed from stack address of parameter */
-    seed = (FT_Fixed)(char*)&seed           ^
-           (FT_Fixed)(char*)&decoder        ^
-           (FT_Fixed)(char*)&charstring_base;
+    seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed              ^
+                         (FT_PtrDist)(char*)&decoder           ^
+                         (FT_PtrDist)(char*)&charstring_base ) &
+                         FT_ULONG_MAX ) ;
     seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
     if ( seed == 0 )
       seed = 0x7384;
@@ -920,18 +963,18 @@
           ip += 2;
         }
         else if ( v < 247 )
-          val = (FT_Long)v - 139;
+          val = (FT_Int32)v - 139;
         else if ( v < 251 )
         {
           if ( ip >= limit )
             goto Syntax_Error;
-          val = ( (FT_Long)v - 247 ) * 256 + *ip++ + 108;
+          val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
         }
         else if ( v < 255 )
         {
           if ( ip >= limit )
             goto Syntax_Error;
-          val = -( (FT_Long)v - 251 ) * 256 - *ip++ - 108;
+          val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
         }
         else
         {
@@ -942,7 +985,8 @@
                 ( (FT_Int32)ip[2] <<  8 ) |
                             ip[3];
           ip    += 4;
-          shift  = 0;
+          if ( charstring_type == 2 )
+            shift = 0;
         }
         if ( decoder->top - stack >= CFF_MAX_OPERANDS )
           goto Stack_Overflow;
@@ -1016,6 +1060,12 @@
             case 0:
               op = cff_op_dotsection;
               break;
+            case 1: /* this is actually the Type1 vstem3 operator */
+              op = cff_op_vstem;
+              break;
+            case 2: /* this is actually the Type1 hstem3 operator */
+              op = cff_op_hstem;
+              break;
             case 3:
               op = cff_op_and;
               break;
@@ -1025,6 +1075,12 @@
             case 5:
               op = cff_op_not;
               break;
+            case 6:
+              op = cff_op_seac;
+              break;
+            case 7:
+              op = cff_op_sbw;
+              break;
             case 8:
               op = cff_op_store;
               break;
@@ -1088,6 +1144,9 @@
             case 30:
               op = cff_op_roll;
               break;
+            case 33:
+              op = cff_op_setcurrentpoint;
+              break;
             case 34:
               op = cff_op_hflex;
               break;
@@ -1155,7 +1214,7 @@
           op = cff_op_hvcurveto;
           break;
         default:
-          ;
+          break;
         }
 
         if ( op == cff_op_unknown )
@@ -1870,6 +1929,21 @@
           }
           break;
 
+        case cff_op_seac:
+            FT_TRACE4(( " seac\n" ));
+
+            error = cff_operator_seac( decoder,
+                                       args[0], args[1], args[2],
+                                       (FT_Int)( args[3] >> 16 ),
+                                       (FT_Int)( args[4] >> 16 ) );
+
+            /* add current outline to the glyph slot */
+            FT_GlyphLoader_Add( builder->loader );
+
+            /* return now! */
+            FT_TRACE4(( "\n" ));
+            return error;
+
         case cff_op_endchar:
           FT_TRACE4(( " endchar\n" ));
 
@@ -1879,10 +1953,8 @@
             /* Save glyph width so that the subglyphs don't overwrite it. */
             FT_Pos  glyph_width = decoder->glyph_width;
 
-
             error = cff_operator_seac( decoder,
-                                       args[-4],
-                                       args[-3],
+                                       0L, args[-4], args[-3],
                                        (FT_Int)( args[-2] >> 16 ),
                                        (FT_Int)( args[-1] >> 16 ) );
 
@@ -2090,7 +2162,7 @@
           FT_TRACE4(( " dup\n" ));
 
           args[1] = args[0];
-          args++;
+          args += 2;
           break;
 
         case cff_op_put:
@@ -2101,7 +2173,7 @@
 
             FT_TRACE4(( " put\n" ));
 
-            if ( idx >= 0 && idx < decoder->len_buildchar )
+            if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
               decoder->buildchar[idx] = val;
           }
           break;
@@ -2114,7 +2186,7 @@
 
             FT_TRACE4(( " get\n" ));
 
-            if ( idx >= 0 && idx < decoder->len_buildchar )
+            if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
               val = decoder->buildchar[idx];
 
             args[0] = val;
@@ -2154,10 +2226,42 @@
 
           FT_TRACE4(( " hsbw (invalid op)\n" ));
 
-          decoder->glyph_width = decoder->nominal_width +
-                                   (args[1] >> 16);
-          x    = args[0];
-          y    = 0;
+          decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 );
+
+          decoder->builder.left_bearing.x = args[0];
+          decoder->builder.left_bearing.y = 0;
+
+          x    = decoder->builder.pos_x + args[0];
+          y    = decoder->builder.pos_y;
+          args = stack;
+          break;
+
+        case cff_op_sbw:
+          /* this is an invalid Type 2 operator; however, there        */
+          /* exist fonts which are incorrectly converted from probably */
+          /* Type 1 to CFF, and some parsers seem to accept it         */
+
+          FT_TRACE4(( " sbw (invalid op)\n" ));
+
+          decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 );
+
+          decoder->builder.left_bearing.x = args[0];
+          decoder->builder.left_bearing.y = args[1];
+
+          x    = decoder->builder.pos_x + args[0];
+          y    = decoder->builder.pos_y + args[1];
+          args = stack;
+          break;
+
+        case cff_op_setcurrentpoint:
+          /* this is an invalid Type 2 operator; however, there        */
+          /* exist fonts which are incorrectly converted from probably */
+          /* Type 1 to CFF, and some parsers seem to accept it         */
+
+          FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
+
+          x    = decoder->builder.pos_x + args[0];
+          y    = decoder->builder.pos_y + args[1];
           args = stack;
           break;
 
@@ -2168,8 +2272,10 @@
 
           FT_TRACE4(( " callothersubr (invalid op)\n" ));
 
-          /* don't modify stack; handle the subr as `unknown' so that */
-          /* following `pop' operands use the arguments on stack      */
+          /* subsequent `pop' operands should add the arguments,       */
+          /* this is the implementation described for `unknown' other  */
+          /* subroutines in the Type1 spec.                            */
+          args -= 2 + ( args[-2] >> 16 );
           break;
 
         case cff_op_pop:
@@ -2241,8 +2347,8 @@
 
             if ( idx >= decoder->num_locals )
             {
-              FT_ERROR(( "cff_decoder_parse_charstrings:" ));
-              FT_ERROR(( " invalid local subr index\n" ));
+              FT_ERROR(( "cff_decoder_parse_charstrings:"
+                         " invalid local subr index\n" ));
               goto Syntax_Error;
             }
 
@@ -2263,7 +2369,7 @@
             if ( !zone->base || zone->limit == zone->base )
             {
               FT_ERROR(( "cff_decoder_parse_charstrings:"
-                         " invoking empty subrs!\n" ));
+                         " invoking empty subrs\n" ));
               goto Syntax_Error;
             }
 
@@ -2283,8 +2389,8 @@
 
             if ( idx >= decoder->num_globals )
             {
-              FT_ERROR(( "cff_decoder_parse_charstrings:" ));
-              FT_ERROR(( " invalid global subr index\n" ));
+              FT_ERROR(( "cff_decoder_parse_charstrings:"
+                         " invalid global subr index\n" ));
               goto Syntax_Error;
             }
 
@@ -2305,7 +2411,7 @@
             if ( !zone->base || zone->limit == zone->base )
             {
               FT_ERROR(( "cff_decoder_parse_charstrings:"
-                         " invoking empty subrs!\n" ));
+                         " invoking empty subrs\n" ));
               goto Syntax_Error;
             }
 
@@ -2354,15 +2460,15 @@
     return error;
 
   Syntax_Error:
-    FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!\n" ));
+    FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
     return CFF_Err_Invalid_File_Format;
 
   Stack_Underflow:
-    FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!\n" ));
+    FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
     return CFF_Err_Too_Few_Arguments;
 
   Stack_Overflow:
-    FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!\n" ));
+    FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
     return CFF_Err_Stack_Overflow;
   }
 
@@ -2565,8 +2671,8 @@
       FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select,
                                              glyph_index );
 
-      FT_Int  top_upm = cff->top_font.font_dict.units_per_em;
-      FT_Int  sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
+      FT_ULong  top_upm = cff->top_font.font_dict.units_per_em;
+      FT_ULong  sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
 
 
       font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
@@ -2658,23 +2764,25 @@
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 
     /* Incremental fonts can optionally override the metrics. */
-    if ( !error                                                              &&
-         face->root.internal->incremental_interface                          &&
+    if ( !error                                                               &&
+         face->root.internal->incremental_interface                           &&
          face->root.internal->incremental_interface->funcs->get_glyph_metrics )
     {
       FT_Incremental_MetricsRec  metrics;
 
 
       metrics.bearing_x = decoder.builder.left_bearing.x;
-      metrics.bearing_y = decoder.builder.left_bearing.y;
+      metrics.bearing_y = 0;
       metrics.advance   = decoder.builder.advance.x;
+      metrics.advance_v = decoder.builder.advance.y;
+
       error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
                 face->root.internal->incremental_interface->object,
                 glyph_index, FALSE, &metrics );
+
       decoder.builder.left_bearing.x = metrics.bearing_x;
-      decoder.builder.left_bearing.y = metrics.bearing_y;
       decoder.builder.advance.x      = metrics.advance;
-      decoder.builder.advance.y      = 0;
+      decoder.builder.advance.y      = metrics.advance_v;
     }
 
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
@@ -2711,9 +2819,14 @@
         glyph->root.linearHoriAdvance           = decoder.glyph_width;
         glyph->root.internal->glyph_transformed = 0;
 
+#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
         has_vertical_info = FT_BOOL( face->vertical_info                   &&
                                      face->vertical.number_Of_VMetrics > 0 &&
                                      face->vertical.long_metrics           );
+#else
+        has_vertical_info = FT_BOOL( face->vertical_info                   &&
+                                     face->vertical.number_Of_VMetrics > 0 );
+#endif
 
         /* get the vertical metrics from the vtmx table if we have one */
         if ( has_vertical_info )
@@ -2750,8 +2863,8 @@
 
         glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
 
-        /* apply the font matrix -- `xx' has already been normalized */
-        if ( !( font_matrix.yy == 0x10000L &&
+        if ( !( font_matrix.xx == 0x10000L &&
+                font_matrix.yy == 0x10000L &&
                 font_matrix.xy == 0        &&
                 font_matrix.yx == 0        ) )
           FT_Outline_Transform( &glyph->root.outline, &font_matrix );
@@ -2804,10 +2917,14 @@
         metrics->horiBearingY = cbox.yMax;
 
         if ( has_vertical_info )
-          metrics->vertBearingX = -metrics->width / 2;
-        else
-          ft_synthesize_vertical_metrics( metrics,
-                                          metrics->vertAdvance );
+          metrics->vertBearingX = metrics->horiBearingX -
+                                    metrics->horiAdvance / 2;
+        else 
+        {
+          if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
+            ft_synthesize_vertical_metrics( metrics,
+                                            metrics->vertAdvance );
+        }
       }
     }
 
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index 667134e..38937be 100644
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (specification).                               */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by             */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009 by       */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -28,8 +28,9 @@
 FT_BEGIN_HEADER
 
 
-#define CFF_MAX_OPERANDS     48
-#define CFF_MAX_SUBRS_CALLS  32
+#define CFF_MAX_OPERANDS        48
+#define CFF_MAX_SUBRS_CALLS     32
+#define CFF_MAX_TRANS_ELEMENTS  32
 
 
   /*************************************************************************/
@@ -53,8 +54,6 @@
   /*                                                                       */
   /*    current       :: The current glyph outline.                        */
   /*                                                                       */
-  /*    last          :: The last point position.                          */
-  /*                                                                       */
   /*    pos_x         :: The horizontal translation (if composite glyph).  */
   /*                                                                       */
   /*    pos_y         :: The vertical translation (if composite glyph).    */
@@ -88,8 +87,6 @@
     FT_Outline*     base;
     FT_Outline*     current;
 
-    FT_Vector       last;
-
     FT_Pos          pos_x;
     FT_Pos          pos_y;
 
@@ -141,8 +138,7 @@
     FT_Bool            read_width;
     FT_Bool            width_only;
     FT_Int             num_hints;
-    FT_Fixed*          buildchar;
-    FT_Int             len_buildchar;
+    FT_Fixed           buildchar[CFF_MAX_TRANS_ELEMENTS];
 
     FT_UInt            num_locals;
     FT_UInt            num_globals;
@@ -158,6 +154,8 @@
 
     FT_Render_Mode     hint_mode;
 
+    FT_Bool            seac;
+
   } CFF_Decoder;
 
 
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 22163fb..64d1395 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -736,6 +736,7 @@
   {
     FT_Error   error   = FT_Err_Ok;
     FT_UInt    i;
+    FT_Long    j;
     FT_UShort  max_cid = 0;
 
 
@@ -750,8 +751,11 @@
     if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
       goto Exit;
 
-    for ( i = 0; i < num_glyphs; i++ )
-      charset->cids[charset->sids[i]] = (FT_UShort)i;
+    /* When multiple GIDs map to the same CID, we choose the lowest */
+    /* GID.  This is not described in any spec, but it matches the  */
+    /* behaviour of recent Acroread versions.                       */
+    for ( j = num_glyphs - 1; j >= 0 ; j-- )
+      charset->cids[charset->sids[j]] = (FT_UShort)j;
 
     charset->max_cid    = max_cid;
     charset->num_glyphs = num_glyphs;
@@ -842,7 +846,20 @@
             goto Exit;
 
           for ( j = 1; j < num_glyphs; j++ )
-            charset->sids[j] = FT_GET_USHORT();
+          {
+            FT_UShort sid = FT_GET_USHORT();
+
+
+            /* this constant is given in the CFF specification */
+            if ( sid < 65000L )
+              charset->sids[j] = sid;
+            else
+            {
+              FT_TRACE0(( "cff_charset_load:"
+                          " invalid SID value %d set to zero\n", sid ));
+              charset->sids[j] = 0;
+            }
+          }
 
           FT_FRAME_EXIT();
         }
@@ -875,6 +892,20 @@
                 goto Exit;
             }
 
+            /* check whether the range contains at least one valid glyph; */
+            /* the constant is given in the CFF specification             */
+            if ( glyph_sid >= 65000L ) {
+              FT_ERROR(( "cff_charset_load: invalid SID range\n" ));
+              error = CFF_Err_Invalid_File_Format;
+              goto Exit;
+            }
+
+            /* try to rescue some of the SIDs if `nleft' is too large */
+            if ( nleft > 65000L - 1L || glyph_sid >= 65000L - nleft ) {
+              FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" ));
+              nleft = ( FT_UInt )( 65000L - 1L - glyph_sid );
+            }
+
             /* Fill in the range of sids -- `nleft + 1' glyphs. */
             for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
               charset->sids[j] = glyph_sid;
@@ -883,7 +914,7 @@
         break;
 
       default:
-        FT_ERROR(( "cff_charset_load: invalid table format!\n" ));
+        FT_ERROR(( "cff_charset_load: invalid table format\n" ));
         error = CFF_Err_Invalid_File_Format;
         goto Exit;
       }
@@ -906,7 +937,7 @@
         if ( num_glyphs > 229 )
         {
           FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
-                     "predefined charset (Adobe ISO-Latin)!\n" ));
+                     "predefined charset (Adobe ISO-Latin)\n" ));
           error = CFF_Err_Invalid_File_Format;
           goto Exit;
         }
@@ -924,7 +955,7 @@
         if ( num_glyphs > 166 )
         {
           FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
-                     "predefined charset (Adobe Expert)!\n" ));
+                     "predefined charset (Adobe Expert)\n" ));
           error = CFF_Err_Invalid_File_Format;
           goto Exit;
         }
@@ -942,7 +973,7 @@
         if ( num_glyphs > 87 )
         {
           FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
-                     "predefined charset (Adobe Expert Subset)!\n" ));
+                     "predefined charset (Adobe Expert Subset)\n" ));
           error = CFF_Err_Invalid_File_Format;
           goto Exit;
         }
@@ -1127,7 +1158,7 @@
         break;
 
       default:
-        FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
+        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
         error = CFF_Err_Invalid_File_Format;
         goto Exit;
       }
@@ -1222,7 +1253,7 @@
         break;
 
       default:
-        FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
+        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
         error = CFF_Err_Invalid_File_Format;
         goto Exit;
       }
@@ -1240,7 +1271,8 @@
                     CFF_Index    idx,
                     FT_UInt      font_index,
                     FT_Stream    stream,
-                    FT_ULong     base_offset )
+                    FT_ULong     base_offset,
+                    FT_Library   library )
   {
     FT_Error         error;
     CFF_ParserRec    parser;
@@ -1250,7 +1282,7 @@
     CFF_Private      priv = &font->private_dict;
 
 
-    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict );
+    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
 
     /* set defaults */
     FT_MEM_ZERO( top, sizeof ( *top ) );
@@ -1301,7 +1333,7 @@
       priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
       priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
 
-      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv );
+      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
 
       if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
            FT_FRAME_ENTER( font->font_dict.private_size )                 )
@@ -1354,7 +1386,8 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  cff_font_load( FT_Stream  stream,
+  cff_font_load( FT_Library library,
+                 FT_Stream  stream,
                  FT_Int     face_index,
                  CFF_Font   font,
                  FT_Bool    pure_cff )
@@ -1394,7 +1427,7 @@
          font->header_size      < 4 ||
          font->absolute_offsize > 4 )
     {
-      FT_TRACE2(( "[not a CFF font header!]\n" ));
+      FT_TRACE2(( "[not a CFF font header]\n" ));
       error = CFF_Err_Unknown_File_Format;
       goto Exit;
     }
@@ -1432,7 +1465,8 @@
                               &font->font_dict_index,
                               face_index,
                               stream,
-                              base_offset );
+                              base_offset,
+                              library );
     if ( error )
       goto Exit;
 
@@ -1462,7 +1496,7 @@
 
       if ( fd_index.count > CFF_MAX_CID_FONTS )
       {
-        FT_ERROR(( "cff_font_load: FD array too large in CID font\n" ));
+        FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
         goto Fail_CID;
       }
 
@@ -1480,7 +1514,7 @@
       {
         sub = font->subfonts[idx];
         error = cff_subfont_load( sub, &fd_index, idx,
-                                  stream, base_offset );
+                                  stream, base_offset, library );
         if ( error )
           goto Fail_CID;
       }
@@ -1503,7 +1537,7 @@
     /* read the charstrings index now */
     if ( dict->charstrings_offset == 0 )
     {
-      FT_ERROR(( "cff_font_load: no charstrings offset!\n" ));
+      FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
       error = CFF_Err_Unknown_File_Format;
       goto Exit;
     }
diff --git a/src/cff/cffload.h b/src/cff/cffload.h
index 02498bd..2b313ac 100644
--- a/src/cff/cffload.h
+++ b/src/cff/cffload.h
@@ -58,7 +58,8 @@
 
 
   FT_LOCAL( FT_Error )
-  cff_font_load( FT_Stream  stream,
+  cff_font_load( FT_Library library, 
+                 FT_Stream  stream,
                  FT_Int     face_index,
                  CFF_Font   font,
                  FT_Bool    pure_cff );
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 3525ea3..bd56c4b 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType objects manager (body).                                     */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -30,6 +30,7 @@
 #include "cffload.h"
 #include "cffcmap.h"
 #include "cfferrs.h"
+#include "cffpic.h"
 
 
   /*************************************************************************/
@@ -223,8 +224,8 @@
       CFF_Font      font     = (CFF_Font)face->extra.data;
       CFF_Internal  internal = (CFF_Internal)size->internal;
 
-      FT_Int   top_upm  = font->top_font.font_dict.units_per_em;
-      FT_UInt  i;
+      FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
+      FT_UInt   i;
 
 
       funcs->set_scale( internal->topfont,
@@ -234,7 +235,7 @@
       for ( i = font->num_subfonts; i > 0; i-- )
       {
         CFF_SubFont  sub     = font->subfonts[i - 1];
-        FT_Int       sub_upm = sub->font_dict.units_per_em;
+        FT_ULong     sub_upm = sub->font_dict.units_per_em;
         FT_Pos       x_scale, y_scale;
 
 
@@ -295,8 +296,8 @@
       CFF_Font      font     = (CFF_Font)cffface->extra.data;
       CFF_Internal  internal = (CFF_Internal)size->internal;
 
-      FT_Int   top_upm  = font->top_font.font_dict.units_per_em;
-      FT_UInt  i;
+      FT_ULong  top_upm  = font->top_font.font_dict.units_per_em;
+      FT_UInt   i;
 
 
       funcs->set_scale( internal->topfont,
@@ -306,7 +307,7 @@
       for ( i = font->num_subfonts; i > 0; i-- )
       {
         CFF_SubFont  sub     = font->subfonts[i - 1];
-        FT_Int       sub_upm = sub->font_dict.units_per_em;
+        FT_ULong     sub_upm = sub->font_dict.units_per_em;
         FT_Pos       x_scale, y_scale;
 
 
@@ -408,6 +409,7 @@
     PSHinter_Service    pshinter;
     FT_Bool             pure_cff    = 1;
     FT_Bool             sfnt_format = 0;
+    FT_Library library = cffface->driver->root.library;
 
 
 #if 0
@@ -419,14 +421,14 @@
       goto Bad_Format;
 #else
     sfnt = (SFNT_Service)FT_Get_Module_Interface(
-             cffface->driver->root.library, "sfnt" );
+             library, "sfnt" );
     if ( !sfnt )
       goto Bad_Format;
 
     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
 
     pshinter = (PSHinter_Service)FT_Get_Module_Interface(
-                 cffface->driver->root.library, "pshinter" );
+                 library, "pshinter" );
 #endif
 
     /* create input stream from resource */
@@ -507,7 +509,7 @@
         goto Exit;
 
       face->extra.data = cff;
-      error = cff_font_load( stream, face_index, cff, pure_cff );
+      error = cff_font_load( library, stream, face_index, cff, pure_cff );
       if ( error )
         goto Exit;
 
@@ -528,10 +530,10 @@
       /* which aren't CID-keyed                               */
       if ( dict->cid_registry == 0xFFFFU && !psnames )
       {
-        FT_ERROR(( "cff_face_init:" ));
-        FT_ERROR(( " cannot open CFF & CEF fonts\n" ));
-        FT_ERROR(( "              " ));
-        FT_ERROR(( " without the `PSNames' module\n" ));
+        FT_ERROR(( "cff_face_init:"
+                   " cannot open CFF & CEF fonts\n"
+                   "              "
+                   " without the `PSNames' module\n" ));
         goto Bad_Format;
       }
 
@@ -582,7 +584,7 @@
 
         if ( sub->units_per_em )
         {
-          FT_Int  scaling;
+          FT_Long  scaling;
 
 
           if ( top->units_per_em > 1 && sub->units_per_em > 1 )
@@ -655,10 +657,11 @@
           cffface->num_glyphs = cff->charstrings_index.count;
 
         /* set global bbox, as well as EM size */
-        cffface->bbox.xMin =   dict->font_bbox.xMin             >> 16;
-        cffface->bbox.yMin =   dict->font_bbox.yMin             >> 16;
-        cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16;
-        cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16;
+        cffface->bbox.xMin =   dict->font_bbox.xMin            >> 16;
+        cffface->bbox.yMin =   dict->font_bbox.yMin            >> 16;
+        /* no `U' suffix here to 0xFFFF! */
+        cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16;
+        cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16;
 
         cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
 
@@ -764,22 +767,22 @@
         /*                                                                 */
         /* Compute face flags.                                             */
         /*                                                                 */
-        flags = FT_FACE_FLAG_SCALABLE   |       /* scalable outlines */
-                FT_FACE_FLAG_HORIZONTAL |       /* horizontal data   */
-                FT_FACE_FLAG_HINTER;            /* has native hinter */
+        flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE   | /* scalable outlines */
+                             FT_FACE_FLAG_HORIZONTAL | /* horizontal data   */
+                             FT_FACE_FLAG_HINTER );    /* has native hinter */
 
         if ( sfnt_format )
-          flags |= FT_FACE_FLAG_SFNT;
+          flags |= (FT_UInt32)FT_FACE_FLAG_SFNT;
 
         /* fixed width font? */
         if ( dict->is_fixed_pitch )
-          flags |= FT_FACE_FLAG_FIXED_WIDTH;
+          flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH;
 
   /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
 #if 0
         /* kerning available? */
         if ( face->kern_pairs )
-          flags |= FT_FACE_FLAG_KERNING;
+          flags |= (FT_UInt32)FT_FACE_FLAG_KERNING;
 #endif
 
         cffface->face_flags = flags;
@@ -868,7 +871,7 @@
 
         nn = (FT_UInt)cffface->num_charmaps;
 
-        FT_CMap_New( &cff_cmap_unicode_class_rec, NULL, &cmaprec, NULL );
+        FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, &cmaprec, NULL );
 
         /* if no Unicode charmap was previously selected, select this one */
         if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
@@ -887,19 +890,19 @@
           {
             cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
             cmaprec.encoding    = FT_ENCODING_ADOBE_STANDARD;
-            clazz               = &cff_cmap_encoding_class_rec;
+            clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
           }
           else if ( encoding->offset == 1 )
           {
             cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
             cmaprec.encoding    = FT_ENCODING_ADOBE_EXPERT;
-            clazz               = &cff_cmap_encoding_class_rec;
+            clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
           }
           else
           {
             cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
             cmaprec.encoding    = FT_ENCODING_ADOBE_CUSTOM;
-            clazz               = &cff_cmap_encoding_class_rec;
+            clazz               = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
           }
 
           FT_CMap_New( clazz, NULL, &cmaprec, NULL );
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index 290595f..01266a1 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -22,6 +22,7 @@
 #include FT_INTERNAL_DEBUG_H
 
 #include "cfferrs.h"
+#include "cffpic.h"
 
 
   /*************************************************************************/
@@ -34,47 +35,20 @@
 #define FT_COMPONENT  trace_cffparse
 
 
-  enum
-  {
-    cff_kind_none = 0,
-    cff_kind_num,
-    cff_kind_fixed,
-    cff_kind_fixed_thousand,
-    cff_kind_string,
-    cff_kind_bool,
-    cff_kind_delta,
-    cff_kind_callback,
-
-    cff_kind_max  /* do not remove */
-  };
-
-
-  /* now generate handlers for the most simple fields */
-  typedef FT_Error  (*CFF_Field_Reader)( CFF_Parser  parser );
-
-  typedef struct  CFF_Field_Handler_
-  {
-    int               kind;
-    int               code;
-    FT_UInt           offset;
-    FT_Byte           size;
-    CFF_Field_Reader  reader;
-    FT_UInt           array_max;
-    FT_UInt           count_offset;
-
-  } CFF_Field_Handler;
 
 
   FT_LOCAL_DEF( void )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
-                   void*       object )
+                   void*       object,
+                   FT_Library  library)
   {
     FT_MEM_ZERO( parser, sizeof ( *parser ) );
 
     parser->top         = parser->stack;
     parser->object_code = code;
     parser->object      = object;
+    parser->library     = library;
   }
 
 
@@ -156,8 +130,8 @@
   static FT_Fixed
   cff_parse_real( FT_Byte*  start,
                   FT_Byte*  limit,
-                  FT_Int    power_ten,
-                  FT_Int*   scaling )
+                  FT_Long   power_ten,
+                  FT_Long*  scaling )
   {
     FT_Byte*  p = start;
     FT_UInt   nib;
@@ -165,7 +139,7 @@
 
     FT_Long   result, number, rest, exponent;
     FT_Int    sign = 0, exponent_sign = 0;
-    FT_Int    exponent_add, integer_length, fraction_length;
+    FT_Long   exponent_add, integer_length, fraction_length;
 
 
     if ( scaling )
@@ -181,6 +155,8 @@
     integer_length  = 0;
     fraction_length = 0;
 
+    FT_UNUSED( rest );
+
     /* First of all, read the integer part. */
     phase = 4;
 
@@ -310,7 +286,7 @@
         {
           if ( exponent > 0 )
           {
-            FT_Int  new_fraction_length, shift;
+            FT_Long  new_fraction_length, shift;
 
 
             /* Make `scaling' as small as possible. */
@@ -410,7 +386,7 @@
   /* but return `10^scaling' times the number read in      */
   static FT_Fixed
   cff_parse_fixed_scaled( FT_Byte**  d,
-                          FT_Int     scaling )
+                          FT_Long    scaling )
   {
     return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
                      : ( cff_parse_integer( d[0], d[1] ) *
@@ -423,7 +399,7 @@
   /* the scaling factor (as a power of 10)                     */
   static FT_Fixed
   cff_parse_fixed_dynamic( FT_Byte**  d,
-                           FT_Int*    scaling )
+                           FT_Long*   scaling )
   {
     FT_ASSERT( scaling );
 
@@ -476,7 +452,7 @@
 
     if ( parser->top >= parser->stack + 6 )
     {
-      FT_Int  scaling;
+      FT_Long  scaling;
 
 
       error = CFF_Err_Ok;
@@ -578,7 +554,12 @@
     {
       dict->cid_registry   = (FT_UInt)cff_parse_num ( data++ );
       dict->cid_ordering   = (FT_UInt)cff_parse_num ( data++ );
-      dict->cid_supplement = (FT_ULong)cff_parse_num( data );
+      if ( **data == 30 )
+        FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
+      dict->cid_supplement = cff_parse_num( data );
+      if ( dict->cid_supplement < 0 )
+        FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
+                   dict->cid_supplement ));
       error = CFF_Err_Ok;
     }
 
@@ -599,6 +580,11 @@
 #define CFF_FIELD_DELTA( code, name, max ) \
           CFF_FIELD( code, name, cff_kind_delta )
 
+#define CFFCODE_TOPDICT  0x1000
+#define CFFCODE_PRIVATE  0x2000
+
+#ifndef FT_CONFIG_OPTION_PIC
+
 #define CFF_FIELD_CALLBACK( code, name ) \
           {                              \
             cff_kind_callback,           \
@@ -630,9 +616,6 @@
           FT_FIELD_OFFSET( num_ ## name )  \
         },
 
-#define CFFCODE_TOPDICT  0x1000
-#define CFFCODE_PRIVATE  0x2000
-
   static const CFF_Field_Handler  cff_field_handlers[] =
   {
 
@@ -642,13 +625,99 @@
   };
 
 
+#else /* FT_CONFIG_OPTION_PIC */
+
+  void FT_Destroy_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler* clazz)
+  {
+    FT_Memory memory = library->memory;
+    if ( clazz )
+      FT_FREE( clazz );
+  }
+
+  FT_Error FT_Create_Class_cff_field_handlers(FT_Library library, CFF_Field_Handler** output_class)
+  {
+    CFF_Field_Handler*  clazz;
+    FT_Error          error;
+    FT_Memory memory = library->memory;
+    int i=0;
+
+#undef CFF_FIELD
+#undef CFF_FIELD_DELTA
+#undef CFF_FIELD_CALLBACK
+#define CFF_FIELD_CALLBACK( code, name ) i++;
+#define CFF_FIELD( code, name, kind ) i++;
+#define CFF_FIELD_DELTA( code, name, max ) i++;
+
+#include "cfftoken.h"
+    i++;/*{ 0, 0, 0, 0, 0, 0, 0 }*/
+
+    if ( FT_ALLOC( clazz, sizeof(CFF_Field_Handler)*i ) )
+      return error;
+
+    i=0;
+#undef CFF_FIELD
+#undef CFF_FIELD_DELTA
+#undef CFF_FIELD_CALLBACK
+
+#define CFF_FIELD_CALLBACK( code_, name_ )                                   \
+    clazz[i].kind = cff_kind_callback;                                       \
+    clazz[i].code = code_ | CFFCODE;                                         \
+    clazz[i].offset = 0;                                                     \
+    clazz[i].size = 0;                                                       \
+    clazz[i].reader = cff_parse_ ## name_;                                   \
+    clazz[i].array_max = 0;                                                  \
+    clazz[i].count_offset = 0;                                               \
+    i++;
+
+#undef  CFF_FIELD
+#define CFF_FIELD( code_, name_, kind_ )                                     \
+    clazz[i].kind = kind_;                                                   \
+    clazz[i].code = code_ | CFFCODE;                                         \
+    clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \
+    clazz[i].size = FT_FIELD_SIZE( name_ );                                  \
+    clazz[i].reader = 0;                                                     \
+    clazz[i].array_max = 0;                                                  \
+    clazz[i].count_offset = 0;                                               \
+    i++;                                                                     \
+
+#undef  CFF_FIELD_DELTA
+#define CFF_FIELD_DELTA( code_, name_, max_ )                                \
+    clazz[i].kind = cff_kind_delta;                                          \
+    clazz[i].code = code_ | CFFCODE;                                         \
+    clazz[i].offset = FT_FIELD_OFFSET( name_ );                              \
+    clazz[i].size = FT_FIELD_SIZE_DELTA( name_ );                            \
+    clazz[i].reader = 0;                                                     \
+    clazz[i].array_max = max_;                                               \
+    clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ );                \
+    i++;
+
+#include "cfftoken.h"
+
+    clazz[i].kind = 0;
+    clazz[i].code = 0;
+    clazz[i].offset = 0;
+    clazz[i].size = 0;
+    clazz[i].reader = 0;
+    clazz[i].array_max = 0;
+    clazz[i].count_offset = 0;
+
+    *output_class = clazz;
+    return FT_Err_Ok;
+  }
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
   FT_LOCAL_DEF( FT_Error )
   cff_parser_run( CFF_Parser  parser,
                   FT_Byte*    start,
                   FT_Byte*    limit )
   {
-    FT_Byte*  p     = start;
-    FT_Error  error = CFF_Err_Ok;
+    FT_Byte*    p       = start;
+    FT_Error    error   = CFF_Err_Ok;
+    FT_Library  library = parser->library;
+    FT_UNUSED(library);
 
 
     parser->top    = parser->stack;
@@ -676,8 +745,10 @@
           p++;
           for (;;)
           {
+            /* An unterminated floating point number at the */
+            /* end of a dictionary is invalid but harmless. */
             if ( p >= limit )
-              goto Syntax_Error;
+              goto Exit;
             v = p[0] >> 4;
             if ( v == 15 )
               break;
@@ -718,7 +789,7 @@
         }
         code = code | parser->object_code;
 
-        for ( field = cff_field_handlers; field->kind; field++ )
+        for ( field = FT_CFF_FIELD_HANDLERS_GET; field->kind; field++ )
         {
           if ( field->code == (FT_Int)code )
           {
diff --git a/src/cff/cffparse.h b/src/cff/cffparse.h
index 8f3fa58..7e2c00a 100644
--- a/src/cff/cffparse.h
+++ b/src/cff/cffparse.h
@@ -36,6 +36,7 @@
 
   typedef struct  CFF_ParserRec_
   {
+    FT_Library library;
     FT_Byte*   start;
     FT_Byte*   limit;
     FT_Byte*   cursor;
@@ -52,7 +53,8 @@
   FT_LOCAL( void )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
-                   void*       object );
+                   void*       object,
+                   FT_Library  library);
 
   FT_LOCAL( FT_Error )
   cff_parser_run( CFF_Parser  parser,
@@ -60,6 +62,37 @@
                   FT_Byte*    limit );
 
 
+  enum
+  {
+    cff_kind_none = 0,
+    cff_kind_num,
+    cff_kind_fixed,
+    cff_kind_fixed_thousand,
+    cff_kind_string,
+    cff_kind_bool,
+    cff_kind_delta,
+    cff_kind_callback,
+
+    cff_kind_max  /* do not remove */
+  };
+
+
+  /* now generate handlers for the most simple fields */
+  typedef FT_Error  (*CFF_Field_Reader)( CFF_Parser  parser );
+
+  typedef struct  CFF_Field_Handler_
+  {
+    int               kind;
+    int               code;
+    FT_UInt           offset;
+    FT_Byte           size;
+    CFF_Field_Reader  reader;
+    FT_UInt           array_max;
+    FT_UInt           count_offset;
+
+  } CFF_Field_Handler;
+
+
 FT_END_HEADER
 
 
diff --git a/src/cff/cffpic.c b/src/cff/cffpic.c
new file mode 100644
index 0000000..568956d
--- /dev/null
+++ b/src/cff/cffpic.c
@@ -0,0 +1,99 @@
+/***************************************************************************/
+/*                                                                         */
+/*  cffpic.c                                                               */
+/*                                                                         */
+/*    The FreeType position independent code services for cff module.      */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include "cffpic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  /* forward declaration of PIC init functions from cffdrivr.c */
+  FT_Error FT_Create_Class_cff_services( FT_Library, FT_ServiceDescRec**);
+  void FT_Destroy_Class_cff_services( FT_Library, FT_ServiceDescRec*);
+  void FT_Init_Class_cff_service_ps_info( FT_Library, FT_Service_PsInfoRec*);
+  void FT_Init_Class_cff_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*);
+  void FT_Init_Class_cff_service_ps_name( FT_Library, FT_Service_PsFontNameRec*);
+  void FT_Init_Class_cff_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*);
+  void FT_Init_Class_cff_service_cid_info( FT_Library, FT_Service_CIDRec*);
+
+  /* forward declaration of PIC init functions from cffparse.c */
+  FT_Error FT_Create_Class_cff_field_handlers( FT_Library, CFF_Field_Handler**);
+  void FT_Destroy_Class_cff_field_handlers( FT_Library, CFF_Field_Handler*);
+
+  /* forward declaration of PIC init functions from cffcmap.c */
+  void FT_Init_Class_cff_cmap_encoding_class_rec( FT_Library, FT_CMap_ClassRec*);
+  void FT_Init_Class_cff_cmap_unicode_class_rec( FT_Library, FT_CMap_ClassRec*);
+
+  void
+  cff_driver_class_pic_free(  FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Memory memory = library->memory;
+    if ( pic_container->cff )
+    {
+      CffModulePIC* container = (CffModulePIC*)pic_container->cff;
+      if(container->cff_services)
+        FT_Destroy_Class_cff_services(library, container->cff_services);
+      container->cff_services = NULL;
+      if(container->cff_field_handlers)
+        FT_Destroy_Class_cff_field_handlers(library, container->cff_field_handlers);
+      container->cff_field_handlers = NULL;
+      FT_FREE( container );
+      pic_container->cff = NULL;
+    }
+  }
+
+  FT_Error
+  cff_driver_class_pic_init(  FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Error        error = FT_Err_Ok;
+    CffModulePIC* container;
+    FT_Memory memory = library->memory;
+
+    /* allocate pointer, clear and set global container pointer */
+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+      return error;
+    FT_MEM_SET( container, 0, sizeof(*container) );
+    pic_container->cff = container;
+
+    /* initialize pointer table - this is how the module usually expects this data */
+    error = FT_Create_Class_cff_services(library, &container->cff_services);
+    if(error) 
+      goto Exit;
+    error = FT_Create_Class_cff_field_handlers(library, &container->cff_field_handlers);
+    if(error) 
+      goto Exit;
+    FT_Init_Class_cff_service_ps_info(library, &container->cff_service_ps_info);
+    FT_Init_Class_cff_service_glyph_dict(library, &container->cff_service_glyph_dict);
+    FT_Init_Class_cff_service_ps_name(library, &container->cff_service_ps_name);
+    FT_Init_Class_cff_service_get_cmap_info(library, &container->cff_service_get_cmap_info);
+    FT_Init_Class_cff_service_cid_info(library, &container->cff_service_cid_info);
+    FT_Init_Class_cff_cmap_encoding_class_rec(library, &container->cff_cmap_encoding_class_rec);
+    FT_Init_Class_cff_cmap_unicode_class_rec(library, &container->cff_cmap_unicode_class_rec);
+Exit:
+    if(error)
+      cff_driver_class_pic_free(library);
+    return error;
+  }
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
+/* END */
diff --git a/src/cff/cffpic.h b/src/cff/cffpic.h
new file mode 100644
index 0000000..e29d068
--- /dev/null
+++ b/src/cff/cffpic.h
@@ -0,0 +1,80 @@
+/***************************************************************************/
+/*                                                                         */
+/*  cffpic.h                                                               */
+/*                                                                         */
+/*    The FreeType position independent code services for cff module.      */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __CFFPIC_H__
+#define __CFFPIC_H__
+
+  
+FT_BEGIN_HEADER
+
+#include FT_INTERNAL_PIC_H
+
+#ifndef FT_CONFIG_OPTION_PIC
+#define FT_CFF_SERVICE_PS_INFO_GET         cff_service_ps_info
+#define FT_CFF_SERVICE_GLYPH_DICT_GET      cff_service_glyph_dict
+#define FT_CFF_SERVICE_PS_NAME_GET         cff_service_ps_name
+#define FT_CFF_SERVICE_GET_CMAP_INFO_GET   cff_service_get_cmap_info
+#define FT_CFF_SERVICE_CID_INFO_GET        cff_service_cid_info
+#define FT_CFF_SERVICES_GET                cff_services
+#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec
+#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET  cff_cmap_unicode_class_rec
+#define FT_CFF_FIELD_HANDLERS_GET          cff_field_handlers
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#include FT_SERVICE_GLYPH_DICT_H
+#include "cffparse.h"
+#include FT_SERVICE_POSTSCRIPT_INFO_H
+#include FT_SERVICE_POSTSCRIPT_NAME_H
+#include FT_SERVICE_TT_CMAP_H
+#include FT_SERVICE_CID_H
+
+  typedef struct CffModulePIC_
+  {
+    FT_ServiceDescRec* cff_services;
+    CFF_Field_Handler* cff_field_handlers;
+    FT_Service_PsInfoRec cff_service_ps_info;
+    FT_Service_GlyphDictRec cff_service_glyph_dict;
+    FT_Service_PsFontNameRec cff_service_ps_name;
+    FT_Service_TTCMapsRec  cff_service_get_cmap_info;
+    FT_Service_CIDRec  cff_service_cid_info;
+    FT_CMap_ClassRec cff_cmap_encoding_class_rec;
+    FT_CMap_ClassRec cff_cmap_unicode_class_rec;
+  } CffModulePIC;
+
+#define GET_PIC(lib)                       ((CffModulePIC*)((lib)->pic_container.cff))
+#define FT_CFF_SERVICE_PS_INFO_GET         (GET_PIC(library)->cff_service_ps_info)
+#define FT_CFF_SERVICE_GLYPH_DICT_GET      (GET_PIC(library)->cff_service_glyph_dict)
+#define FT_CFF_SERVICE_PS_NAME_GET         (GET_PIC(library)->cff_service_ps_name)
+#define FT_CFF_SERVICE_GET_CMAP_INFO_GET   (GET_PIC(library)->cff_service_get_cmap_info)
+#define FT_CFF_SERVICE_CID_INFO_GET        (GET_PIC(library)->cff_service_cid_info)
+#define FT_CFF_SERVICES_GET                (GET_PIC(library)->cff_services)
+#define FT_CFF_CMAP_ENCODING_CLASS_REC_GET (GET_PIC(library)->cff_cmap_encoding_class_rec)
+#define FT_CFF_CMAP_UNICODE_CLASS_REC_GET  (GET_PIC(library)->cff_cmap_unicode_class_rec)
+#define FT_CFF_FIELD_HANDLERS_GET          (GET_PIC(library)->cff_field_handlers)
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __CFFPIC_H__ */
+
+
+/* END */
diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h
index 546ea3b..df92e9a 100644
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -130,7 +130,7 @@
     /* these should only be used for the top-level font dictionary */
     FT_UInt    cid_registry;
     FT_UInt    cid_ordering;
-    FT_ULong   cid_supplement;
+    FT_Long    cid_supplement;
 
     FT_Long    cid_font_version;
     FT_Long    cid_font_revision;
diff --git a/src/psaux/afmparse.c b/src/psaux/afmparse.c
index 63a786e..91a17e2 100644
--- a/src/psaux/afmparse.c
+++ b/src/psaux/afmparse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    AFM parser (body).                                                   */
 /*                                                                         */
-/*  Copyright 2006, 2007, 2008 by                                          */
+/*  Copyright 2006, 2007, 2008, 2009 by                                    */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -18,7 +18,6 @@
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_DEBUG_H
 
 #include "afmparse.h"
 #include "psconv.h"
@@ -367,11 +366,11 @@
   FT_LOCAL_DEF( FT_Int )
   afm_parser_read_vals( AFM_Parser  parser,
                         AFM_Value   vals,
-                        FT_Int      n )
+                        FT_UInt     n )
   {
     AFM_Stream  stream = parser->stream;
     char*       str;
-    FT_Int      i;
+    FT_UInt     i;
 
 
     if ( n > AFM_MAX_ARGUMENTS )
@@ -379,7 +378,7 @@
 
     for ( i = 0; i < n; i++ )
     {
-      FT_UInt    len;
+      FT_Offset  len;
       AFM_Value  val = vals + i;
 
 
@@ -441,7 +440,7 @@
   FT_LOCAL_DEF( char* )
   afm_parser_next_key( AFM_Parser  parser,
                        FT_Bool     line,
-                       FT_UInt*    len )
+                       FT_Offset*  len )
   {
     AFM_Stream  stream = parser->stream;
     char*       key    = 0;  /* make stupid compiler happy */
@@ -489,7 +488,7 @@
     }
 
     if ( len )
-      *len = ( key ) ? AFM_STREAM_KEY_LEN( stream, key )
+      *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key )
                      : 0;
 
     return key;
@@ -498,7 +497,7 @@
 
   static AFM_Token
   afm_tokenize( const char*  key,
-                FT_UInt      len )
+                FT_Offset    len )
   {
     int  n;
 
@@ -586,7 +585,7 @@
     AFM_FontInfo   fi = parser->FontInfo;
     AFM_TrackKern  tk;
     char*          key;
-    FT_UInt        len;
+    FT_Offset      len;
     int            n = -1;
 
 
@@ -687,7 +686,7 @@
     AFM_FontInfo  fi = parser->FontInfo;
     AFM_KernPair  kp;
     char*         key;
-    FT_UInt       len;
+    FT_Offset     len;
     int           n = -1;
 
 
@@ -775,9 +774,9 @@
   static FT_Error
   afm_parse_kern_data( AFM_Parser  parser )
   {
-    FT_Error  error;
-    char*     key;
-    FT_UInt   len;
+    FT_Error   error;
+    char*      key;
+    FT_Offset  len;
 
 
     while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
@@ -819,8 +818,8 @@
                            FT_UInt     n,
                            AFM_Token   end_section )
   {
-    char*    key;
-    FT_UInt  len;
+    char*      key;
+    FT_Offset  len;
 
 
     while ( n-- > 0 )
@@ -851,7 +850,7 @@
     AFM_FontInfo  fi     = parser->FontInfo;
     FT_Error      error  = PSaux_Err_Syntax_Error;
     char*         key;
-    FT_UInt       len;
+    FT_Offset     len;
     FT_Int        metrics_sets = 0;
 
 
diff --git a/src/psaux/afmparse.h b/src/psaux/afmparse.h
index c2fce75..de2a530 100644
--- a/src/psaux/afmparse.h
+++ b/src/psaux/afmparse.h
@@ -71,13 +71,13 @@
   FT_LOCAL( FT_Int )
   afm_parser_read_vals( AFM_Parser  parser,
                         AFM_Value   vals,
-                        FT_Int      n );
+                        FT_UInt     n );
 
   /* read the next key from the next line or column */
   FT_LOCAL( char* )
   afm_parser_next_key( AFM_Parser  parser,
                        FT_Bool     line,
-                       FT_UInt*    len );
+                       FT_Offset*  len );
 
 FT_END_HEADER
 
diff --git a/src/psaux/psauxmod.h b/src/psaux/psauxmod.h
index 92ac056..35e042d 100644
--- a/src/psaux/psauxmod.h
+++ b/src/psaux/psauxmod.h
@@ -26,6 +26,10 @@
 
 FT_BEGIN_HEADER
 
+#ifdef FT_CONFIG_OPTION_PIC
+#error "this module does not support PIC yet"
+#endif 
+
 
   FT_EXPORT_VAR( const FT_Module_Class )  psaux_driver_class;
 
diff --git a/src/psaux/psconv.c b/src/psaux/psconv.c
index d824b59..1531d8f 100644
--- a/src/psaux/psconv.c
+++ b/src/psaux/psconv.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Some convenience conversions (body).                                 */
 /*                                                                         */
-/*  Copyright 2006, 2008 by                                                */
+/*  Copyright 2006, 2008, 2009 by                                          */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -18,10 +18,8 @@
 
 #include <ft2build.h>
 #include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_DEBUG_H
 
 #include "psconv.h"
-#include "psobjs.h"
 #include "psauxerr.h"
 
 
@@ -241,7 +239,7 @@
   PS_Conv_StringDecode( FT_Byte**  cursor,
                         FT_Byte*   limit,
                         FT_Byte*   buffer,
-                        FT_UInt    n )
+                        FT_Offset  n )
   {
     FT_Byte*  p;
     FT_UInt   r = 0;
@@ -336,7 +334,7 @@
   PS_Conv_ASCIIHexDecode( FT_Byte**  cursor,
                           FT_Byte*   limit,
                           FT_Byte*   buffer,
-                          FT_UInt    n )
+                          FT_Offset  n )
   {
     FT_Byte*  p;
     FT_UInt   r   = 0;
@@ -425,7 +423,7 @@
   PS_Conv_EexecDecode( FT_Byte**   cursor,
                        FT_Byte*    limit,
                        FT_Byte*    buffer,
-                       FT_UInt     n,
+                       FT_Offset   n,
                        FT_UShort*  seed )
   {
     FT_Byte*  p;
diff --git a/src/psaux/psconv.h b/src/psaux/psconv.h
index e511241..84854ba 100644
--- a/src/psaux/psconv.h
+++ b/src/psaux/psconv.h
@@ -46,20 +46,20 @@
   PS_Conv_StringDecode( FT_Byte**  cursor,
                         FT_Byte*   limit,
                         FT_Byte*   buffer,
-                        FT_UInt    n );
+                        FT_Offset  n );
 #endif
 
   FT_LOCAL( FT_UInt )
   PS_Conv_ASCIIHexDecode( FT_Byte**  cursor,
                           FT_Byte*   limit,
                           FT_Byte*   buffer,
-                          FT_UInt    n );
+                          FT_Offset  n );
 
   FT_LOCAL( FT_UInt )
   PS_Conv_EexecDecode( FT_Byte**   cursor,
                        FT_Byte*    limit,
                        FT_Byte*    buffer,
-                       FT_UInt     n,
+                       FT_Offset   n,
                        FT_UShort*  seed );
 
 
diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
index 52e30a4..fe8398a 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -19,6 +19,7 @@
 #include <ft2build.h>
 #include FT_INTERNAL_POSTSCRIPT_AUX_H
 #include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_CALC_H
 
 #include "psobjs.h"
 #include "psconv.h"
@@ -564,8 +565,8 @@
       cur++;
       if ( cur >= limit || *cur != '>' )             /* >> */
       {
-        FT_ERROR(( "ps_parser_skip_PS_token: "
-                   "unexpected closing delimiter `>'\n" ));
+        FT_ERROR(( "ps_parser_skip_PS_token:"
+                   " unexpected closing delimiter `>'\n" ));
         error = PSaux_Err_Invalid_File_Format;
         goto Exit;
       }
@@ -590,9 +591,10 @@
   Exit:
     if ( cur == parser->cursor )
     {
-      FT_ERROR(( "ps_parser_skip_PS_token: "
-                 "current token is `%c', which is self-delimiting "
-                 "but invalid at this point\n",
+      FT_ERROR(( "ps_parser_skip_PS_token:"
+                 " current token is `%c' which is self-delimiting\n"
+                 "                        "
+                 " but invalid at this point\n",
                  *cur ));
 
       error = PSaux_Err_Invalid_File_Format;
@@ -1153,8 +1155,10 @@
           }
           else
           {
-            FT_ERROR(( "ps_parser_load_field: expected a name or string "
-                       "but found token of type %d instead\n",
+            FT_ERROR(( "ps_parser_load_field:"
+                       " expected a name or string\n"
+                       "                     "
+                       " but found token of type %d instead\n",
                        token.type ));
             error = PSaux_Err_Invalid_File_Format;
             goto Exit;
@@ -1191,8 +1195,8 @@
 
           if ( result < 0 )
           {
-            FT_ERROR(( "ps_parser_load_field: "
-                       "expected four integers in bounding box\n" ));
+            FT_ERROR(( "ps_parser_load_field:"
+                       " expected four integers in bounding box\n" ));
             error = PSaux_Err_Invalid_File_Format;
             goto Exit;
           }
@@ -1309,7 +1313,7 @@
   FT_LOCAL_DEF( FT_Error )
   ps_parser_to_bytes( PS_Parser  parser,
                       FT_Byte*   bytes,
-                      FT_Long    max_bytes,
+                      FT_Offset  max_bytes,
                       FT_Long*   pnum_bytes,
                       FT_Bool    delimiters )
   {
@@ -1551,16 +1555,9 @@
       FT_Byte*    control = (FT_Byte*)outline->tags + outline->n_points;
 
 
-      if ( builder->shift )
-      {
-        x >>= 16;
-        y >>= 16;
-      }
-      point->x = x;
-      point->y = y;
+      point->x = FIXED_TO_INT( x );
+      point->y = FIXED_TO_INT( y );
       *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
-
-      builder->last = *point;
     }
     outline->n_points++;
   }
@@ -1668,8 +1665,8 @@
 
     if ( outline->n_contours > 0 )
     {
-      /* Don't add contours only consisting of one point, i.e., */
-      /* check whether begin point and last point are the same. */
+      /* Don't add contours only consisting of one point, i.e.,  */
+      /* check whether the first and the last point is the same. */
       if ( first == outline->n_points - 1 )
       {
         outline->n_contours--;
diff --git a/src/psaux/psobjs.h b/src/psaux/psobjs.h
index c2cbf2c..e380c60 100644
--- a/src/psaux/psobjs.h
+++ b/src/psaux/psobjs.h
@@ -111,7 +111,7 @@
   FT_LOCAL( FT_Error )
   ps_parser_to_bytes( PS_Parser  parser,
                       FT_Byte*   bytes,
-                      FT_Long    max_bytes,
+                      FT_Offset  max_bytes,
                       FT_Long*   pnum_bytes,
                       FT_Bool    delimiters );
 
diff --git a/src/psaux/t1cmap.c b/src/psaux/t1cmap.c
index 67a23db..f933e4d 100644
--- a/src/psaux/t1cmap.c
+++ b/src/psaux/t1cmap.c
@@ -95,7 +95,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   t1_cmap_std_char_next( T1_CMapStd   cmap,
                          FT_UInt32   *pchar_code )
   {
@@ -179,7 +179,7 @@
 
 
     cmap->first   = encoding->code_first;
-    cmap->count   = (FT_UInt)( encoding->code_last - cmap->first + 1 );
+    cmap->count   = (FT_UInt)( encoding->code_last - cmap->first );
     cmap->indices = encoding->char_index;
 
     FT_ASSERT( cmap->indices != NULL );
@@ -213,7 +213,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   t1_cmap_custom_char_next( T1_CMapCustom  cmap,
                             FT_UInt32     *pchar_code )
   {
@@ -312,7 +312,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   t1_cmap_unicode_char_next( PS_Unicodes  unicodes,
                              FT_UInt32   *pchar_code )
   {
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index bda2324..31554ff 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -4,7 +4,8 @@
 /*                                                                         */
 /*    PostScript Type 1 decoding routines (body).                          */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
+/*  Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009    */
+/*            2010 by                                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -17,6 +18,7 @@
 
 
 #include <ft2build.h>
+#include FT_INTERNAL_CALC_H
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
 #include FT_OUTLINE_H
@@ -144,7 +146,8 @@
       FT_String*  name = (FT_String*)decoder->glyph_names[n];
 
 
-      if ( name && name[0] == glyph_name[0]  &&
+      if ( name                               &&
+           name[0] == glyph_name[0]           &&
            ft_strcmp( name, glyph_name ) == 0 )
         return n;
     }
@@ -193,26 +196,52 @@
 #endif
     FT_Vector    left_bearing, advance;
 
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+    T1_Face      face  = (T1_Face)decoder->builder.face;
+#endif     
+
+
+    if ( decoder->seac )
+    {
+      FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));
+      return PSaux_Err_Syntax_Error;
+    }
 
     /* seac weirdness */
     adx += decoder->builder.left_bearing.x;
 
     /* `glyph_names' is set to 0 for CID fonts which do not */
     /* include an encoding.  How can we deal with these?    */
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+    if ( decoder->glyph_names == 0                   &&
+         !face->root.internal->incremental_interface )
+#else
     if ( decoder->glyph_names == 0 )
+#endif /* FT_CONFIG_OPTION_INCREMENTAL */
     {
-      FT_ERROR(( "t1operator_seac:" ));
-      FT_ERROR(( " glyph names table not available in this font!\n" ));
+      FT_ERROR(( "t1operator_seac:"
+                 " glyph names table not available in this font\n" ));
       return PSaux_Err_Syntax_Error;
     }
 
-    bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
-    achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+    if ( face->root.internal->incremental_interface )
+    {
+      /* the caller must handle the font encoding also */
+      bchar_index = bchar;
+      achar_index = achar;
+    }
+    else
+#endif
+    {
+      bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
+      achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
+    }
 
     if ( bchar_index < 0 || achar_index < 0 )
     {
-      FT_ERROR(( "t1operator_seac:" ));
-      FT_ERROR(( " invalid seac character code arguments\n" ));
+      FT_ERROR(( "t1operator_seac:"
+                 " invalid seac character code arguments\n" ));
       return PSaux_Err_Syntax_Error;
     }
 
@@ -243,8 +272,8 @@
       /* subglyph 1 = accent character */
       subg->index = achar_index;
       subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
-      subg->arg1  = (FT_Int)( adx - asb );
-      subg->arg2  = (FT_Int)ady;
+      subg->arg1  = (FT_Int)FIXED_TO_INT( adx - asb );
+      subg->arg2  = (FT_Int)FIXED_TO_INT( ady );
 
       /* set up remaining glyph fields */
       glyph->num_subglyphs = 2;
@@ -260,7 +289,10 @@
 
     FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
 
+    /* the seac operator must not be nested */
+    decoder->seac = TRUE;
     error = t1_decoder_parse_glyph( decoder, bchar_index );
+    decoder->seac = FALSE;
     if ( error )
       goto Exit;
 
@@ -278,7 +310,11 @@
 
     /* Now load `achar' on top of */
     /* the base outline           */
+
+    /* the seac operator must not be nested */
+    decoder->seac = TRUE;
     error = t1_decoder_parse_glyph( decoder, achar_index );
+    decoder->seac = FALSE;
     if ( error )
       goto Exit;
 
@@ -327,9 +363,15 @@
     FT_Pos           x, y, orig_x, orig_y;
     FT_Int           known_othersubr_result_cnt   = 0;
     FT_Int           unknown_othersubr_result_cnt = 0;
+    FT_Bool          large_int;
+    FT_Fixed         seed;
 
     T1_Hints_Funcs   hinter;
 
+#ifdef FT_DEBUG_LEVEL_TRACE
+    FT_Bool          bol = TRUE;
+#endif
+
 
     /* we don't want to touch the source code -- use macro trick */
 #define start_point    t1_builder_start_point
@@ -339,6 +381,16 @@
 #define add_contour    t1_builder_add_contour
 #define close_contour  t1_builder_close_contour
 
+
+    /* compute random seed from stack address of parameter */
+    seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed              ^
+                         (FT_PtrDist)(char*)&decoder           ^
+                         (FT_PtrDist)(char*)&charstring_base ) &
+                         FT_ULONG_MAX ) ;
+    seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
+    if ( seed == 0 )
+      seed = 0x7384;
+
     /* First of all, initialize the decoder */
     decoder->top  = decoder->stack;
     decoder->zone = decoder->zones;
@@ -351,14 +403,15 @@
     /* a font that reads BuildCharArray without setting */
     /* its values first is buggy, but ...               */
     FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
-               ( decoder->buildchar == NULL ) );
+               ( decoder->buildchar == NULL )  );
 
     if ( decoder->len_buildchar > 0 )
       ft_memset( &decoder->buildchar[0],
                  0,
                  sizeof( decoder->buildchar[0] ) * decoder->len_buildchar );
 
-    FT_TRACE4(( "\nStart charstring\n" ));
+    FT_TRACE4(( "\n"
+                "Start charstring\n" ));
 
     zone->base           = charstring_base;
     limit = zone->limit  = charstring_base + charstring_len;
@@ -373,18 +426,26 @@
     if ( hinter )
       hinter->open( hinter->hints );
 
+    large_int = FALSE;
+
     /* now, execute loop */
     while ( ip < limit )
     {
       FT_Long*     top   = decoder->top;
       T1_Operator  op    = op_none;
-      FT_Long      value = 0;
+      FT_Int32     value = 0;
 
 
       FT_ASSERT( known_othersubr_result_cnt == 0   ||
                  unknown_othersubr_result_cnt == 0 );
 
-      FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+      if ( bol )
+      {
+        FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
+        bol = FALSE;
+      }
+#endif
 
       /*********************************************************************/
       /*                                                                   */
@@ -455,8 +516,8 @@
       case 12:
         if ( ip > limit )
         {
-          FT_ERROR(( "t1_decoder_parse_charstrings: "
-                     "invalid escape (12+EOF)\n" ));
+          FT_ERROR(( "t1_decoder_parse_charstrings:"
+                     " invalid escape (12+EOF)\n" ));
           goto Syntax_Error;
         }
 
@@ -491,8 +552,8 @@
           break;
 
         default:
-          FT_ERROR(( "t1_decoder_parse_charstrings: "
-                     "invalid escape (12+%d)\n",
+          FT_ERROR(( "t1_decoder_parse_charstrings:"
+                     " invalid escape (12+%d)\n",
                      ip[-1] ));
           goto Syntax_Error;
         }
@@ -501,42 +562,69 @@
       case 255:    /* four bytes integer */
         if ( ip + 4 > limit )
         {
-          FT_ERROR(( "t1_decoder_parse_charstrings: "
-                     "unexpected EOF in integer\n" ));
+          FT_ERROR(( "t1_decoder_parse_charstrings:"
+                     " unexpected EOF in integer\n" ));
           goto Syntax_Error;
         }
 
-        value = (FT_Int32)( ((FT_Long)ip[0] << 24) |
-                            ((FT_Long)ip[1] << 16) |
-                            ((FT_Long)ip[2] << 8 ) |
-                                      ip[3] );
+        value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) |
+                            ( (FT_Long)ip[1] << 16 ) |
+                            ( (FT_Long)ip[2] << 8  ) |
+                                       ip[3]         );
         ip += 4;
+
+        /* According to the specification, values > 32000 or < -32000 must */
+        /* be followed by a `div' operator to make the result be in the    */
+        /* range [-32000;32000].  We expect that the second argument of    */
+        /* `div' is not a large number.  Additionally, we don't handle     */
+        /* stuff like `<large1> <large2> <num> div <num> div' or           */
+        /* <large1> <large2> <num> div div'.  This is probably not allowed */
+        /* anyway.                                                         */
+        if ( value > 32000 || value < -32000 )
+        {
+          if ( large_int )
+          {
+            FT_ERROR(( "t1_decoder_parse_charstrings:"
+                       " no `div' after large integer\n" ));
+          }
+          else
+            large_int = TRUE;
+        }
+        else
+        {
+          if ( !large_int )
+            value <<= 16;
+        }
+
         break;
 
       default:
         if ( ip[-1] >= 32 )
         {
           if ( ip[-1] < 247 )
-            value = (FT_Long)ip[-1] - 139;
+            value = (FT_Int32)ip[-1] - 139;
           else
           {
             if ( ++ip > limit )
             {
-              FT_ERROR(( "t1_decoder_parse_charstrings: " ));
-              FT_ERROR(( "unexpected EOF in integer\n" ));
+              FT_ERROR(( "t1_decoder_parse_charstrings:"
+                         " unexpected EOF in integer\n" ));
               goto Syntax_Error;
             }
 
             if ( ip[-2] < 251 )
-              value =  ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
+              value =  ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
             else
-              value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
+              value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
           }
+
+          if ( !large_int )
+            value <<= 16;
         }
         else
         {
-          FT_ERROR(( "t1_decoder_parse_charstrings: "
-                     "invalid byte (%d)\n", ip[-1] ));
+          FT_ERROR(( "t1_decoder_parse_charstrings:"
+                     " invalid byte (%d)\n", ip[-1] ));
           goto Syntax_Error;
         }
       }
@@ -558,6 +646,14 @@
         }
       }
 
+      if ( large_int && !( op == op_none || op == op_div ) )
+      {
+        FT_ERROR(( "t1_decoder_parse_charstrings:"
+                   " no `div' after large integer\n" ));
+
+        large_int = FALSE;
+      }
+
       /*********************************************************************/
       /*                                                                   */
       /*  Push value on stack, or process operator                         */
@@ -567,11 +663,16 @@
       {
         if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
         {
-          FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow!\n" ));
+          FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));
           goto Syntax_Error;
         }
 
-        FT_TRACE4(( " %ld", value ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+        if ( large_int )
+          FT_TRACE4(( " %ld", value ));
+        else
+          FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) ));
+#endif
 
         *top++       = value;
         decoder->top = top;
@@ -582,15 +683,18 @@
         FT_Int  arg_cnt;
 
 
-        FT_TRACE4(( " callothersubr" ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+        FT_TRACE4(( " callothersubr\n" ));
+        bol = TRUE;
+#endif
 
         if ( top - decoder->stack < 2 )
           goto Stack_Underflow;
 
         top -= 2;
 
-        subr_no = (FT_Int)top[1];
-        arg_cnt = (FT_Int)top[0];
+        subr_no = (FT_Int)( top[1] >> 16 );
+        arg_cnt = (FT_Int)( top[0] >> 16 );
 
         /***********************************************************/
         /*                                                         */
@@ -667,8 +771,8 @@
           if ( decoder->flex_state       == 0 ||
                decoder->num_flex_vectors != 7 )
           {
-            FT_ERROR(( "t1_decoder_parse_charstrings: "
-                       "unexpected flex end\n" ));
+            FT_ERROR(( "t1_decoder_parse_charstrings:"
+                       " unexpected flex end\n" ));
             goto Syntax_Error;
           }
 
@@ -684,7 +788,6 @@
 
           if ( hinter )
             hinter->reset( hinter->hints, builder->current->n_points );
-
           break;
 
         case 12:
@@ -707,16 +810,16 @@
 
             if ( !blend )
             {
-              FT_ERROR(( "t1_decoder_parse_charstrings: " ));
-              FT_ERROR(( "unexpected multiple masters operator!\n" ));
+              FT_ERROR(( "t1_decoder_parse_charstrings:"
+                         " unexpected multiple masters operator\n" ));
               goto Syntax_Error;
             }
 
             num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );
             if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
             {
-              FT_ERROR(( "t1_decoder_parse_charstrings: " ));
-              FT_ERROR(( "incorrect number of mm arguments\n" ));
+              FT_ERROR(( "t1_decoder_parse_charstrings:"
+                         " incorrect number of multiple masters arguments\n" ));
               goto Syntax_Error;
             }
 
@@ -752,12 +855,6 @@
             break;
           }
 
-#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
-
-          /* We cannot yet enable these since currently  */
-          /* our T1 stack stores integers which lack the */
-          /* precision to express the values             */
-
         case 19:
           /* <idx> 1 19 callothersubr                             */
           /* => replace elements starting from index cvi( <idx> ) */
@@ -770,10 +867,10 @@
             if ( arg_cnt != 1 || blend == NULL )
               goto Unexpected_OtherSubr;
 
-            idx = top[0];
+            idx = (FT_Int)( top[0] >> 16 );
 
-            if ( idx < 0                                                 ||
-                 idx + blend->num_designs > decoder->face->len_buildchar )
+            if ( idx < 0                                           ||
+                 idx + blend->num_designs > decoder->len_buildchar )
               goto Unexpected_OtherSubr;
 
             ft_memcpy( &decoder->buildchar[idx],
@@ -811,7 +908,7 @@
           if ( arg_cnt != 2 )
             goto Unexpected_OtherSubr;
 
-          top[0] *= top[1]; /* XXX (over|under)flow */
+          top[0] = FT_MulFix( top[0], top[1] );
 
           known_othersubr_result_cnt = 1;
           break;
@@ -822,24 +919,23 @@
           if ( arg_cnt != 2 || top[1] == 0 )
             goto Unexpected_OtherSubr;
 
-          top[0] /= top[1]; /* XXX (over|under)flow */
+          top[0] = FT_DivFix( top[0], top[1] );
 
           known_othersubr_result_cnt = 1;
           break;
 
-#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */
-
         case 24:
-          /* <val> <idx> 2 24 callothersubr              */
-          /* => set BuildCharArray[cvi( <idx> )] = <val> */
+          /* <val> <idx> 2 24 callothersubr               */
+          /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
           {
             FT_Int    idx;
             PS_Blend  blend = decoder->blend;
 
+
             if ( arg_cnt != 2 || blend == NULL )
               goto Unexpected_OtherSubr;
 
-            idx = top[1];
+            idx = (FT_Int)( top[1] >> 16 );
 
             if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
               goto Unexpected_OtherSubr;
@@ -849,17 +945,18 @@
           break;
 
         case 25:
-          /* <idx> 1 25 callothersubr pop       */
-          /* => push BuildCharArray[cvi( idx )] */
-          /*    onto T1 stack                   */
+          /* <idx> 1 25 callothersubr pop        */
+          /* ==> push BuildCharArray[cvi( idx )] */
+          /*     onto T1 stack                   */
           {
             FT_Int    idx;
             PS_Blend  blend = decoder->blend;
 
+
             if ( arg_cnt != 1 || blend == NULL )
               goto Unexpected_OtherSubr;
 
-            idx = top[0];
+            idx = (FT_Int)( top[0] >> 16 );
 
             if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
               goto Unexpected_OtherSubr;
@@ -875,13 +972,13 @@
           /* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
           /*                      leave mark on T1 stack                    */
           /* <val> <idx>      ==> set BuildCharArray[cvi( <idx> )] = <val>  */
-          XXX who has left his mark on the (PostScript) stack ?;
+          XXX which routine has left its mark on the (PostScript) stack?;
           break;
 #endif
 
         case 27:
           /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
-          /* ==> push <res1> onto T1 stack if <val1> <= <val2>,  */
+          /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
           /*     otherwise push <res2>                          */
           if ( arg_cnt != 4 )
             goto Unexpected_OtherSubr;
@@ -892,28 +989,40 @@
           known_othersubr_result_cnt = 1;
           break;
 
-#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
         case 28:
           /* 0 28 callothersubr pop                               */
           /* => push random value from interval [0, 1) onto stack */
           if ( arg_cnt != 0 )
             goto Unexpected_OtherSubr;
 
-          top[0] = FT_rand();
+          {
+            FT_Fixed  Rand;
+
+
+            Rand = seed;
+            if ( Rand >= 0x8000L )
+              Rand++;
+
+            top[0] = Rand;
+
+            seed = FT_MulFix( seed, 0x10000L - seed );
+            if ( seed == 0 )
+              seed += 0x2873;
+          }
+
           known_othersubr_result_cnt = 1;
           break;
-#endif
 
         default:
-          FT_ERROR(( "t1_decoder_parse_charstrings: "
-                     "unknown othersubr [%d %d], wish me luck!\n",
+          FT_ERROR(( "t1_decoder_parse_charstrings:"
+                     " unknown othersubr [%d %d], wish me luck\n",
                      arg_cnt, subr_no ));
           unknown_othersubr_result_cnt = arg_cnt;
           break;
 
         Unexpected_OtherSubr:
-          FT_ERROR(( "t1_decoder_parse_charstrings: "
-                     "invalid othersubr [%d %d]!\n", arg_cnt, subr_no ));
+          FT_ERROR(( "t1_decoder_parse_charstrings:"
+                     " invalid othersubr [%d %d]\n", arg_cnt, subr_no ));
           goto Syntax_Error;
         }
 
@@ -950,9 +1059,9 @@
 
         default:
           if ( top - decoder->stack != num_args )
-            FT_TRACE0(( "t1_decoder_parse_charstrings: "
-                        "too much operands on the stack "
-                        "(seen %d, expected %d)\n",
+            FT_TRACE0(( "t1_decoder_parse_charstrings:"
+                        " too much operands on the stack"
+                        " (seen %d, expected %d)\n",
                         top - decoder->stack, num_args ));
             break;
         }
@@ -964,28 +1073,26 @@
         switch ( op )
         {
         case op_endchar:
-          FT_TRACE4(( " endchar" ));
+          FT_TRACE4(( " endchar\n" ));
 
           close_contour( builder );
 
           /* close hints recording session */
           if ( hinter )
           {
-            if (hinter->close( hinter->hints, builder->current->n_points ))
+            if ( hinter->close( hinter->hints, builder->current->n_points ) )
               goto Syntax_Error;
 
             /* apply hints to the loaded glyph outline now */
             hinter->apply( hinter->hints,
                            builder->current,
-                           (PSH_Globals) builder->hints_globals,
+                           (PSH_Globals)builder->hints_globals,
                            decoder->hint_mode );
           }
 
           /* add current outline to the glyph slot */
           FT_GlyphLoader_Add( builder->loader );
 
-          FT_TRACE4(( "\n" ));
-
           /* the compiler should optimize away this empty loop but ... */
 
 #ifdef FT_DEBUG_LEVEL_TRACE
@@ -1019,8 +1126,8 @@
           builder->advance.x       = top[1];
           builder->advance.y       = 0;
 
-          orig_x = builder->last.x = x = builder->pos_x + top[0];
-          orig_y = builder->last.y = y = builder->pos_y;
+          orig_x = x = builder->pos_x + top[0];
+          orig_y = y = builder->pos_y;
 
           FT_UNUSED( orig_y );
 
@@ -1033,9 +1140,12 @@
           break;
 
         case op_seac:
-          /* return immediately after the processing */
-          return t1operator_seac( decoder, top[0], top[1], top[2],
-                                           (FT_Int)top[3], (FT_Int)top[4] );
+          return t1operator_seac( decoder,
+                                  top[0],
+                                  top[1],
+                                  top[2],
+                                  (FT_Int)( top[3] >> 16 ),
+                                  (FT_Int)( top[4] >> 16 ) );
 
         case op_sbw:
           FT_TRACE4(( " sbw" ));
@@ -1047,8 +1157,8 @@
           builder->advance.x       = top[2];
           builder->advance.y       = top[3];
 
-          builder->last.x = x = builder->pos_x + top[0];
-          builder->last.y = y = builder->pos_y + top[1];
+          x = builder->pos_x + top[0];
+          y = builder->pos_y + top[1];
 
           /* the `metrics_only' indicates that we only want to compute */
           /* the glyph's metrics (lsb + advance width), not load the   */
@@ -1134,7 +1244,7 @@
           break;
 
         case op_rrcurveto:
-          FT_TRACE4(( " rcurveto" ));
+          FT_TRACE4(( " rrcurveto" ));
 
           if ( start_point( builder, x, y ) ||
                check_points( builder, 3 )   )
@@ -1193,16 +1303,13 @@
         case op_div:
           FT_TRACE4(( " div" ));
 
-          if ( top[1] )
-          {
-            *top = top[0] / top[1];
-            ++top;
-          }
-          else
-          {
-            FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" ));
-            goto Syntax_Error;
-          }
+          /* if `large_int' is set, we divide unscaled numbers; */
+          /* otherwise, we divide numbers in 16.16 format --    */
+          /* in both cases, it is the same operation            */
+          *top = FT_DivFix( top[0], top[1] );
+          ++top;
+
+          large_int = FALSE;
           break;
 
         case op_callsubr:
@@ -1212,18 +1319,18 @@
 
             FT_TRACE4(( " callsubr" ));
 
-            idx = (FT_Int)top[0];
+            idx = (FT_Int)( top[0] >> 16 );
             if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs )
             {
-              FT_ERROR(( "t1_decoder_parse_charstrings: "
-                         "invalid subrs index\n" ));
+              FT_ERROR(( "t1_decoder_parse_charstrings:"
+                         " invalid subrs index\n" ));
               goto Syntax_Error;
             }
 
             if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
             {
-              FT_ERROR(( "t1_decoder_parse_charstrings: "
-                         "too many nested subrs\n" ));
+              FT_ERROR(( "t1_decoder_parse_charstrings:"
+                         " too many nested subrs\n" ));
               goto Syntax_Error;
             }
 
@@ -1250,8 +1357,8 @@
 
             if ( !zone->base )
             {
-              FT_ERROR(( "t1_decoder_parse_charstrings: "
-                         "invoking empty subrs!\n" ));
+              FT_ERROR(( "t1_decoder_parse_charstrings:"
+                         " invoking empty subrs\n" ));
               goto Syntax_Error;
             }
 
@@ -1273,8 +1380,8 @@
 
           if ( unknown_othersubr_result_cnt == 0 )
           {
-            FT_ERROR(( "t1_decoder_parse_charstrings: "
-                       "no more operands for othersubr!\n" ));
+            FT_ERROR(( "t1_decoder_parse_charstrings:"
+                       " no more operands for othersubr\n" ));
             goto Syntax_Error;
           }
 
@@ -1287,7 +1394,8 @@
 
           if ( zone <= decoder->zones )
           {
-            FT_ERROR(( "t1_decoder_parse_charstrings: unexpected return\n" ));
+            FT_ERROR(( "t1_decoder_parse_charstrings:"
+                       " unexpected return\n" ));
             goto Syntax_Error;
           }
 
@@ -1311,7 +1419,6 @@
             /* top[0] += builder->left_bearing.y; */
             hinter->stem( hinter->hints, 1, top );
           }
-
           break;
 
         case op_hstem3:
@@ -1320,19 +1427,17 @@
           /* record horizontal counter-controlled hints */
           if ( hinter )
             hinter->stem3( hinter->hints, 1, top );
-
           break;
 
         case op_vstem:
           FT_TRACE4(( " vstem" ));
 
-          /* record vertical  hint */
+          /* record vertical hint */
           if ( hinter )
           {
             top[0] += orig_x;
             hinter->stem( hinter->hints, 0, top );
           }
-
           break;
 
         case op_vstem3:
@@ -1354,20 +1459,28 @@
         case op_setcurrentpoint:
           FT_TRACE4(( " setcurrentpoint" ));
 
-          /* From the T1 specs, section 6.4:                        */
+          /* From the T1 specification, section 6.4:                */
           /*                                                        */
           /*   The setcurrentpoint command is used only in          */
           /*   conjunction with results from OtherSubrs procedures. */
 
-          /* known_othersubr_result_cnt != 0 is already handled above */
+          /* known_othersubr_result_cnt != 0 is already handled     */
+          /* above.                                                 */
+
+          /* Note, however, that both Ghostscript and Adobe         */
+          /* Distiller handle this situation by silently ignoring   */
+          /* the inappropriate `setcurrentpoint' instruction.  So   */
+          /* we do the same.                                        */
+#if 0
+
           if ( decoder->flex_state != 1 )
           {
-            FT_ERROR(( "t1_decoder_parse_charstrings: " ));
-            FT_ERROR(( "unexpected `setcurrentpoint'\n" ));
-
+            FT_ERROR(( "t1_decoder_parse_charstrings:"
+                       " unexpected `setcurrentpoint'\n" ));
             goto Syntax_Error;
           }
           else
+#endif
             decoder->flex_state = 0;
           break;
 
@@ -1377,8 +1490,8 @@
           break;
 
         default:
-          FT_ERROR(( "t1_decoder_parse_charstrings: "
-                     "unhandled opcode %d\n", op ));
+          FT_ERROR(( "t1_decoder_parse_charstrings:"
+                     " unhandled opcode %d\n", op ));
           goto Syntax_Error;
         }
 
@@ -1389,6 +1502,11 @@
 
         decoder->top = top;
 
+#ifdef FT_DEBUG_LEVEL_TRACE
+        FT_TRACE4(( "\n" ));
+        bol = TRUE;
+#endif
+
       } /* general operator processing */
 
     } /* while ip < limit */
@@ -1437,8 +1555,8 @@
       FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
       if ( !psnames )
       {
-        FT_ERROR(( "t1_decoder_init: " ));
-        FT_ERROR(( "the `psnames' module is not available\n" ));
+        FT_ERROR(( "t1_decoder_init:"
+                   " the `psnames' module is not available\n" ));
         return PSaux_Err_Unimplemented_Feature;
       }
 
diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c
index f9ab3da..417dcee 100644
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -103,7 +103,7 @@
 
     if ( idx >= table->max_hints )
     {
-      FT_ERROR(( "psh_hint_table_record: invalid hint index %d\n", idx ));
+      FT_TRACE0(( "psh_hint_table_record: invalid hint index %d\n", idx ));
       return;
     }
 
@@ -137,7 +137,7 @@
     if ( table->num_hints < table->max_hints )
       table->sort_global[table->num_hints++] = hint;
     else
-      FT_ERROR(( "psh_hint_table_record: too many sorted hints!  BUG!\n" ));
+      FT_TRACE0(( "psh_hint_table_record: too many sorted hints!  BUG!\n" ));
   }
 
 
@@ -230,7 +230,7 @@
       FT_UInt  idx;
 
 
-      FT_ERROR(( "psh_hint_table_init: missing/incorrect hint masks!\n" ));
+      FT_TRACE0(( "psh_hint_table_init: missing/incorrect hint masks\n" ));
 
       count = table->max_hints;
       for ( idx = 0; idx < count; idx++ )
@@ -282,8 +282,8 @@
           {
             hint2 = sort[0];
             if ( psh_hint_overlap( hint, hint2 ) )
-              FT_ERROR(( "psh_hint_table_activate_mask:"
-                         " found overlapping hints\n" ))
+              FT_TRACE0(( "psh_hint_table_activate_mask:"
+                          " found overlapping hints\n" ))
           }
 #else
           count2 = 0;
@@ -295,8 +295,8 @@
             if ( count < table->max_hints )
               table->sort[count++] = hint;
             else
-              FT_ERROR(( "psh_hint_tableactivate_mask:"
-                         " too many active hints\n" ));
+              FT_TRACE0(( "psh_hint_tableactivate_mask:"
+                          " too many active hints\n" ));
           }
         }
       }
diff --git a/src/pshinter/pshinter.c b/src/pshinter/pshinter.c
index 8e3f193..b35a2a9 100644
--- a/src/pshinter/pshinter.c
+++ b/src/pshinter/pshinter.c
@@ -19,6 +19,7 @@
 #define FT_MAKE_OPTION_SINGLE_OBJECT
 
 #include <ft2build.h>
+#include "pshpic.c"
 #include "pshrec.c"
 #include "pshglob.c"
 #include "pshalgo.c"
diff --git a/src/pshinter/pshmod.c b/src/pshinter/pshmod.c
index 4eb3d91..91da5d7 100644
--- a/src/pshinter/pshmod.c
+++ b/src/pshinter/pshmod.c
@@ -20,6 +20,7 @@
 #include FT_INTERNAL_OBJECTS_H
 #include "pshrec.h"
 #include "pshalgo.h"
+#include "pshpic.h"
 
 
   /* the Postscript Hinter module structure */
@@ -92,30 +93,26 @@
   }
 
 
-  static
-  const PSHinter_Interface  pshinter_interface =
-  {
+  FT_DEFINE_PSHINTER_INTERFACE(pshinter_interface,
     pshinter_get_globals_funcs,
     pshinter_get_t1_funcs,
     pshinter_get_t2_funcs
-  };
+  )
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Module_Class  pshinter_module_class =
-  {
+  FT_DEFINE_MODULE(pshinter_module_class,
+
     0,
     sizeof ( PS_Hinter_ModuleRec ),
     "pshinter",
     0x10000L,
     0x20000L,
 
-    &pshinter_interface,            /* module-specific interface */
+    &FTPSHINTER_INTERFACE_GET,            /* module-specific interface */
 
     (FT_Module_Constructor)ps_hinter_init,
     (FT_Module_Destructor) ps_hinter_done,
     (FT_Module_Requester)  0        /* no additional interface for now */
-  };
-
+  )
 
 /* END */
diff --git a/src/pshinter/pshmod.h b/src/pshinter/pshmod.h
index 1a91025..0ae7e96 100644
--- a/src/pshinter/pshmod.h
+++ b/src/pshinter/pshmod.h
@@ -27,7 +27,7 @@
 FT_BEGIN_HEADER
 
 
-  FT_EXPORT_VAR( const FT_Module_Class )  pshinter_module_class;
+  FT_DECLARE_MODULE( pshinter_module_class )
 
 
 FT_END_HEADER
diff --git a/src/pshinter/pshpic.c b/src/pshinter/pshpic.c
new file mode 100644
index 0000000..51a0879
--- /dev/null
+++ b/src/pshinter/pshpic.c
@@ -0,0 +1,67 @@
+/***************************************************************************/
+/*                                                                         */
+/*  pshpic.c                                                               */
+/*                                                                         */
+/*    The FreeType position independent code services for pshinter module. */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include "pshpic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  /* forward declaration of PIC init functions from pshmod.c */
+  void FT_Init_Class_pshinter_interface( FT_Library, PSHinter_Interface*);
+
+  void
+  pshinter_module_class_pic_free( FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Memory memory = library->memory;
+    if ( pic_container->pshinter )
+    {
+      FT_FREE( pic_container->pshinter );
+      pic_container->pshinter = NULL;
+    }
+  }
+
+  FT_Error
+  pshinter_module_class_pic_init( FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Error        error = FT_Err_Ok;
+    PSHinterPIC*  container;
+    FT_Memory memory = library->memory;
+
+    /* allocate pointer, clear and set global container pointer */
+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+      return error;
+    FT_MEM_SET( container, 0, sizeof(*container) );
+    pic_container->pshinter = container;
+    
+    /* add call to initialization function when you add new scripts */
+    FT_Init_Class_pshinter_interface(library, &container->pshinter_interface);
+
+/*Exit:*/
+    if(error)
+      pshinter_module_class_pic_free(library);
+    return error;
+  }
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+/* END */
diff --git a/src/pshinter/pshpic.h b/src/pshinter/pshpic.h
new file mode 100644
index 0000000..3555d8e
--- /dev/null
+++ b/src/pshinter/pshpic.h
@@ -0,0 +1,53 @@
+/***************************************************************************/
+/*                                                                         */
+/*  pshpic.h                                                               */
+/*                                                                         */
+/*    The FreeType position independent code services for pshinter module. */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __PSHPIC_H__
+#define __PSHPIC_H__
+
+  
+FT_BEGIN_HEADER
+
+#include FT_INTERNAL_PIC_H
+
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FTPSHINTER_INTERFACE_GET        pshinter_interface
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#include FT_INTERNAL_POSTSCRIPT_HINTS_H
+
+  typedef struct PSHinterPIC_
+  {
+    PSHinter_Interface pshinter_interface;
+  } PSHinterPIC;
+
+#define GET_PIC(lib)                    ((PSHinterPIC*)((lib)->pic_container.autofit))
+#define FTPSHINTER_INTERFACE_GET        (GET_PIC(library)->pshinter_interface)
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __PSHPIC_H__ */
+
+
+/* END */
diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c
index 2a885ef..0910cc5 100644
--- a/src/pshinter/pshrec.c
+++ b/src/pshinter/pshrec.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript hints recorder (body).                           */
 /*                                                                         */
-/*  Copyright 2001, 2002, 2003, 2004, 2007 by                              */
+/*  Copyright 2001, 2002, 2003, 2004, 2007, 2009 by                        */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,6 +20,8 @@
 #include FT_FREETYPE_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_CALC_H
+
 #include "pshrec.h"
 #include "pshalgo.h"
 
@@ -62,7 +64,7 @@
   {
     FT_UInt   old_max = table->max_hints;
     FT_UInt   new_max = count;
-    FT_Error  error   = 0;
+    FT_Error  error   = PSH_Err_Ok;
 
 
     if ( new_max > old_max )
@@ -81,7 +83,7 @@
                        FT_Memory      memory,
                        PS_Hint       *ahint )
   {
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
     FT_UInt   count;
     PS_Hint   hint = 0;
 
@@ -137,7 +139,7 @@
   {
     FT_UInt   old_max = ( mask->max_bits + 7 ) >> 3;
     FT_UInt   new_max = ( count          + 7 ) >> 3;
-    FT_Error  error   = 0;
+    FT_Error  error   = PSH_Err_Ok;
 
 
     if ( new_max > old_max )
@@ -184,7 +186,7 @@
                    FT_Int     idx,
                    FT_Memory  memory )
   {
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
     FT_Byte*  p;
 
 
@@ -234,7 +236,7 @@
   {
     FT_UInt   old_max = table->max_masks;
     FT_UInt   new_max = count;
-    FT_Error  error   = 0;
+    FT_Error  error   = PSH_Err_Ok;
 
 
     if ( new_max > old_max )
@@ -254,7 +256,7 @@
                        PS_Mask       *amask )
   {
     FT_UInt   count;
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
     PS_Mask   mask  = 0;
 
 
@@ -285,7 +287,7 @@
                       FT_Memory      memory,
                       PS_Mask       *amask )
   {
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
     FT_UInt   count;
     PS_Mask   mask;
 
@@ -314,7 +316,7 @@
                           FT_UInt         bit_count,
                           FT_Memory       memory )
   {
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
     PS_Mask   mask;
 
 
@@ -407,7 +409,7 @@
                        FT_Memory      memory )
   {
     FT_UInt   temp;
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
 
 
     /* swap index1 and index2 so that index1 < index2 */
@@ -481,8 +483,8 @@
       table->num_masks--;
     }
     else
-      FT_ERROR(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n",
-                 index1, index2 ));
+      FT_TRACE0(( "ps_mask_table_merge: ignoring invalid indices (%d,%d)\n",
+                  index1, index2 ));
 
   Exit:
     return error;
@@ -497,7 +499,7 @@
                            FT_Memory      memory )
   {
     FT_Int    index1, index2;
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
 
 
     for ( index1 = table->num_masks - 1; index1 > 0; index1-- )
@@ -558,8 +560,8 @@
                              FT_UInt       idx,
                              FT_Memory     memory )
   {
-    PS_Mask  mask;
-    FT_Error  error = 0;
+    PS_Mask   mask;
+    FT_Error  error = PSH_Err_Ok;
 
 
     /* get last hint mask */
@@ -619,7 +621,7 @@
                               FT_UInt         end_point,
                               FT_Memory       memory )
   {
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
 
 
     /* reset current mask, if any */
@@ -644,7 +646,7 @@
                            FT_Memory     memory,
                            FT_Int       *aindex )
   {
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
     FT_UInt   flags = 0;
 
 
@@ -715,7 +717,7 @@
                             FT_Int        hint3,
                             FT_Memory     memory )
   {
-    FT_Error  error   = 0;
+    FT_Error  error   = PSH_Err_Ok;
     FT_UInt   count   = dim->counters.num_masks;
     PS_Mask   counter = dim->counters.masks;
 
@@ -789,7 +791,7 @@
     ps_dimension_done( &hints->dimension[0], memory );
     ps_dimension_done( &hints->dimension[1], memory );
 
-    hints->error  = 0;
+    hints->error  = PSH_Err_Ok;
     hints->memory = 0;
   }
 
@@ -800,7 +802,7 @@
   {
     FT_MEM_ZERO( hints, sizeof ( *hints ) );
     hints->memory = memory;
-    return 0;
+    return PSH_Err_Ok;
   }
 
 
@@ -813,7 +815,7 @@
     {
     case PS_HINT_TYPE_1:
     case PS_HINT_TYPE_2:
-      hints->error     = 0;
+      hints->error     = PSH_Err_Ok;
       hints->hint_type = hint_type;
 
       ps_dimension_init( &hints->dimension[0] );
@@ -824,7 +826,7 @@
       hints->error     = PSH_Err_Invalid_Argument;
       hints->hint_type = hint_type;
 
-      FT_ERROR(( "ps_hints_open: invalid charstring type!\n" ));
+      FT_TRACE0(( "ps_hints_open: invalid charstring type\n" ));
       break;
     }
   }
@@ -842,8 +844,8 @@
       /* limit "dimension" to 0..1 */
       if ( dimension < 0 || dimension > 1 )
       {
-        FT_ERROR(( "ps_hints_stem: invalid dimension (%d) used\n",
-                   dimension ));
+        FT_TRACE0(( "ps_hints_stem: invalid dimension (%d) used\n",
+                    dimension ));
         dimension = ( dimension != 0 );
       }
 
@@ -878,8 +880,8 @@
         }
 
       default:
-        FT_ERROR(( "ps_hints_stem: called with invalid hint type (%d)\n",
-                   hints->hint_type ));
+        FT_TRACE0(( "ps_hints_stem: called with invalid hint type (%d)\n",
+                    hints->hint_type ));
         break;
       }
     }
@@ -888,11 +890,11 @@
 
   /* add one Type1 counter stem to the current hints table */
   static void
-  ps_hints_t1stem3( PS_Hints  hints,
-                    FT_Int    dimension,
-                    FT_Long*  stems )
+  ps_hints_t1stem3( PS_Hints   hints,
+                    FT_Int     dimension,
+                    FT_Fixed*  stems )
   {
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
 
 
     if ( !hints->error )
@@ -906,8 +908,8 @@
       /* limit "dimension" to 0..1 */
       if ( dimension < 0 || dimension > 1 )
       {
-        FT_ERROR(( "ps_hints_t1stem3: invalid dimension (%d) used\n",
-                   dimension ));
+        FT_TRACE0(( "ps_hints_t1stem3: invalid dimension (%d) used\n",
+                    dimension ));
         dimension = ( dimension != 0 );
       }
 
@@ -919,9 +921,10 @@
         /* add the three stems to our hints/masks table */
         for ( count = 0; count < 3; count++, stems += 2 )
         {
-          error = ps_dimension_add_t1stem(
-                    dim, (FT_Int)stems[0], (FT_Int)stems[1],
-                    memory, &idx[count] );
+          error = ps_dimension_add_t1stem( dim,
+                                           (FT_Int)FIXED_TO_INT( stems[0] ),
+                                           (FT_Int)FIXED_TO_INT( stems[1] ),
+                                           memory, &idx[count] );
           if ( error )
             goto Fail;
         }
@@ -934,7 +937,7 @@
       }
       else
       {
-        FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type!\n" ));
+        FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type\n" ));
         error = PSH_Err_Invalid_Argument;
         goto Fail;
       }
@@ -953,7 +956,7 @@
   ps_hints_t1reset( PS_Hints  hints,
                     FT_UInt   end_point )
   {
-    FT_Error  error = 0;
+    FT_Error  error = PSH_Err_Ok;
 
 
     if ( !hints->error )
@@ -1008,8 +1011,8 @@
       /* check bit count; must be equal to current total hint count */
       if ( bit_count !=  count1 + count2 )
       {
-        FT_ERROR(( "ps_hints_t2mask: "
-                   "called with invalid bitcount %d (instead of %d)\n",
+        FT_TRACE0(( "ps_hints_t2mask:"
+                    " called with invalid bitcount %d (instead of %d)\n",
                    bit_count, count1 + count2 ));
 
         /* simply ignore the operator */
@@ -1053,8 +1056,8 @@
       /* check bit count, must be equal to current total hint count */
       if ( bit_count !=  count1 + count2 )
       {
-        FT_ERROR(( "ps_hints_t2counter: "
-                   "called with invalid bitcount %d (instead of %d)\n",
+        FT_TRACE0(( "ps_hints_t2counter:"
+                    " called with invalid bitcount %d (instead of %d)\n",
                    bit_count, count1 + count2 ));
 
         /* simply ignore the operator */
@@ -1124,11 +1127,17 @@
   }
 
   static void
-  t1_hints_stem( T1_Hints  hints,
-                 FT_Int    dimension,
-                 FT_Long*  coords )
+  t1_hints_stem( T1_Hints   hints,
+                 FT_Int     dimension,
+                 FT_Fixed*  coords )
   {
-    ps_hints_stem( (PS_Hints)hints, dimension, 1, coords );
+    FT_Pos  stems[2];
+
+
+    stems[0] = FIXED_TO_INT( coords[0] );
+    stems[1] = FIXED_TO_INT( coords[1] );
+
+    ps_hints_stem( (PS_Hints)hints, dimension, 1, stems );
   }
 
 
@@ -1183,7 +1192,7 @@
       for ( n = 0; n < count * 2; n++ )
       {
         y       += coords[n];
-        stems[n] = ( y + 0x8000L ) >> 16;
+        stems[n] = FIXED_TO_INT( y );
       }
 
       /* compute lengths */
diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c
index 41942a9..00b363f 100644
--- a/src/psnames/psmodule.c
+++ b/src/psnames/psmodule.c
@@ -24,6 +24,7 @@
 #include "pstables.h"
 
 #include "psnamerr.h"
+#include "pspic.h"
 
 
 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
@@ -33,7 +34,7 @@
 
 
 #define VARIANT_BIT         0x80000000UL
-#define BASE_GLYPH( code )  ( (code) & ~VARIANT_BIT )
+#define BASE_GLYPH( code )  ( (FT_UInt32)( (code) & ~VARIANT_BIT ) )
 
 
   /* Return the Unicode value corresponding to a given glyph.  Note that */
@@ -57,7 +58,7 @@
       /*      `uniXXXXYYYYZZZZ'...                                   */
 
       FT_Int       count;
-      FT_ULong     value = 0;
+      FT_UInt32    value = 0;
       const char*  p     = glyph_name + 3;
 
 
@@ -92,7 +93,7 @@
         if ( *p == '\0' )
           return value;
         if ( *p == '.' )
-          return value | VARIANT_BIT;
+          return (FT_UInt32)( value | VARIANT_BIT );
       }
     }
 
@@ -101,7 +102,7 @@
     if ( glyph_name[0] == 'u' )
     {
       FT_Int       count;
-      FT_ULong     value = 0;
+      FT_UInt32    value = 0;
       const char*  p     = glyph_name + 1;
 
 
@@ -132,7 +133,7 @@
         if ( *p == '\0' )
           return value;
         if ( *p == '.' )
-          return value | VARIANT_BIT;
+          return (FT_UInt32)( value | VARIANT_BIT );
       }
     }
 
@@ -154,9 +155,10 @@
 
       /* now look up the glyph in the Adobe Glyph List */
       if ( !dot )
-        return ft_get_adobe_glyph_index( glyph_name, p );
+        return (FT_UInt32)ft_get_adobe_glyph_index( glyph_name, p );
       else
-        return ft_get_adobe_glyph_index( glyph_name, dot ) | VARIANT_BIT;
+        return (FT_UInt32)( ft_get_adobe_glyph_index( glyph_name, dot ) |
+                            VARIANT_BIT );
     }
   }
 
@@ -435,7 +437,7 @@
   }
 
 
-  static FT_ULong
+  static FT_UInt32
   ps_unicodes_char_next( PS_Unicodes  table,
                          FT_UInt32   *unicode )
   {
@@ -516,38 +518,43 @@
   }
 
 
-  static
-  const FT_Service_PsCMapsRec  pscmaps_interface =
-  {
 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
-
+  FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, 
     (PS_Unicode_ValueFunc)     ps_unicode_value,
     (PS_Unicodes_InitFunc)     ps_unicodes_init,
     (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,
     (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,
 
-#else
-
-    0,
-    0,
-    0,
-    0,
-
-#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
-
     (PS_Macintosh_NameFunc)    ps_get_macintosh_name,
     (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
 
     t1_standard_encoding,
     t1_expert_encoding
-  };
+  )
+
+#else
+
+  FT_DEFINE_SERVICE_PSCMAPSREC(pscmaps_interface, 
+    0,
+    0,
+    0,
+    0,
+
+    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,
+    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings,
+
+    t1_standard_encoding,
+    t1_expert_encoding
+  )
+
+#endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
 
 
-  static const FT_ServiceDescRec  pscmaps_services[] =
-  {
-    { FT_SERVICE_ID_POSTSCRIPT_CMAPS, &pscmaps_interface },
-    { NULL, NULL }
-  };
+  FT_DEFINE_SERVICEDESCREC1(pscmaps_services, 
+    FT_SERVICE_ID_POSTSCRIPT_CMAPS, &FT_PSCMAPS_INTERFACE_GET
+  )
+
+
 
 
   static FT_Pointer
@@ -556,16 +563,20 @@
   {
     FT_UNUSED( module );
 
-    return ft_service_list_lookup( pscmaps_services, service_id );
+    return ft_service_list_lookup( FT_PSCMAPS_SERVICES_GET, service_id );
   }
 
 #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
 
+#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
+#define PUT_PS_NAMES_SERVICE(a) 0
+#else
+#define PUT_PS_NAMES_SERVICE(a) a
+#endif
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Module_Class  psnames_module_class =
-  {
+  FT_DEFINE_MODULE(psnames_module_class,
+  
     0,  /* this is not a font driver, nor a renderer */
     sizeof ( FT_ModuleRec ),
 
@@ -573,18 +584,12 @@
     0x10000L,   /* driver version                      */
     0x20000L,   /* driver requires FreeType 2 or above */
 
-#ifndef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
-    0,
+    PUT_PS_NAMES_SERVICE((void*)&FT_PSCMAPS_INTERFACE_GET),   /* module specific interface */
     (FT_Module_Constructor)0,
     (FT_Module_Destructor) 0,
-    (FT_Module_Requester)  0
-#else
-    (void*)&pscmaps_interface,   /* module specific interface */
-    (FT_Module_Constructor)0,
-    (FT_Module_Destructor) 0,
-    (FT_Module_Requester)  psnames_get_service
-#endif
-  };
+    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE(psnames_get_service)
+  )
+
 
 
 /* END */
diff --git a/src/psnames/psmodule.h b/src/psnames/psmodule.h
index 232fdfb..28fa148 100644
--- a/src/psnames/psmodule.h
+++ b/src/psnames/psmodule.h
@@ -27,7 +27,7 @@
 FT_BEGIN_HEADER
 
 
-  FT_EXPORT_VAR( const FT_Module_Class )  psnames_module_class;
+  FT_DECLARE_MODULE( psnames_module_class )
 
 
 FT_END_HEADER
diff --git a/src/psnames/psnames.c b/src/psnames/psnames.c
index d6ed998..1ede225 100644
--- a/src/psnames/psnames.c
+++ b/src/psnames/psnames.c
@@ -19,6 +19,7 @@
 #define FT_MAKE_OPTION_SINGLE_OBJECT
 
 #include <ft2build.h>
+#include "pspic.c"
 #include "psmodule.c"
 
 
diff --git a/src/psnames/pspic.c b/src/psnames/pspic.c
new file mode 100644
index 0000000..ed7dadd
--- /dev/null
+++ b/src/psnames/pspic.c
@@ -0,0 +1,77 @@
+/***************************************************************************/
+/*                                                                         */
+/*  pspic.c                                                                */
+/*                                                                         */
+/*    The FreeType position independent code services for psnames module.  */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include "pspic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  /* forward declaration of PIC init functions from psmodule.c */
+  FT_Error FT_Create_Class_pscmaps_services( FT_Library, FT_ServiceDescRec**);
+  void FT_Destroy_Class_pscmaps_services( FT_Library, FT_ServiceDescRec*);
+  void FT_Init_Class_pscmaps_interface( FT_Library, FT_Service_PsCMapsRec*);
+
+  void
+  psnames_module_class_pic_free(  FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Memory memory = library->memory;
+    if ( pic_container->psnames )
+    {
+      PSModulePIC* container = (PSModulePIC*)pic_container->psnames;
+      if(container->pscmaps_services)
+        FT_Destroy_Class_pscmaps_services(library, container->pscmaps_services);
+      container->pscmaps_services = NULL;
+      FT_FREE( container );
+      pic_container->psnames = NULL;
+    }
+  }
+
+  FT_Error
+  psnames_module_class_pic_init(  FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Error        error = FT_Err_Ok;
+    PSModulePIC* container;
+    FT_Memory memory = library->memory;
+
+    /* allocate pointer, clear and set global container pointer */
+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+      return error;
+    FT_MEM_SET( container, 0, sizeof(*container) );
+    pic_container->psnames = container;
+
+    /* initialize pointer table - this is how the module usually expects this data */
+    error = FT_Create_Class_pscmaps_services(library, &container->pscmaps_services);
+    if(error) 
+      goto Exit;
+    FT_Init_Class_pscmaps_interface(library, &container->pscmaps_interface);
+    
+Exit:
+    if(error)
+      psnames_module_class_pic_free(library);
+    return error;
+  }
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
+/* END */
diff --git a/src/psnames/pspic.h b/src/psnames/pspic.h
new file mode 100644
index 0000000..75a14fd
--- /dev/null
+++ b/src/psnames/pspic.h
@@ -0,0 +1,54 @@
+/***************************************************************************/
+/*                                                                         */
+/*  pspic.h                                                                */
+/*                                                                         */
+/*    The FreeType position independent code services for psnames module.  */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __PSPIC_H__
+#define __PSPIC_H__
+
+  
+FT_BEGIN_HEADER
+
+#include FT_INTERNAL_PIC_H
+
+#ifndef FT_CONFIG_OPTION_PIC
+#define FT_PSCMAPS_SERVICES_GET     pscmaps_services
+#define FT_PSCMAPS_INTERFACE_GET    pscmaps_interface
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#include FT_SERVICE_POSTSCRIPT_CMAPS_H
+
+  typedef struct PSModulePIC_
+  {
+    FT_ServiceDescRec* pscmaps_services;
+    FT_Service_PsCMapsRec pscmaps_interface;
+  } PSModulePIC;
+
+#define GET_PIC(lib)                ((PSModulePIC*)((lib)->pic_container.psnames))
+#define FT_PSCMAPS_SERVICES_GET     (GET_PIC(library)->pscmaps_services)
+#define FT_PSCMAPS_INTERFACE_GET    (GET_PIC(library)->pscmaps_interface)
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __PSPIC_H__ */
+
+
+/* END */
diff --git a/src/raster/ftmisc.h b/src/raster/ftmisc.h
index d9d73e3..f04b540 100644
--- a/src/raster/ftmisc.h
+++ b/src/raster/ftmisc.h
@@ -52,6 +52,31 @@
               (FT_ULong)_x4         )
 
 
+  /* from include/freetype2/ftsystem.h */
+
+  typedef struct FT_MemoryRec_*  FT_Memory;
+
+  typedef void* (*FT_Alloc_Func)( FT_Memory  memory,
+                                  long       size );
+
+  typedef void (*FT_Free_Func)( FT_Memory  memory,
+                                void*      block );
+
+  typedef void* (*FT_Realloc_Func)( FT_Memory  memory,
+                                    long       cur_size,
+                                    long       new_size,
+                                    void*      block );
+
+  typedef struct FT_MemoryRec_
+  {
+    void*            user;
+
+    FT_Alloc_Func    alloc;
+    FT_Free_Func     free;
+    FT_Realloc_Func  realloc;
+
+  } FT_MemoryRec;
+
   /* from src/ftcalc.c */
 
 #include <inttypes.h>
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index eb9c4a4..23ad592 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -49,6 +49,10 @@
 
 #ifdef _STANDALONE_
 
+#define FT_CONFIG_STANDARD_LIBRARY_H  <stdlib.h>
+
+#include <string.h>           /* for memset */
+
 #include "ftmisc.h"
 #include "ftimage.h"
 
@@ -58,6 +62,8 @@
 #include "ftraster.h"
 #include FT_INTERNAL_CALC_H   /* for FT_MulDiv only */
 
+#include "rastpic.h"
+
 #endif /* !_STANDALONE_ */
 
 
@@ -72,13 +78,15 @@
   /*       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 its scanline position boundaries, i.e. `Ymin' and `Ymax'      */
   /*                                                                       */
   /*       o an array of intersection coordinates for each scanline        */
-  /*         between `Ymin' and `Ymax'.                                    */
+  /*         between `Ymin' and `Ymax'                                     */
   /*                                                                       */
   /*       o a direction, indicating whether it was built going `up' or    */
-  /*         `down', as this is very important for filling rules.          */
+  /*         `down', as this is very important for filling rules           */
+  /*                                                                       */
+  /*       o its drop-out mode                                             */
   /*                                                                       */
   /*   2 - Sweeping the target map's scanlines in order to compute segment */
   /*       `spans' which are then filled.  Additionally, this pass         */
@@ -88,15 +96,15 @@
   /*   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      |-->     */
-  /*    |_________|___________________|_________|_________________|__ _ _  */
+  /*     __________________________________________________________ _ _    */
+  /*    |         |                 |         |                 |          */
+  /*    | profile | coordinates for | profile | coordinates for |-->       */
+  /*    |    1    |  profile 1      |    2    |  profile 2      |-->       */
+  /*    |_________|_________________|_________|_________________|__ _ _    */
   /*                                                                       */
-  /*    ^                                                         ^        */
-  /*    |                                                         |        */
-  /*  start of render pool                                       top       */
+  /*    ^                                                       ^          */
+  /*    |                                                       |          */
+  /* start of render pool                                      top         */
   /*                                                                       */
   /*   The top of the profile stack is kept in the `top' variable.         */
   /*                                                                       */
@@ -140,11 +148,11 @@
   /*************************************************************************/
 
   /* define DEBUG_RASTER if you want to compile a debugging version */
-#define xxxDEBUG_RASTER
+/* #define DEBUG_RASTER */
 
-  /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */
-  /* 5-levels anti-aliasing                                                */
-#undef FT_RASTER_OPTION_ANTI_ALIASING
+  /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */
+  /* 5-levels anti-aliasing                                       */
+/* #define FT_RASTER_OPTION_ANTI_ALIASING */
 
   /* The size of the two-lines intermediate bitmap used */
   /* for anti-aliasing, in bytes.                       */
@@ -197,9 +205,22 @@
 #define Raster_Err_Invalid      -4
 #define Raster_Err_Unsupported  -5
 
-#define ft_memset   memset
+#define ft_memset  memset
 
-#else /* _STANDALONE_ */
+#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \
+                                raster_reset_, raster_set_mode_,    \
+                                raster_render_, raster_done_ )      \
+          const FT_Raster_Funcs class_ =                            \
+          {                                                         \
+            glyph_format_,                                          \
+            raster_new_,                                            \
+            raster_reset_,                                          \
+            raster_set_mode_,                                       \
+            raster_render_,                                         \
+            raster_done_                                            \
+         };
+
+#else /* !_STANDALONE_ */
 
 
 #include FT_INTERNAL_OBJECTS_H
@@ -215,7 +236,7 @@
 #define Raster_Err_Unsupported  Raster_Err_Cannot_Render_Glyph
 
 
-#endif /* _STANDALONE_ */
+#endif /* !_STANDALONE_ */
 
 
 #ifndef FT_MEM_SET
@@ -304,13 +325,10 @@
   } TPoint;
 
 
-  typedef enum  TFlow_
-  {
-    Flow_None = 0,
-    Flow_Up   = 1,
-    Flow_Down = -1
-
-  } TFlow;
+  /* values for the `flags' bit field */
+#define Flow_Up           0x8
+#define Overshoot_Top     0x10
+#define Overshoot_Bottom  0x20
 
 
   /* States of each line, arc, and profile */
@@ -329,18 +347,21 @@
 
   struct  TProfile_
   {
-    FT_F26Dot6  X;           /* current coordinate during sweep        */
-    PProfile    link;        /* link to next profile - various purpose */
-    PLong       offset;      /* start of profile's data in render pool */
-    int         flow;        /* Profile orientation: Asc/Descending    */
-    long        height;      /* profile's height in scanlines          */
-    long        start;       /* profile's starting scanline            */
+    FT_F26Dot6  X;           /* current coordinate during sweep          */
+    PProfile    link;        /* link to next profile (various purposes)  */
+    PLong       offset;      /* start of profile's data in render pool   */
+    unsigned    flags;       /* Bit 0-2: drop-out mode                   */
+                             /* Bit 3: profile orientation (up/down)     */
+                             /* Bit 4: is top profile?                   */
+                             /* Bit 5: is bottom profile?                */
+    long        height;      /* profile's height in scanlines            */
+    long        start;       /* profile's starting scanline              */
 
-    unsigned    countL;      /* number of lines to step before this    */
-                             /* profile becomes drawable               */
+    unsigned    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;
@@ -373,7 +394,7 @@
 #define FT_UNUSED_RASTER  do { } while ( 0 )
 
 
-#else /* FT_STATIC_RASTER */
+#else /* !FT_STATIC_RASTER */
 
 
 #define RAS_ARGS       PWorker    worker,
@@ -385,7 +406,7 @@
 #define FT_UNUSED_RASTER  FT_UNUSED( worker )
 
 
-#endif /* FT_STATIC_RASTER */
+#endif /* !FT_STATIC_RASTER */
 
 
   typedef struct TWorker_  TWorker, *PWorker;
@@ -415,65 +436,68 @@
 #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.          */
+#define IS_BOTTOM_OVERSHOOT( x )  ( CEILING( x ) - x >= ras.precision_half )
+#define IS_TOP_OVERSHOOT( x )     ( x - FLOOR( x ) >= ras.precision_half )
+
+  /* The most used variables are positioned at the top of the structure. */
+  /* Thus, their offset can be coded with less opcodes, resulting in a   */
+  /* smaller executable.                                                 */
 
   struct  TWorker_
   {
-    Int       precision_bits;       /* precision related variables         */
-    Int       precision;
-    Int       precision_half;
-    Long      precision_mask;
-    Int       precision_shift;
-    Int       precision_step;
-    Int       precision_jitter;
+    Int         precision_bits;     /* precision related variables         */
+    Int         precision;
+    Int         precision_half;
+    Long        precision_mask;
+    Int         precision_shift;
+    Int         precision_step;
+    Int         precision_jitter;
 
-    Int       scale_shift;          /* == precision_shift   for bitmaps    */
+    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            */
+    PLong       buff;               /* The profiles buffer                 */
+    PLong       sizeBuff;           /* Render pool size                    */
+    PLong       maxBuff;            /* Profiles buffer size                */
+    PLong       top;                /* Current cursor in buffer            */
 
-    FT_Error  error;
+    FT_Error    error;
 
-    Int       numTurns;             /* number of Y-turns in outline        */
+    Int         numTurns;           /* number of Y-turns in outline        */
 
-    TPoint*   arc;                  /* current Bezier arc pointer          */
+    TPoint*     arc;                /* current Bezier arc pointer          */
 
-    UShort    bWidth;               /* target bitmap width                 */
-    PByte     bTarget;              /* target bitmap buffer                */
-    PByte     gTarget;              /* target pixmap buffer                */
+    UShort      bWidth;             /* target bitmap width                 */
+    PByte       bTarget;            /* target bitmap buffer                */
+    PByte       gTarget;            /* target pixmap buffer                */
 
-    Long      lastX, lastY, minY, maxY;
+    Long        lastX, lastY;
+    Long        minY, maxY;
 
-    UShort    num_Profs;            /* current number of profiles          */
+    UShort      num_Profs;          /* current number of profiles          */
 
-    Bool      fresh;                /* signals a fresh new profile which   */
-                                    /* 'start' field must be completed     */
-    Bool      joint;                /* signals that the last arc ended     */
+    Bool        fresh;              /* signals a fresh new profile which   */
+                                    /* `start' field must be completed     */
+    Bool        joint;              /* signals that the last arc ended     */
                                     /* exactly on a scanline.  Allows      */
                                     /* removal of doublets                 */
-    PProfile  cProfile;             /* current profile                     */
-    PProfile  fProfile;             /* head of linked list of profiles     */
-    PProfile  gProfile;             /* contour's first profile in case     */
+    PProfile    cProfile;           /* current profile                     */
+    PProfile    fProfile;           /* head of linked list of profiles     */
+    PProfile    gProfile;           /* contour's first profile in case     */
                                     /* of impact                           */
 
-    TStates   state;                /* rendering state                     */
+    TStates     state;              /* rendering state                     */
 
     FT_Bitmap   target;             /* description of target bit/pixmap    */
     FT_Outline  outline;
 
-    Long      traceOfs;             /* current offset in target bitmap     */
-    Long      traceG;               /* current offset in target pixmap     */
+    Long        traceOfs;           /* current offset in target bitmap     */
+    Long        traceG;             /* current offset in target pixmap     */
 
-    Short     traceIncr;            /* sweep's increment in target bitmap  */
+    Short       traceIncr;          /* sweep's increment in target bitmap  */
 
-    Short     gray_min_x;           /* current min x during gray rendering */
-    Short     gray_max_x;           /* current max x during gray rendering */
+    Short       gray_min_x;         /* current min x during gray rendering */
+    Short       gray_max_x;         /* current max x during gray rendering */
 
     /* dispatch variables */
 
@@ -482,31 +506,31 @@
     Function_Sweep_Span*  Proc_Sweep_Drop;
     Function_Sweep_Step*  Proc_Sweep_Step;
 
-    Byte      dropOutControl;       /* current drop_out control method     */
+    Byte        dropOutControl;     /* current drop_out control method     */
 
-    Bool      second_pass;          /* indicates whether a horizontal pass */
+    Bool        second_pass;        /* indicates whether a horizontal pass */
                                     /* should be performed to control      */
                                     /* drop-out accurately when calling    */
                                     /* Render_Glyph.  Note that there is   */
                                     /* no horizontal pass during gray      */
                                     /* rendering.                          */
 
-    TPoint    arcs[3 * MaxBezier + 1]; /* The Bezier stack                 */
+    TPoint      arcs[3 * MaxBezier + 1]; /* The Bezier stack               */
 
-    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                      */
 
 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
 
-    Byte*     grays;
+    Byte*       grays;
 
-    Byte      gray_lines[RASTER_GRAY_LINES];
+    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        */
+    Short       gray_width;     /* width in bytes of one monochrome        */
                                 /* intermediate scanline of gray_lines.    */
                                 /* Each gray pixel takes 2 bits long there */
 
@@ -520,12 +544,12 @@
 
   typedef struct  TRaster_
   {
-    char*     buffer;
-    long      buffer_size;
-    void*     memory;
-    PWorker   worker;
-    Byte      grays[5];
-    Short     gray_width;
+    char*    buffer;
+    long     buffer_size;
+    void*    memory;
+    PWorker  worker;
+    Byte     grays[5];
+    Short    gray_width;
 
   } TRaster, *PRaster;
 
@@ -534,34 +558,72 @@
   static TWorker  cur_ras;
 #define ras  cur_ras
 
-#else
+#else /* !FT_STATIC_RASTER */
 
 #define ras  (*worker)
 
-#endif /* FT_STATIC_RASTER */
+#endif /* !FT_STATIC_RASTER */
 
 
 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
 
-  static const char  count_table[256] =
+  /* A lookup table used to quickly count set bits in four gray 2x2 */
+  /* cells.  The values of the table have been produced with the    */
+  /* following code:                                                */
+  /*                                                                */
+  /*   for ( i = 0; i < 256; i++ )                                  */
+  /*   {                                                            */
+  /*     l = 0;                                                     */
+  /*     j = i;                                                     */
+  /*                                                                */
+  /*     for ( c = 0; c < 4; c++ )                                  */
+  /*     {                                                          */
+  /*       l <<= 4;                                                 */
+  /*                                                                */
+  /*       if ( j & 0x80 ) l++;                                     */
+  /*       if ( j & 0x40 ) l++;                                     */
+  /*                                                                */
+  /*       j = ( j << 2 ) & 0xFF;                                   */
+  /*     }                                                          */
+  /*     printf( "0x%04X", l );                                     */
+  /*   }                                                            */
+  /*                                                                */
+
+  static const short  count_table[256] =
   {
-    0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4,
-    1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
-    1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
-    2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
-    1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
-    2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
-    2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
-    3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
-    1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5,
-    2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
-    2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
-    3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
-    2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6,
-    3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
-    3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7,
-    4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8
-a  };
+    0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012,
+    0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022,
+    0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
+    0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
+    0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
+    0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
+    0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212,
+    0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222,
+    0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
+    0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
+    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
+    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
+    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
+    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
+    0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
+    0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
+    0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
+    0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
+    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
+    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
+    0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
+    0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
+    0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
+    0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
+    0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012,
+    0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022,
+    0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
+    0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
+    0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
+    0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
+    0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212,
+    0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222
+  };
 
 #endif /* FT_RASTER_OPTION_ANTI_ALIASING */
 
@@ -593,9 +655,9 @@
   {
     if ( High )
     {
-      ras.precision_bits   = 10;
-      ras.precision_step   = 128;
-      ras.precision_jitter = 24;
+      ras.precision_bits   = 12;
+      ras.precision_step   = 256;
+      ras.precision_jitter = 50;
     }
     else
     {
@@ -622,14 +684,18 @@
   /*    Create a new profile in the render pool.                           */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    aState :: The state/orientation of the new profile.                */
+  /*    aState    :: The state/orientation of the new profile.             */
+  /*                                                                       */
+  /*    overshoot :: Whether the profile's unrounded start position        */
+  /*                 differs by at least a half pixel.                     */
   /*                                                                       */
   /* <Return>                                                              */
   /*   SUCCESS on success.  FAILURE in case of overflow or of incoherent   */
   /*   profile.                                                            */
   /*                                                                       */
   static Bool
-  New_Profile( RAS_ARGS TStates  aState )
+  New_Profile( RAS_ARGS TStates  aState,
+                        Bool     overshoot )
   {
     if ( !ras.fProfile )
     {
@@ -644,29 +710,35 @@
       return FAILURE;
     }
 
-    switch ( aState )
-    {
-    case Ascending_State:
-      ras.cProfile->flow = Flow_Up;
-      FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile ));
-      break;
-
-    case Descending_State:
-      ras.cProfile->flow = Flow_Down;
-      FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile ));
-      break;
-
-    default:
-      FT_ERROR(( "New_Profile: invalid profile direction!\n" ));
-      ras.error = Raster_Err_Invalid;
-      return FAILURE;
-    }
-
+    ras.cProfile->flags  = 0;
     ras.cProfile->start  = 0;
     ras.cProfile->height = 0;
     ras.cProfile->offset = ras.top;
     ras.cProfile->link   = (PProfile)0;
     ras.cProfile->next   = (PProfile)0;
+    ras.cProfile->flags  = ras.dropOutControl;
+
+    switch ( aState )
+    {
+    case Ascending_State:
+      ras.cProfile->flags |= Flow_Up;
+      if ( overshoot )
+        ras.cProfile->flags |= Overshoot_Bottom;
+
+      FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile ));
+      break;
+
+    case Descending_State:
+      if ( overshoot )
+        ras.cProfile->flags |= Overshoot_Top;
+      FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile ));
+      break;
+
+    default:
+      FT_ERROR(( "New_Profile: invalid profile direction\n" ));
+      ras.error = Raster_Err_Invalid;
+      return FAILURE;
+    }
 
     if ( !ras.gProfile )
       ras.gProfile = ras.cProfile;
@@ -687,11 +759,15 @@
   /* <Description>                                                         */
   /*    Finalize the current profile.                                      */
   /*                                                                       */
+  /* <Input>                                                               */
+  /*    overshoot :: Whether the profile's unrounded end position differs  */
+  /*                 by at least a half pixel.                             */
+  /*                                                                       */
   /* <Return>                                                              */
   /*    SUCCESS on success.  FAILURE in case of overflow or incoherency.   */
   /*                                                                       */
   static Bool
-  End_Profile( RAS_ARG )
+  End_Profile( RAS_ARGS Bool  overshoot )
   {
     Long      h;
     PProfile  oldProfile;
@@ -701,7 +777,7 @@
 
     if ( h < 0 )
     {
-      FT_ERROR(( "End_Profile: negative height encountered!\n" ));
+      FT_ERROR(( "End_Profile: negative height encountered\n" ));
       ras.error = Raster_Err_Neg_Height;
       return FAILURE;
     }
@@ -711,15 +787,24 @@
       FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n",
                   (long)ras.cProfile, ras.cProfile->start, h ));
 
-      oldProfile           = ras.cProfile;
       ras.cProfile->height = h;
-      ras.cProfile         = (PProfile)ras.top;
+      if ( overshoot )
+      {
+        if ( ras.cProfile->flags & Flow_Up )
+          ras.cProfile->flags |= Overshoot_Top;
+        else
+          ras.cProfile->flags |= Overshoot_Bottom;
+      }
 
-      ras.top             += AlignProfileSize;
+      oldProfile   = ras.cProfile;
+      ras.cProfile = (PProfile)ras.top;
+
+      ras.top += AlignProfileSize;
 
       ras.cProfile->height = 0;
       ras.cProfile->offset = ras.top;
-      oldProfile->next     = ras.cProfile;
+
+      oldProfile->next = ras.cProfile;
       ras.num_Profs++;
     }
 
@@ -822,23 +907,21 @@
         else
           p->link = NULL;
 
-        switch ( p->flow )
+        if ( p->flags & Flow_Up )
         {
-        case Flow_Down:
+          bottom = (Int)p->start;
+          top    = (Int)( p->start + p->height - 1 );
+        }
+        else
+        {
           bottom     = (Int)( p->start - p->height + 1 );
           top        = (Int)p->start;
           p->start   = bottom;
           p->offset += p->height - 1;
-          break;
-
-        case Flow_Up:
-        default:
-          bottom = (Int)p->start;
-          top    = (Int)( p->start + p->height - 1 );
         }
 
-        if ( Insert_Y_Turn( RAS_VARS bottom )   ||
-             Insert_Y_Turn( RAS_VARS top + 1 )  )
+        if ( Insert_Y_Turn( RAS_VARS bottom )  ||
+             Insert_Y_Turn( RAS_VARS top + 1 ) )
           return FAILURE;
 
         p = p->link;
@@ -1230,7 +1313,7 @@
         }
         else
         {
-          *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x,
+          *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x,
                                             e - y1, y2 - y1 );
           arc -= degree;
           e   += ras.precision;
@@ -1335,13 +1418,15 @@
     case Unknown_State:
       if ( y > ras.lastY )
       {
-        if ( New_Profile( RAS_VARS Ascending_State ) )
+        if ( New_Profile( RAS_VARS Ascending_State,
+                                   IS_BOTTOM_OVERSHOOT( ras.lastY ) ) )
           return FAILURE;
       }
       else
       {
         if ( y < ras.lastY )
-          if ( New_Profile( RAS_VARS Descending_State ) )
+          if ( New_Profile( RAS_VARS Descending_State,
+                                     IS_TOP_OVERSHOOT( ras.lastY ) ) )
             return FAILURE;
       }
       break;
@@ -1349,8 +1434,9 @@
     case Ascending_State:
       if ( y < ras.lastY )
       {
-        if ( End_Profile( RAS_VAR )                   ||
-             New_Profile( RAS_VARS Descending_State ) )
+        if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) ||
+             New_Profile( RAS_VARS Descending_State,
+                                   IS_TOP_OVERSHOOT( ras.lastY ) ) )
           return FAILURE;
       }
       break;
@@ -1358,8 +1444,9 @@
     case Descending_State:
       if ( y > ras.lastY )
       {
-        if ( End_Profile( RAS_VAR )                  ||
-             New_Profile( RAS_VARS Ascending_State ) )
+        if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ||
+             New_Profile( RAS_VARS Ascending_State,
+                                   IS_BOTTOM_OVERSHOOT( ras.lastY ) ) )
           return FAILURE;
       }
       break;
@@ -1374,13 +1461,13 @@
     {
     case Ascending_State:
       if ( Line_Up( RAS_VARS ras.lastX, ras.lastY,
-                    x, y, ras.minY, ras.maxY ) )
+                             x, y, ras.minY, ras.maxY ) )
         return FAILURE;
       break;
 
     case Descending_State:
       if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,
-                      x, y, ras.minY, ras.maxY ) )
+                               x, y, ras.minY, ras.maxY ) )
         return FAILURE;
       break;
 
@@ -1431,8 +1518,10 @@
     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[1].x = cx;
+    ras.arc[1].y = cy;
+    ras.arc[0].x = x;
+    ras.arc[0].y = y;
 
     do
     {
@@ -1472,13 +1561,17 @@
         state_bez = y1 < y3 ? Ascending_State : Descending_State;
         if ( ras.state != state_bez )
         {
+          Bool  o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )
+                                                 : IS_TOP_OVERSHOOT( y1 );
+
+
           /* finalize current profile if any */
-          if ( ras.state != Unknown_State   &&
-               End_Profile( RAS_VAR ) )
+          if ( ras.state != Unknown_State &&
+               End_Profile( RAS_VARS o )  )
             goto Fail;
 
           /* create a new profile */
-          if ( New_Profile( RAS_VARS state_bez ) )
+          if ( New_Profile( RAS_VARS state_bez, o ) )
             goto Fail;
         }
 
@@ -1547,9 +1640,12 @@
     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;
+    ras.arc[2].x = cx1;
+    ras.arc[2].y = cy1;
+    ras.arc[1].x = cx2;
+    ras.arc[1].y = cy2;
+    ras.arc[0].x = x;
+    ras.arc[0].y = y;
 
     do
     {
@@ -1601,11 +1697,16 @@
         /* detect a change of direction */
         if ( ras.state != state_bez )
         {
-          if ( ras.state != Unknown_State   &&
-               End_Profile( RAS_VAR ) )
+          Bool  o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )
+                                                 : IS_TOP_OVERSHOOT( y1 );
+
+
+          /* finalize current profile if any */
+          if ( ras.state != Unknown_State &&
+               End_Profile( RAS_VARS o )  )
             goto Fail;
 
-          if ( New_Profile( RAS_VARS state_bez ) )
+          if ( New_Profile( RAS_VARS state_bez, o ) )
             goto Fail;
         }
 
@@ -1698,8 +1799,13 @@
     v_control = v_start;
 
     point = points + first;
-    tags  = ras.outline.tags  + first;
-    tag   = FT_CURVE_TAG( tags[0] );
+    tags  = ras.outline.tags + first;
+
+    /* set scan mode if necessary */
+    if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE )
+      ras.dropOutControl = (Byte)tags[0] >> 5;
+
+    tag = FT_CURVE_TAG( tags[0] );
 
     /* A contour cannot start with a cubic control point! */
     if ( tag == FT_CURVE_TAG_CUBIC )
@@ -1905,27 +2011,36 @@
 
     for ( i = 0; i < ras.outline.n_contours; i++ )
     {
+      Bool  o;
+
+
       ras.state    = Unknown_State;
       ras.gProfile = NULL;
 
       if ( Decompose_Curve( RAS_VARS (unsigned short)start,
-                            ras.outline.contours[i],
-                            flipped ) )
+                                     ras.outline.contours[i],
+                                     flipped ) )
         return FAILURE;
 
       start = ras.outline.contours[i] + 1;
 
-      /* We must now see whether the extreme arcs join or not */
+      /* we must now check whether the extreme arcs join or not */
       if ( FRAC( ras.lastY ) == 0 &&
            ras.lastY >= ras.minY  &&
            ras.lastY <= ras.maxY  )
-        if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow )
+        if ( ras.gProfile                        &&
+             ( ras.gProfile->flags & Flow_Up ) ==
+               ( ras.cProfile->flags & Flow_Up ) )
           ras.top--;
         /* Note that ras.gProfile can be nil if the contour was too small */
         /* to be drawn.                                                   */
 
       lastProfile = ras.cProfile;
-      if ( End_Profile( RAS_VAR ) )
+      if ( ras.cProfile->flags & Flow_Up )
+        o = IS_TOP_OVERSHOOT( ras.lastY );
+      else
+        o = IS_BOTTOM_OVERSHOOT( ras.lastY );
+      if ( End_Profile( RAS_VARS o ) )
         return FAILURE;
 
       /* close the `next profile in contour' linked list */
@@ -2045,7 +2160,7 @@
     while ( current )
     {
       current->X       = *current->offset;
-      current->offset += current->flow;
+      current->offset += current->flags & Flow_Up ? 1 : -1;
       current->height--;
       current = current->link;
     }
@@ -2220,16 +2335,19 @@
 
     if ( e1 > e2 )
     {
+      Int  dropOutControl = left->flags & 7;
+
+
       if ( e1 == e2 + ras.precision )
       {
-        switch ( ras.dropOutControl )
+        switch ( dropOutControl )
         {
         case 0: /* simple drop-outs including stubs */
           pxl = e2;
           break;
 
         case 4: /* smart drop-outs including stubs */
-          pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+          pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
           break;
 
         case 1: /* simple drop-outs excluding stubs */
@@ -2237,11 +2355,10 @@
 
           /* Drop-out Control Rules #4 and #6 */
 
-          /* The spec is not very clear regarding those rules.  It  */
-          /* presents a method that is way too costly to implement  */
-          /* while the general idea seems to get rid of `stubs'.    */
+          /* The specification neither provides an exact definition */
+          /* of a `stub' nor gives exact rules to exclude them.     */
           /*                                                        */
-          /* Here, we only get rid of stubs recognized if:          */
+          /* Here the constraints we use to recognize a stub.       */
           /*                                                        */
           /*  upper stub:                                           */
           /*                                                        */
@@ -2255,27 +2372,31 @@
           /*   - P_Left is the successor of P_Right in that contour */
           /*   - y is the bottom of P_Left                          */
           /*                                                        */
+          /* We draw a stub if the following constraints are met.   */
+          /*                                                        */
+          /*   - for an upper or lower stub, there is top or bottom */
+          /*     overshoot, respectively                            */
+          /*   - the covered interval is greater or equal to a half */
+          /*     pixel                                              */
 
-          /* FIXXXME: uncommenting this line solves the disappearing */
-          /*          bit problem in the `7' of verdana 10pts, but   */
-          /*          makes a new one in the `C' of arial 14pts      */
-#if 0
-          if ( x2 - x1 < ras.precision_half )
-#endif
-          {
-            /* upper stub test */
-            if ( left->next == right && left->height <= 0 )
-              return;
+          /* upper stub test */
+          if ( left->next == right                &&
+               left->height <= 0                  &&
+               !( left->flags & Overshoot_Top   &&
+                  x2 - x1 >= ras.precision_half ) )
+            return;
 
-            /* lower stub test */
-            if ( right->next == left && left->start == y )
-              return;
-          }
+          /* lower stub test */
+          if ( right->next == left                 &&
+               left->start == y                    &&
+               !( left->flags & Overshoot_Bottom &&
+                  x2 - x1 >= ras.precision_half  ) )
+            return;
 
-          if ( ras.dropOutControl == 1 )
+          if ( dropOutControl == 1 )
             pxl = e2;
           else
-            pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+            pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
           break;
 
         default: /* modes 2, 3, 6, 7 */
@@ -2415,16 +2536,19 @@
 
     if ( e1 > e2 )
     {
+      Int  dropOutControl = left->flags & 7;
+
+
       if ( e1 == e2 + ras.precision )
       {
-        switch ( ras.dropOutControl )
+        switch ( dropOutControl )
         {
         case 0: /* simple drop-outs including stubs */
           pxl = e2;
           break;
 
         case 4: /* smart drop-outs including stubs */
-          pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+          pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
           break;
 
         case 1: /* simple drop-outs excluding stubs */
@@ -2432,17 +2556,23 @@
           /* see Vertical_Sweep_Drop for details */
 
           /* rightmost stub test */
-          if ( left->next == right && left->height <= 0 )
+          if ( left->next == right                &&
+               left->height <= 0                  &&
+               !( left->flags & Overshoot_Top   &&
+                  x2 - x1 >= ras.precision_half ) )
             return;
 
           /* leftmost stub test */
-          if ( right->next == left && left->start == y )
+          if ( right->next == left                 &&
+               left->start == y                    &&
+               !( left->flags & Overshoot_Bottom &&
+                  x2 - x1 >= ras.precision_half  ) )
             return;
 
-          if ( ras.dropOutControl == 1 )
+          if ( dropOutControl == 1 )
             pxl = e2;
           else
-            pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+            pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
           break;
 
         default: /* modes 2, 3, 6, 7 */
@@ -2543,10 +2673,10 @@
   static void
   Vertical_Gray_Sweep_Step( RAS_ARG )
   {
-    Int    c1, c2;
-    PByte  pix, bit, bit2;
-    char*  count = (char*)count_table;
-    Byte*  grays;
+    Int     c1, c2;
+    PByte   pix, bit, bit2;
+    short*  count = (short*)count_table;
+    Byte*   grays;
 
 
     ras.traceOfs += ras.gray_width;
@@ -2665,16 +2795,19 @@
 
     if ( e1 > e2 )
     {
+      Int  dropOutControl = left->flags & 7;
+
+
       if ( e1 == e2 + ras.precision )
       {
-        switch ( ras.dropOutControl )
+        switch ( dropOutControl )
         {
         case 0: /* simple drop-outs including stubs */
           e1 = e2;
           break;
 
         case 4: /* smart drop-outs including stubs */
-          e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+          e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
           break;
 
         case 1: /* simple drop-outs excluding stubs */
@@ -2689,10 +2822,10 @@
           if ( right->next == left && left->start == y )
             return;
 
-          if ( ras.dropOutControl == 1 )
+          if ( dropOutControl == 1 )
             e1 = e2;
           else
-            e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half );
+            e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
 
           break;
 
@@ -2806,7 +2939,7 @@
     y        = min_Y;
     y_height = 0;
 
-    if ( ras.numTurns > 0 &&
+    if ( ras.numTurns > 0                     &&
          ras.sizeBuff[-ras.numTurns] == min_Y )
       ras.numTurns--;
 
@@ -2824,16 +2957,10 @@
         {
           DelOld( &waiting, P );
 
-          switch ( P->flow )
-          {
-          case Flow_Up:
+          if ( P->flags & Flow_Up )
             InsNew( &draw_left,  P );
-            break;
-
-          case Flow_Down:
+          else
             InsNew( &draw_right, P );
-            break;
-          }
         }
 
         P = Q;
@@ -2876,7 +3003,10 @@
           {
             if ( e1 > e2 || e2 == e1 + ras.precision )
             {
-              if ( ras.dropOutControl != 2 )
+              Int  dropOutControl = P_Left->flags & 7;
+
+
+              if ( dropOutControl != 2 )
               {
                 /* a drop-out was detected */
 
@@ -3070,7 +3200,7 @@
 
 
     Set_High_Precision( RAS_VARS ras.outline.flags &
-                        FT_OUTLINE_HIGH_PRECISION );
+                                 FT_OUTLINE_HIGH_PRECISION );
     ras.scale_shift = ras.precision_shift;
 
     if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
@@ -3146,7 +3276,7 @@
 
 
     Set_High_Precision( RAS_VARS ras.outline.flags &
-                        FT_OUTLINE_HIGH_PRECISION );
+                                 FT_OUTLINE_HIGH_PRECISION );
     ras.scale_shift = ras.precision_shift + 1;
 
     if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
@@ -3234,7 +3364,6 @@
       raster->grays[n] = n * 255 / 4;
 
     raster->gray_width = RASTER_GRAY_LINES / 2;
-
 #else
     FT_UNUSED( raster );
 #endif
@@ -3411,23 +3540,24 @@
 #ifdef FT_RASTER_OPTION_ANTI_ALIASING
     worker->grays      = raster->grays;
     worker->gray_width = raster->gray_width;
+
+    FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 );
 #endif
 
-    return ( ( params->flags & FT_RASTER_FLAG_AA )
-               ? Render_Gray_Glyph( RAS_VAR )
-               : Render_Glyph( RAS_VAR ) );
+    return ( params->flags & FT_RASTER_FLAG_AA )
+           ? Render_Gray_Glyph( RAS_VAR )
+           : Render_Glyph( RAS_VAR );
   }
 
 
-  const FT_Raster_Funcs  ft_standard_raster =
-  {
+  FT_DEFINE_RASTER_FUNCS( ft_standard_raster,
     FT_GLYPH_FORMAT_OUTLINE,
     (FT_Raster_New_Func)     ft_black_new,
     (FT_Raster_Reset_Func)   ft_black_reset,
     (FT_Raster_Set_Mode_Func)ft_black_set_mode,
     (FT_Raster_Render_Func)  ft_black_render,
     (FT_Raster_Done_Func)    ft_black_done
-  };
+  )
 
 
 /* END */
diff --git a/src/raster/ftrend1.c b/src/raster/ftrend1.c
index 3cc8d07..1ed8af6 100644
--- a/src/raster/ftrend1.c
+++ b/src/raster/ftrend1.c
@@ -21,6 +21,7 @@
 #include FT_OUTLINE_H
 #include "ftrend1.h"
 #include "ftraster.h"
+#include "rastpic.h"
 
 #include "rasterrs.h"
 
@@ -118,6 +119,7 @@
     }
 
     /* check rendering mode */
+#ifndef FT_CONFIG_OPTION_PIC
     if ( mode != FT_RENDER_MODE_MONO )
     {
       /* raster1 is only capable of producing monochrome bitmaps */
@@ -130,6 +132,25 @@
       if ( render->clazz == &ft_raster5_renderer_class )
         return Raster_Err_Cannot_Render_Glyph;
     }
+#else /* FT_CONFIG_OPTION_PIC */
+    /* When PIC is enabled, we cannot get to the class object      */
+    /* so instead we check the final character in the class name   */
+    /* ("raster5" or "raster1"). Yes this is a hack.               */
+    /* The "correct" thing to do is have different render function */
+    /* for each of the classes.                                    */
+    if ( mode != FT_RENDER_MODE_MONO )
+    {
+      /* raster1 is only capable of producing monochrome bitmaps */
+      if ( render->clazz->root.module_name[6] == '1' )
+        return Raster_Err_Cannot_Render_Glyph;
+    }
+    else
+    {
+      /* raster5 is only capable of producing 5-gray-levels bitmaps */
+      if ( render->clazz->root.module_name[6] == '5' )
+        return Raster_Err_Cannot_Render_Glyph;
+    }
+#endif /* FT_CONFIG_OPTION_PIC */
 
     outline = &slot->outline;
 
@@ -208,10 +229,8 @@
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Renderer_Class  ft_raster1_renderer_class =
-  {
-    {
+  FT_DEFINE_RENDERER(ft_raster1_renderer_class,
+    
       FT_MODULE_RENDERER,
       sizeof( FT_RendererRec ),
 
@@ -224,7 +243,7 @@
       (FT_Module_Constructor)ft_raster1_init,
       (FT_Module_Destructor) 0,
       (FT_Module_Requester)  0
-    },
+    ,
 
     FT_GLYPH_FORMAT_OUTLINE,
 
@@ -233,18 +252,17 @@
     (FT_Renderer_GetCBoxFunc)  ft_raster1_get_cbox,
     (FT_Renderer_SetModeFunc)  ft_raster1_set_mode,
 
-    (FT_Raster_Funcs*)    &ft_standard_raster
-  };
+    (FT_Raster_Funcs*)    &FT_STANDARD_RASTER_GET
+  )
 
 
   /* This renderer is _NOT_ part of the default modules; you will need */
   /* to register it by hand in your application.  It should only be    */
   /* used for backwards-compatibility with FT 1.x anyway.              */
   /*                                                                   */
-  FT_CALLBACK_TABLE_DEF
-  const FT_Renderer_Class  ft_raster5_renderer_class =
-  {
-    {
+  FT_DEFINE_RENDERER(ft_raster5_renderer_class,
+  
+    
       FT_MODULE_RENDERER,
       sizeof( FT_RendererRec ),
 
@@ -257,7 +275,7 @@
       (FT_Module_Constructor)ft_raster1_init,
       (FT_Module_Destructor) 0,
       (FT_Module_Requester)  0
-    },
+    ,
 
     FT_GLYPH_FORMAT_OUTLINE,
 
@@ -266,8 +284,8 @@
     (FT_Renderer_GetCBoxFunc)  ft_raster1_get_cbox,
     (FT_Renderer_SetModeFunc)  ft_raster1_set_mode,
 
-    (FT_Raster_Funcs*)    &ft_standard_raster
-  };
+    (FT_Raster_Funcs*)    &FT_STANDARD_RASTER_GET
+  )
 
 
 /* END */
diff --git a/src/raster/ftrend1.h b/src/raster/ftrend1.h
index 76e9a5f..4cf1286 100644
--- a/src/raster/ftrend1.h
+++ b/src/raster/ftrend1.h
@@ -27,13 +27,13 @@
 FT_BEGIN_HEADER
 
 
-  FT_EXPORT_VAR( const FT_Renderer_Class )  ft_raster1_renderer_class;
+  FT_DECLARE_RENDERER( ft_raster1_renderer_class )
 
   /* this renderer is _NOT_ part of the default modules, you'll need */
   /* to register it by hand in your application.  It should only be  */
   /* used for backwards-compatibility with FT 1.x anyway.            */
   /*                                                                 */
-  FT_EXPORT_VAR( const FT_Renderer_Class )  ft_raster5_renderer_class;
+  FT_DECLARE_RENDERER( ft_raster5_renderer_class )
 
 
 FT_END_HEADER
diff --git a/src/raster/raster.c b/src/raster/raster.c
index f13a67a..1202a11 100644
--- a/src/raster/raster.c
+++ b/src/raster/raster.c
@@ -19,6 +19,7 @@
 #define FT_MAKE_OPTION_SINGLE_OBJECT
 
 #include <ft2build.h>
+#include "rastpic.c"
 #include "ftraster.c"
 #include "ftrend1.c"
 
diff --git a/src/raster/rastpic.c b/src/raster/rastpic.c
new file mode 100644
index 0000000..3c26487
--- /dev/null
+++ b/src/raster/rastpic.c
@@ -0,0 +1,89 @@
+/***************************************************************************/
+/*                                                                         */
+/*  rastpic.c                                                              */
+/*                                                                         */
+/*    The FreeType position independent code services for raster module.   */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include "rastpic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  /* forward declaration of PIC init functions from ftraster.c */
+  void FT_Init_Class_ft_standard_raster(FT_Raster_Funcs*);
+
+  void
+  ft_raster1_renderer_class_pic_free(  FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Memory memory = library->memory;
+    if ( pic_container->raster )
+    {
+      RasterPIC* container = (RasterPIC*)pic_container->raster;
+      if(--container->ref_count)
+        return;
+      FT_FREE( container );
+      pic_container->raster = NULL;
+    }
+  }
+
+
+  FT_Error
+  ft_raster1_renderer_class_pic_init(  FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Error        error = FT_Err_Ok;
+    RasterPIC* container;
+    FT_Memory memory = library->memory;
+
+    /* since this function also serve raster5 renderer, 
+       it implements reference counting */
+    if(pic_container->raster)
+    {
+      ((RasterPIC*)pic_container->raster)->ref_count++;
+      return error;
+    }
+
+    /* allocate pointer, clear and set global container pointer */
+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+      return error;
+    FT_MEM_SET( container, 0, sizeof(*container) );
+    pic_container->raster = container;
+    container->ref_count = 1;
+
+    /* initialize pointer table - this is how the module usually expects this data */
+    FT_Init_Class_ft_standard_raster(&container->ft_standard_raster);
+/*Exit:*/
+    if(error)
+      ft_raster1_renderer_class_pic_free(library);
+    return error;
+  }
+
+  /* re-route these init and free functions to the above functions */
+  FT_Error ft_raster5_renderer_class_pic_init(FT_Library library)
+  {
+    return ft_raster1_renderer_class_pic_init(library);
+  }
+  void ft_raster5_renderer_class_pic_free(FT_Library library)
+  {
+    ft_raster1_renderer_class_pic_free(library);
+  }
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
+/* END */
diff --git a/src/raster/rastpic.h b/src/raster/rastpic.h
new file mode 100644
index 0000000..dcd82b8
--- /dev/null
+++ b/src/raster/rastpic.h
@@ -0,0 +1,50 @@
+/***************************************************************************/
+/*                                                                         */
+/*  rastpic.h                                                              */
+/*                                                                         */
+/*    The FreeType position independent code services for raster module.   */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __RASTPIC_H__
+#define __RASTPIC_H__
+
+  
+FT_BEGIN_HEADER
+
+#include FT_INTERNAL_PIC_H
+
+#ifndef FT_CONFIG_OPTION_PIC
+#define FT_STANDARD_RASTER_GET     ft_standard_raster
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+  typedef struct RasterPIC_
+  {
+    int ref_count;
+    FT_Raster_Funcs ft_standard_raster;
+  } RasterPIC;
+
+#define GET_PIC(lib)               ((RasterPIC*)((lib)->pic_container.raster))
+#define FT_STANDARD_RASTER_GET     (GET_PIC(library)->ft_standard_raster)
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __RASTPIC_H__ */
+
+
+/* END */
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 142ef76..1097efb 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -17,12 +17,14 @@
 
 
 #include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_SFNT_H
 #include FT_INTERNAL_OBJECTS_H
 
 #include "sfdriver.h"
 #include "ttload.h"
 #include "sfobjs.h"
+#include "sfntpic.h"
 
 #include "sferrors.h"
 
@@ -48,6 +50,15 @@
 #include FT_SERVICE_SFNT_H
 #include FT_SERVICE_TT_CMAP_H
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_sfdriver
+
 
  /*
   *  SFNT TABLE SERVICE
@@ -103,27 +114,28 @@
   sfnt_table_info( TT_Face    face,
                    FT_UInt    idx,
                    FT_ULong  *tag,
+                   FT_ULong  *offset,
                    FT_ULong  *length )
   {
-    if ( !tag || !length )
+    if ( !tag || !offset || !length )
       return SFNT_Err_Invalid_Argument;
 
     if ( idx >= face->num_tables )
       return SFNT_Err_Table_Missing;
 
     *tag    = face->dir_tables[idx].Tag;
+    *offset = face->dir_tables[idx].Offset;
     *length = face->dir_tables[idx].Length;
 
     return SFNT_Err_Ok;
   }
 
 
-  static const FT_Service_SFNT_TableRec  sfnt_service_sfnt_table =
-  {
+  FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table,
     (FT_SFNT_TableLoadFunc)tt_face_load_any,
     (FT_SFNT_TableGetFunc) get_sfnt_table,
     (FT_SFNT_TableInfoFunc)sfnt_table_info
-  };
+  )
 
 
 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
@@ -155,11 +167,19 @@
   sfnt_get_name_index( TT_Face     face,
                        FT_String*  glyph_name )
   {
-    FT_Face  root = &face->root;
-    FT_Long  i;
+    FT_Face   root = &face->root;
+    FT_UInt   i, max_gid = FT_UINT_MAX;
 
 
-    for ( i = 0; i < root->num_glyphs; i++ )
+    if ( root->num_glyphs < 0 )
+      return 0;
+    else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX )
+      max_gid = ( FT_UInt ) root->num_glyphs;
+    else
+      FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
+         FT_UINT_MAX, root->num_glyphs ));
+
+    for ( i = 0; i < max_gid; i++ )
     {
       FT_String*  gname;
       FT_Error    error = tt_face_get_ps_name( face, i, &gname );
@@ -169,18 +189,17 @@
         continue;
 
       if ( !ft_strcmp( glyph_name, gname ) )
-        return (FT_UInt)i;
+        return i;
     }
 
     return 0;
   }
 
 
-  static const FT_Service_GlyphDictRec  sfnt_service_glyph_dict =
-  {
+  FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict,
     (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,
     (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index
-  };
+  )
 
 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
@@ -300,19 +319,17 @@
     return result;
   }
 
-  static const FT_Service_PsFontNameRec  sfnt_service_ps_name =
-  {
+  FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name,
     (FT_PsName_GetFunc)sfnt_get_ps_name
-  };
+  )
 
 
   /*
    *  TT CMAP INFO
    */
-  static const FT_Service_TTCMapsRec  tt_service_get_cmap_info =
-  {
+  FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info,
     (TT_CMap_Info_GetFunc)tt_get_cmap_info
-  };
+  )
 
 
 #ifdef TT_CONFIG_OPTION_BDF
@@ -353,11 +370,10 @@
   }
 
 
-  static const FT_Service_BDFRec  sfnt_service_bdf =
-  {
+  FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf,
     (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
-    (FT_BDF_GetPropertyFunc)  tt_face_find_bdf_prop,
-  };
+    (FT_BDF_GetPropertyFunc)  tt_face_find_bdf_prop
+  )
 
 #endif /* TT_CONFIG_OPTION_BDF */
 
@@ -366,20 +382,35 @@
    *  SERVICE LIST
    */
 
-  static const FT_ServiceDescRec  sfnt_services[] =
-  {
-    { FT_SERVICE_ID_SFNT_TABLE,           &sfnt_service_sfnt_table },
-    { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name },
-#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
-    { FT_SERVICE_ID_GLYPH_DICT,           &sfnt_service_glyph_dict },
+#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
+  FT_DEFINE_SERVICEDESCREC5(sfnt_services,
+    FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,
+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
+    FT_SERVICE_ID_GLYPH_DICT,           &FT_SFNT_SERVICE_GLYPH_DICT_GET,
+    FT_SERVICE_ID_BDF,                  &FT_SFNT_SERVICE_BDF_GET,
+    FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET
+  )
+#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+  FT_DEFINE_SERVICEDESCREC4(sfnt_services,
+    FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,
+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
+    FT_SERVICE_ID_GLYPH_DICT,           &FT_SFNT_SERVICE_GLYPH_DICT_GET,
+    FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET
+  )
+#elif defined TT_CONFIG_OPTION_BDF
+  FT_DEFINE_SERVICEDESCREC4(sfnt_services,
+    FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,
+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
+    FT_SERVICE_ID_BDF,                  &FT_SFNT_SERVICE_BDF_GET,
+    FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET
+  )
+#else
+  FT_DEFINE_SERVICEDESCREC3(sfnt_services,
+    FT_SERVICE_ID_SFNT_TABLE,           &FT_SFNT_SERVICE_SFNT_TABLE_GET,
+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
+    FT_SERVICE_ID_TT_CMAP,              &FT_TT_SERVICE_GET_CMAP_INFO_GET
+  )
 #endif
-#ifdef TT_CONFIG_OPTION_BDF
-    { FT_SERVICE_ID_BDF,                  &sfnt_service_bdf },
-#endif
-    { FT_SERVICE_ID_TT_CMAP,              &tt_service_get_cmap_info },
-
-    { NULL, NULL }
-  };
 
 
   FT_CALLBACK_DEF( FT_Module_Interface )
@@ -388,7 +419,7 @@
   {
     FT_UNUSED( module );
 
-    return ft_service_list_lookup( sfnt_services, module_interface );
+    return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface );
   }
 
 
@@ -519,10 +550,18 @@
 
 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
 
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+#define PUT_EMBEDDED_BITMAPS(a) a 
+#else
+#define PUT_EMBEDDED_BITMAPS(a) 0 
+#endif
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+#define PUT_PS_NAMES(a) a 
+#else
+#define PUT_PS_NAMES(a) 0 
+#endif
 
-  static
-  const SFNT_Interface  sfnt_interface =
-  {
+  FT_DEFINE_SFNT_INTERFACE(sfnt_interface,
     tt_face_goto_table,
 
     sfnt_init_face,
@@ -532,10 +571,8 @@
 
     tt_face_load_any,
 
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-    tt_face_load_sfnt_header_stub,
-    tt_face_load_directory_stub,
-#endif
+    tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+    tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
 
     tt_face_load_head,
     tt_face_load_hhea,
@@ -547,53 +584,32 @@
     tt_face_load_name,
     tt_face_free_name,
 
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-    tt_face_load_hdmx_stub,
-    tt_face_free_hdmx_stub,
-#endif
+    tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+    tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
 
     tt_face_load_kern,
     tt_face_load_gasp,
     tt_face_load_pclt,
 
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
     /* see `ttload.h' */
-    tt_face_load_bhed,
-#else
-    0,
-#endif
+    PUT_EMBEDDED_BITMAPS(tt_face_load_bhed),
 
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-    tt_face_set_sbit_strike_stub,
-    tt_face_load_sbit_stub,
+    tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+    tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
 
-    tt_find_sbit_image,
-    tt_load_sbit_metrics,
-#endif
+    tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+    tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */
 
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-    tt_face_load_sbit_image,
-#else
-    0,
-#endif
+    PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image),
 
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-    tt_face_free_sbit_stub,
-#endif
+    tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
 
-#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
     /* see `ttpost.h' */
-    tt_face_get_ps_name,
-    tt_face_free_ps_names,
-#else
-    0,
-    0,
-#endif
+    PUT_PS_NAMES(tt_face_get_ps_name),
+    PUT_PS_NAMES(tt_face_free_ps_names),
 
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-    tt_face_load_charmap_stub,
-    tt_face_free_charmap_stub,
-#endif
+    tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
+    tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
 
     /* since version 2.1.8 */
 
@@ -604,27 +620,19 @@
     tt_face_load_font_dir,
     tt_face_load_hmtx,
 
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
     /* see `ttsbit.h' and `sfnt.h' */
-    tt_face_load_eblc,
-    tt_face_free_eblc,
+    PUT_EMBEDDED_BITMAPS(tt_face_load_eblc),
+    PUT_EMBEDDED_BITMAPS(tt_face_free_eblc),
 
-    tt_face_set_sbit_strike,
-    tt_face_load_strike_metrics,
-#else
-    0,
-    0,
-    0,
-    0,
-#endif
+    PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike),
+    PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics),
 
     tt_face_get_metrics
-  };
+  )
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Module_Class  sfnt_module_class =
-  {
+  FT_DEFINE_MODULE(sfnt_module_class,
+  
     0,  /* not a font driver or renderer */
     sizeof( FT_ModuleRec ),
 
@@ -632,12 +640,12 @@
     0x10000L,   /* driver version 1.0                     */
     0x20000L,   /* driver requires FreeType 2.0 or higher */
 
-    (const void*)&sfnt_interface,  /* module specific interface */
+    (const void*)&FT_SFNT_INTERFACE_GET,  /* module specific interface */
 
     (FT_Module_Constructor)0,
     (FT_Module_Destructor) 0,
     (FT_Module_Requester)  sfnt_get_interface
-  };
+  )
 
 
 /* END */
diff --git a/src/sfnt/sfdriver.h b/src/sfnt/sfdriver.h
index 92db796..5de25d5 100644
--- a/src/sfnt/sfdriver.h
+++ b/src/sfnt/sfdriver.h
@@ -27,7 +27,7 @@
 FT_BEGIN_HEADER
 
 
-  FT_EXPORT_VAR( const FT_Module_Class )  sfnt_module_class;
+  FT_DECLARE_MODULE( sfnt_module_class )
 
 
 FT_END_HEADER
diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c
index 45a820b..fc507b4 100644
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfnt.c
@@ -19,6 +19,7 @@
 #define FT_MAKE_OPTION_SINGLE_OBJECT
 
 #include <ft2build.h>
+#include "sfntpic.c"
 #include "ttload.c"
 #include "ttmtx.c"
 #include "ttcmap.c"
diff --git a/src/sfnt/sfntpic.c b/src/sfnt/sfntpic.c
new file mode 100644
index 0000000..fd3cf4e
--- /dev/null
+++ b/src/sfnt/sfntpic.c
@@ -0,0 +1,101 @@
+/***************************************************************************/
+/*                                                                         */
+/*  sfntpic.c                                                              */
+/*                                                                         */
+/*    The FreeType position independent code services for sfnt module.     */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_INTERNAL_OBJECTS_H
+#include "sfntpic.h"
+
+#ifdef FT_CONFIG_OPTION_PIC
+
+  /* forward declaration of PIC init functions from sfdriver.c */
+  FT_Error FT_Create_Class_sfnt_services( FT_Library, FT_ServiceDescRec**);
+  void FT_Destroy_Class_sfnt_services( FT_Library, FT_ServiceDescRec*);
+  void FT_Init_Class_sfnt_service_bdf( FT_Service_BDFRec*);
+  void FT_Init_Class_sfnt_interface( FT_Library, SFNT_Interface*);
+  void FT_Init_Class_sfnt_service_glyph_dict( FT_Library, FT_Service_GlyphDictRec*);
+  void FT_Init_Class_sfnt_service_ps_name( FT_Library, FT_Service_PsFontNameRec*);
+  void FT_Init_Class_tt_service_get_cmap_info( FT_Library, FT_Service_TTCMapsRec*);
+  void FT_Init_Class_sfnt_service_sfnt_table( FT_Service_SFNT_TableRec*);
+
+  /* forward declaration of PIC init functions from ttcmap.c */
+  FT_Error FT_Create_Class_tt_cmap_classes( FT_Library, TT_CMap_Class**);
+  void FT_Destroy_Class_tt_cmap_classes( FT_Library, TT_CMap_Class*);
+
+  void
+  sfnt_module_class_pic_free(  FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Memory memory = library->memory;
+    if ( pic_container->sfnt )
+    {
+      sfntModulePIC* container = (sfntModulePIC*)pic_container->sfnt;
+      if(container->sfnt_services)
+        FT_Destroy_Class_sfnt_services(library, container->sfnt_services);
+      container->sfnt_services = NULL;
+      if(container->tt_cmap_classes)
+        FT_Destroy_Class_tt_cmap_classes(library, container->tt_cmap_classes);
+      container->tt_cmap_classes = NULL;
+      FT_FREE( container );
+      pic_container->sfnt = NULL;
+    }
+  }
+
+
+  FT_Error
+  sfnt_module_class_pic_init(  FT_Library library )
+  {
+    FT_PIC_Container* pic_container = &library->pic_container;
+    FT_Error        error = FT_Err_Ok;
+    sfntModulePIC* container;
+    FT_Memory memory = library->memory;
+
+    /* allocate pointer, clear and set global container pointer */
+    if ( FT_ALLOC ( container, sizeof ( *container ) ) )
+      return error;
+    FT_MEM_SET( container, 0, sizeof(*container) );
+    pic_container->sfnt = container;
+
+    /* initialize pointer table - this is how the module usually expects this data */
+    error = FT_Create_Class_sfnt_services(library, &container->sfnt_services);
+    if(error) 
+      goto Exit;
+    error = FT_Create_Class_tt_cmap_classes(library, &container->tt_cmap_classes);
+    if(error) 
+      goto Exit;
+    FT_Init_Class_sfnt_service_glyph_dict(library, &container->sfnt_service_glyph_dict);
+    FT_Init_Class_sfnt_service_ps_name(library, &container->sfnt_service_ps_name);
+    FT_Init_Class_tt_service_get_cmap_info(library, &container->tt_service_get_cmap_info);
+    FT_Init_Class_sfnt_service_sfnt_table(&container->sfnt_service_sfnt_table);
+#ifdef TT_CONFIG_OPTION_BDF
+    FT_Init_Class_sfnt_service_bdf(&container->sfnt_service_bdf);
+#endif
+    FT_Init_Class_sfnt_interface(library, &container->sfnt_interface);
+
+Exit:
+    if(error)
+      sfnt_module_class_pic_free(library);
+    return error;
+  }
+
+
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+
+/* END */
diff --git a/src/sfnt/sfntpic.h b/src/sfnt/sfntpic.h
new file mode 100644
index 0000000..6943b42
--- /dev/null
+++ b/src/sfnt/sfntpic.h
@@ -0,0 +1,88 @@
+/***************************************************************************/
+/*                                                                         */
+/*  sfntpic.h                                                              */
+/*                                                                         */
+/*    The FreeType position independent code services for sfnt module.     */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __SFNTPIC_H__
+#define __SFNTPIC_H__
+
+  
+FT_BEGIN_HEADER
+
+#include FT_INTERNAL_PIC_H
+
+ #ifndef FT_CONFIG_OPTION_PIC
+#define FT_SFNT_SERVICES_GET             sfnt_services
+#define FT_SFNT_SERVICE_GLYPH_DICT_GET   sfnt_service_glyph_dict
+#define FT_SFNT_SERVICE_PS_NAME_GET      sfnt_service_ps_name
+#define FT_TT_SERVICE_GET_CMAP_INFO_GET  tt_service_get_cmap_info
+#define FT_SFNT_SERVICES_GET             sfnt_services
+#define FT_TT_CMAP_CLASSES_GET           tt_cmap_classes
+#define FT_SFNT_SERVICE_SFNT_TABLE_GET   sfnt_service_sfnt_table
+#define FT_SFNT_SERVICE_BDF_GET          sfnt_service_bdf
+#define FT_SFNT_INTERFACE_GET            sfnt_interface
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+/* some include files required for members of sfntModulePIC */
+#include FT_SERVICE_GLYPH_DICT_H
+#include FT_SERVICE_POSTSCRIPT_NAME_H
+#include FT_SERVICE_SFNT_H
+#include FT_SERVICE_TT_CMAP_H
+#ifdef TT_CONFIG_OPTION_BDF
+#include "ttbdf.h"
+#include FT_SERVICE_BDF_H
+#endif
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_SFNT_H
+#include "ttcmap.h"
+
+typedef struct sfntModulePIC_
+  {
+    FT_ServiceDescRec* sfnt_services;
+    FT_Service_GlyphDictRec sfnt_service_glyph_dict;
+    FT_Service_PsFontNameRec  sfnt_service_ps_name;
+    FT_Service_TTCMapsRec  tt_service_get_cmap_info;
+    TT_CMap_Class* tt_cmap_classes;
+    FT_Service_SFNT_TableRec sfnt_service_sfnt_table;
+#ifdef TT_CONFIG_OPTION_BDF
+    FT_Service_BDFRec sfnt_service_bdf;
+#endif
+    SFNT_Interface sfnt_interface;
+  } sfntModulePIC;
+
+#define GET_PIC(lib)                      ((sfntModulePIC*)((lib)->pic_container.sfnt))
+#define FT_SFNT_SERVICES_GET              (GET_PIC(library)->sfnt_services)
+#define FT_SFNT_SERVICE_GLYPH_DICT_GET    (GET_PIC(library)->sfnt_service_glyph_dict)
+#define FT_SFNT_SERVICE_PS_NAME_GET       (GET_PIC(library)->sfnt_service_ps_name)
+#define FT_TT_SERVICE_GET_CMAP_INFO_GET   (GET_PIC(library)->tt_service_get_cmap_info)
+#define FT_SFNT_SERVICES_GET              (GET_PIC(library)->sfnt_services)
+#define FT_TT_CMAP_CLASSES_GET            (GET_PIC(library)->tt_cmap_classes)
+#define FT_SFNT_SERVICE_SFNT_TABLE_GET    (GET_PIC(library)->sfnt_service_sfnt_table)
+#define FT_SFNT_SERVICE_BDF_GET           (GET_PIC(library)->sfnt_service_bdf)
+#define FT_SFNT_INTERFACE_GET             (GET_PIC(library)->sfnt_interface)
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+/* */
+
+FT_END_HEADER
+
+#endif /* __SFNTPIC_H__ */
+
+
+/* END */
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index c826b92..b74b1a9 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -26,6 +26,7 @@
 #include FT_TRUETYPE_IDS_H
 #include FT_TRUETYPE_TAGS_H
 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
+#include FT_SFNT_NAMES_H
 #include "sferrors.h"
 
 #ifdef TT_CONFIG_OPTION_BDF
@@ -527,13 +528,27 @@
 #endif
     FT_Bool       has_outline;
     FT_Bool       is_apple_sbit;
+    FT_Bool       ignore_preferred_family = FALSE;
+    FT_Bool       ignore_preferred_subfamily = FALSE;
 
     SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
 
     FT_UNUSED( face_index );
-    FT_UNUSED( num_params );
-    FT_UNUSED( params );
 
+    /* Check parameters */
+    
+    {
+      FT_Int  i;
+
+
+      for ( i = 0; i < num_params; i++ )
+      {
+        if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY )
+          ignore_preferred_family = TRUE;
+        else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY )
+          ignore_preferred_subfamily = TRUE;
+      }
+    }
 
     /* Load tables */
 
@@ -722,26 +737,30 @@
     /* Foundation (WPF).  This flag has been introduced in version   */
     /* 1.5 of the OpenType specification (May 2008).                 */
 
+    face->root.family_name = NULL;
+    face->root.style_name  = NULL;
     if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )
     {
-      GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
+      if ( !ignore_preferred_family )
+        GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
       if ( !face->root.family_name )
         GET_NAME( FONT_FAMILY, &face->root.family_name );
 
-      GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
+      if ( !ignore_preferred_subfamily )
+        GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
       if ( !face->root.style_name )
         GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
     }
     else
     {
       GET_NAME( WWS_FAMILY, &face->root.family_name );
-      if ( !face->root.family_name )
+      if ( !face->root.family_name && !ignore_preferred_family )
         GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
       if ( !face->root.family_name )
         GET_NAME( FONT_FAMILY, &face->root.family_name );
 
       GET_NAME( WWS_SUBFAMILY, &face->root.style_name );
-      if ( !face->root.style_name )
+      if ( !face->root.style_name && !ignore_preferred_subfamily )
         GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
       if ( !face->root.style_name )
         GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
@@ -749,8 +768,8 @@
 
     /* now set up root fields */
     {
-      FT_Face   root  = &face->root;
-      FT_Int32  flags = root->face_flags;
+      FT_Face  root  = &face->root;
+      FT_Long  flags = root->face_flags;
 
 
       /*********************************************************************/
diff --git a/src/sfnt/ttbdf.c b/src/sfnt/ttbdf.c
index 6c95387..206cece 100644
--- a/src/sfnt/ttbdf.c
+++ b/src/sfnt/ttbdf.c
@@ -84,7 +84,7 @@
       FT_Byte*   p           = bdf->table;
       FT_UInt    version     = FT_NEXT_USHORT( p );
       FT_UInt    num_strikes = FT_NEXT_USHORT( p );
-      FT_UInt32  strings     = FT_NEXT_ULONG ( p );
+      FT_ULong   strings     = FT_NEXT_ULONG ( p );
       FT_UInt    count;
       FT_Byte*   strike;
 
@@ -141,13 +141,13 @@
                          const char*       property_name,
                          BDF_PropertyRec  *aprop )
   {
-    TT_BDF    bdf   = &face->bdf;
-    FT_Size   size  = FT_FACE(face)->size;
-    FT_Error  error = 0;
-    FT_Byte*  p;
-    FT_UInt   count;
-    FT_Byte*  strike;
-    FT_UInt   property_len;
+    TT_BDF     bdf   = &face->bdf;
+    FT_Size    size  = FT_FACE(face)->size;
+    FT_Error   error = 0;
+    FT_Byte*   p;
+    FT_UInt    count;
+    FT_Byte*   strike;
+    FT_Offset  property_len;
 
 
     aprop->type = BDF_PROPERTY_TYPE_NONE;
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index 6830391..b283f6d 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -25,6 +25,7 @@
 #include FT_INTERNAL_STREAM_H
 #include "ttload.h"
 #include "ttcmap.h"
+#include "sfntpic.h"
 
 
   /*************************************************************************/
@@ -124,7 +125,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   tt_cmap0_char_next( TT_CMap     cmap,
                       FT_UInt32  *pchar_code )
   {
@@ -157,17 +158,14 @@
     FT_Byte*  p = cmap->data + 4;
 
 
-    cmap_info->format = 0;
+    cmap_info->format   = 0;
     cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
 
     return SFNT_Err_Ok;
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const TT_CMap_ClassRec  tt_cmap0_class_rec =
-  {
-    {
+  FT_DEFINE_TT_CMAP(tt_cmap0_class_rec,
       sizeof ( TT_CMapRec ),
 
       (FT_CMap_InitFunc)     tt_cmap_init,
@@ -176,11 +174,11 @@
       (FT_CMap_CharNextFunc) tt_cmap0_char_next,
 
       NULL, NULL, NULL, NULL, NULL
-    },
+    ,
     0,
     (TT_CMap_ValidateFunc)   tt_cmap0_validate,
     (TT_CMap_Info_GetFunc)   tt_cmap0_get_info
-  };
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_0 */
 
@@ -462,7 +460,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   tt_cmap2_char_next( TT_CMap     cmap,
                       FT_UInt32  *pcharcode )
   {
@@ -536,17 +534,14 @@
     FT_Byte*  p = cmap->data + 4;
 
 
-    cmap_info->format = 2;
+    cmap_info->format   = 2;
     cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
 
     return SFNT_Err_Ok;
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const TT_CMap_ClassRec  tt_cmap2_class_rec =
-  {
-    {
+  FT_DEFINE_TT_CMAP(tt_cmap2_class_rec,
       sizeof ( TT_CMapRec ),
 
       (FT_CMap_InitFunc)     tt_cmap_init,
@@ -555,11 +550,11 @@
       (FT_CMap_CharNextFunc) tt_cmap2_char_next,
 
       NULL, NULL, NULL, NULL, NULL
-    },
+    ,
     2,
     (TT_CMap_ValidateFunc)   tt_cmap2_validate,
     (TT_CMap_Info_GetFunc)   tt_cmap2_get_info
-  };
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_2 */
 
@@ -664,7 +659,7 @@
 
     p                  = table + 6;
     cmap->num_ranges   = FT_PEEK_USHORT( p ) >> 1;
-    cmap->cur_charcode = 0xFFFFFFFFUL;
+    cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
     cmap->cur_gindex   = 0;
 
     return SFNT_Err_Ok;
@@ -742,7 +737,7 @@
     if ( cmap->cur_charcode >= 0xFFFFUL )
       goto Fail;
 
-    charcode = cmap->cur_charcode + 1;
+    charcode = (FT_UInt)cmap->cur_charcode + 1;
 
     if ( charcode < cmap->cur_start )
       charcode = cmap->cur_start;
@@ -804,7 +799,7 @@
     }
 
   Fail:
-    cmap->cur_charcode = 0xFFFFFFFFUL;
+    cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
     cmap->cur_gindex   = 0;
   }
 
@@ -1093,7 +1088,7 @@
     FT_UInt   num_segs2, start, end, offset;
     FT_Int    delta;
     FT_UInt   max, min, mid, num_segs;
-    FT_UInt   charcode = *pcharcode;
+    FT_UInt   charcode = (FT_UInt)*pcharcode;
     FT_UInt   gindex   = 0;
     FT_Byte*  p;
 
@@ -1335,7 +1330,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   tt_cmap4_char_next( TT_CMap     cmap,
                       FT_UInt32  *pchar_code )
   {
@@ -1375,17 +1370,14 @@
     FT_Byte*  p = cmap->data + 4;
 
 
-    cmap_info->format = 4;
+    cmap_info->format   = 4;
     cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
 
     return SFNT_Err_Ok;
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const TT_CMap_ClassRec  tt_cmap4_class_rec =
-  {
-    {
+  FT_DEFINE_TT_CMAP(tt_cmap4_class_rec,
       sizeof ( TT_CMap4Rec ),
       (FT_CMap_InitFunc)     tt_cmap4_init,
       (FT_CMap_DoneFunc)     NULL,
@@ -1393,11 +1385,11 @@
       (FT_CMap_CharNextFunc) tt_cmap4_char_next,
 
       NULL, NULL, NULL, NULL, NULL
-    },
+    ,
     4,
     (TT_CMap_ValidateFunc)   tt_cmap4_validate,
     (TT_CMap_Info_GetFunc)   tt_cmap4_get_info
-  };
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_4 */
 
@@ -1489,7 +1481,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   tt_cmap6_char_next( TT_CMap     cmap,
                       FT_UInt32  *pchar_code )
   {
@@ -1537,17 +1529,14 @@
     FT_Byte*  p = cmap->data + 4;
 
 
-    cmap_info->format = 6;
+    cmap_info->format   = 6;
     cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p );
 
     return SFNT_Err_Ok;
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const TT_CMap_ClassRec  tt_cmap6_class_rec =
-  {
-    {
+  FT_DEFINE_TT_CMAP(tt_cmap6_class_rec,
       sizeof ( TT_CMapRec ),
 
       (FT_CMap_InitFunc)     tt_cmap_init,
@@ -1556,11 +1545,11 @@
       (FT_CMap_CharNextFunc) tt_cmap6_char_next,
 
       NULL, NULL, NULL, NULL, NULL
-    },
+    ,
     6,
     (TT_CMap_ValidateFunc)   tt_cmap6_validate,
     (TT_CMap_Info_GetFunc)   tt_cmap6_get_info
-  };
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_6 */
 
@@ -1635,7 +1624,7 @@
       FT_INVALID_TOO_SHORT;
 
     length = TT_NEXT_ULONG( p );
-    if ( table + length > valid->limit || length < 8208 )
+    if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 )
       FT_INVALID_TOO_SHORT;
 
     is32       = table + 12;
@@ -1745,7 +1734,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   tt_cmap8_char_next( TT_CMap     cmap,
                       FT_UInt32  *pchar_code )
   {
@@ -1793,17 +1782,14 @@
     FT_Byte*  p = cmap->data + 8;
 
 
-    cmap_info->format = 8;
+    cmap_info->format   = 8;
     cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
 
     return SFNT_Err_Ok;
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const TT_CMap_ClassRec  tt_cmap8_class_rec =
-  {
-    {
+  FT_DEFINE_TT_CMAP(tt_cmap8_class_rec,
       sizeof ( TT_CMapRec ),
 
       (FT_CMap_InitFunc)     tt_cmap_init,
@@ -1812,11 +1798,11 @@
       (FT_CMap_CharNextFunc) tt_cmap8_char_next,
 
       NULL, NULL, NULL, NULL, NULL
-    },
+    ,
     8,
     (TT_CMap_ValidateFunc)   tt_cmap8_validate,
     (TT_CMap_Info_GetFunc)   tt_cmap8_get_info
-  };
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_8 */
 
@@ -1863,7 +1849,8 @@
     p      = table + 16;
     count  = TT_NEXT_ULONG( p );
 
-    if ( table + length > valid->limit || length < 20 + count * 2 )
+    if ( length > (FT_ULong)( valid->limit - table ) ||
+         length < 20 + count * 2                     )
       FT_INVALID_TOO_SHORT;
 
     /* check glyph indices */
@@ -1905,7 +1892,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   tt_cmap10_char_next( TT_CMap     cmap,
                        FT_UInt32  *pchar_code )
   {
@@ -1944,17 +1931,14 @@
     FT_Byte*  p = cmap->data + 8;
 
 
-    cmap_info->format = 10;
+    cmap_info->format   = 10;
     cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
 
     return SFNT_Err_Ok;
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const TT_CMap_ClassRec  tt_cmap10_class_rec =
-  {
-    {
+  FT_DEFINE_TT_CMAP(tt_cmap10_class_rec,
       sizeof ( TT_CMapRec ),
 
       (FT_CMap_InitFunc)     tt_cmap_init,
@@ -1963,11 +1947,11 @@
       (FT_CMap_CharNextFunc) tt_cmap10_char_next,
 
       NULL, NULL, NULL, NULL, NULL
-    },
+    ,
     10,
     (TT_CMap_ValidateFunc)   tt_cmap10_validate,
     (TT_CMap_Info_GetFunc)   tt_cmap10_get_info
-  };
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_10 */
 
@@ -2048,7 +2032,8 @@
     p          = table + 12;
     num_groups = TT_NEXT_ULONG( p );
 
-    if ( table + length > valid->limit || length < 16 + 12 * num_groups )
+    if ( length > (FT_ULong)( valid->limit - table ) ||
+         length < 16 + 12 * num_groups               )
       FT_INVALID_TOO_SHORT;
 
     /* check groups, they must be in increasing order */
@@ -2225,7 +2210,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   tt_cmap12_char_next( TT_CMap     cmap,
                        FT_UInt32  *pchar_code )
   {
@@ -2243,8 +2228,10 @@
       if ( cmap12->valid )
       {
         gindex = cmap12->cur_gindex;
+
+        /* XXX: check cur_charcode overflow is expected */
         if ( gindex )
-          *pchar_code = cmap12->cur_charcode;
+          *pchar_code = (FT_UInt32)cmap12->cur_charcode;
       }
       else
         gindex = 0;
@@ -2252,7 +2239,8 @@
     else
       gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );
 
-    return gindex;
+    /* XXX: check gindex overflow is expected */
+    return (FT_UInt32)gindex;
   }
 
 
@@ -2263,17 +2251,14 @@
     FT_Byte*  p = cmap->data + 8;
 
 
-    cmap_info->format = 12;
+    cmap_info->format   = 12;
     cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
 
     return SFNT_Err_Ok;
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const TT_CMap_ClassRec  tt_cmap12_class_rec =
-  {
-    {
+  FT_DEFINE_TT_CMAP(tt_cmap12_class_rec,
       sizeof ( TT_CMap12Rec ),
 
       (FT_CMap_InitFunc)     tt_cmap12_init,
@@ -2282,11 +2267,11 @@
       (FT_CMap_CharNextFunc) tt_cmap12_char_next,
 
       NULL, NULL, NULL, NULL, NULL
-    },
+    ,
     12,
     (TT_CMap_ValidateFunc)   tt_cmap12_validate,
     (TT_CMap_Info_GetFunc)   tt_cmap12_get_info
-  };
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_12 */
 
@@ -2294,6 +2279,322 @@
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
+  /*****                          FORMAT 13                            *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* TABLE OVERVIEW                                                        */
+  /* --------------                                                        */
+  /*                                                                       */
+  /*   NAME        OFFSET     TYPE       DESCRIPTION                       */
+  /*                                                                       */
+  /*   format      0          USHORT     must be 13                        */
+  /*   reserved    2          USHORT     reserved                          */
+  /*   length      4          ULONG      length in bytes                   */
+  /*   language    8          ULONG      Mac language code                 */
+  /*   count       12         ULONG      number of groups                  */
+  /*               16                                                      */
+  /*                                                                       */
+  /* This header is followed by `count' groups of the following format:    */
+  /*                                                                       */
+  /*   start       0          ULONG      first charcode                    */
+  /*   end         4          ULONG      last charcode                     */
+  /*   glyphId     8          ULONG      glyph ID for the whole group      */
+  /*                                                                       */
+
+#ifdef TT_CONFIG_CMAP_FORMAT_13
+
+  typedef struct  TT_CMap13Rec_
+  {
+    TT_CMapRec  cmap;
+    FT_Bool     valid;
+    FT_ULong    cur_charcode;
+    FT_UInt     cur_gindex;
+    FT_ULong    cur_group;
+    FT_ULong    num_groups;
+
+  } TT_CMap13Rec, *TT_CMap13;
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  tt_cmap13_init( TT_CMap13  cmap,
+                  FT_Byte*   table )
+  {
+    cmap->cmap.data  = table;
+
+    table           += 12;
+    cmap->num_groups = FT_PEEK_ULONG( table );
+
+    cmap->valid      = 0;
+
+    return SFNT_Err_Ok;
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  tt_cmap13_validate( FT_Byte*      table,
+                      FT_Validator  valid )
+  {
+    FT_Byte*   p;
+    FT_ULong   length;
+    FT_ULong   num_groups;
+
+
+    if ( table + 16 > valid->limit )
+      FT_INVALID_TOO_SHORT;
+
+    p      = table + 4;
+    length = TT_NEXT_ULONG( p );
+
+    p          = table + 12;
+    num_groups = TT_NEXT_ULONG( p );
+
+    if ( length > (FT_ULong)( valid->limit - table ) ||
+         length < 16 + 12 * num_groups               )
+      FT_INVALID_TOO_SHORT;
+
+    /* check groups, they must be in increasing order */
+    {
+      FT_ULong  n, start, end, glyph_id, last = 0;
+
+
+      for ( n = 0; n < num_groups; n++ )
+      {
+        start    = TT_NEXT_ULONG( p );
+        end      = TT_NEXT_ULONG( p );
+        glyph_id = TT_NEXT_ULONG( p );
+
+        if ( start > end )
+          FT_INVALID_DATA;
+
+        if ( n > 0 && start <= last )
+          FT_INVALID_DATA;
+
+        if ( valid->level >= FT_VALIDATE_TIGHT )
+        {
+          if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) )
+            FT_INVALID_GLYPH_ID;
+        }
+
+        last = end;
+      }
+    }
+
+    return SFNT_Err_Ok;
+  }
+
+
+  /* search the index of the charcode next to cmap->cur_charcode */
+  /* cmap->cur_group should be set up properly by caller         */
+  /*                                                             */
+  static void
+  tt_cmap13_next( TT_CMap13  cmap )
+  {
+    FT_Byte*  p;
+    FT_ULong  start, end, glyph_id, char_code;
+    FT_ULong  n;
+    FT_UInt   gindex;
+
+
+    if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
+      goto Fail;
+
+    char_code = cmap->cur_charcode + 1;
+
+    n = cmap->cur_group;
+
+    for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
+    {
+      p        = cmap->cmap.data + 16 + 12 * n;
+      start    = TT_NEXT_ULONG( p );
+      end      = TT_NEXT_ULONG( p );
+      glyph_id = TT_PEEK_ULONG( p );
+
+      if ( char_code < start )
+        char_code = start;
+
+      if ( char_code <= end )
+      {
+        gindex = (FT_UInt)glyph_id;
+
+        if ( gindex )
+        {
+          cmap->cur_charcode = char_code;;
+          cmap->cur_gindex   = gindex;
+          cmap->cur_group    = n;
+
+          return;
+        }
+      }
+    }
+
+  Fail:
+    cmap->valid = 0;
+  }
+
+
+  static FT_UInt
+  tt_cmap13_char_map_binary( TT_CMap     cmap,
+                             FT_UInt32*  pchar_code,
+                             FT_Bool     next )
+  {
+    FT_UInt    gindex     = 0;
+    FT_Byte*   p          = cmap->data + 12;
+    FT_UInt32  num_groups = TT_PEEK_ULONG( p );
+    FT_UInt32  char_code  = *pchar_code;
+    FT_UInt32  start, end;
+    FT_UInt32  max, min, mid;
+
+
+    if ( !num_groups )
+      return 0;
+
+    /* make compiler happy */
+    mid = num_groups;
+    end = 0xFFFFFFFFUL;
+
+    if ( next )
+      char_code++;
+
+    min = 0;
+    max = num_groups;
+
+    /* binary search */
+    while ( min < max )
+    {
+      mid = ( min + max ) >> 1;
+      p   = cmap->data + 16 + 12 * mid;
+
+      start = TT_NEXT_ULONG( p );
+      end   = TT_NEXT_ULONG( p );
+
+      if ( char_code < start )
+        max = mid;
+      else if ( char_code > end )
+        min = mid + 1;
+      else
+      {
+        gindex = (FT_UInt)TT_PEEK_ULONG( p );
+
+        break;
+      }
+    }
+
+    if ( next )
+    {
+      TT_CMap13  cmap13 = (TT_CMap13)cmap;
+
+
+      /* if `char_code' is not in any group, then `mid' is */
+      /* the group nearest to `char_code'                  */
+      /*                                                   */
+
+      if ( char_code > end )
+      {
+        mid++;
+        if ( mid == num_groups )
+          return 0;
+      }
+
+      cmap13->valid        = 1;
+      cmap13->cur_charcode = char_code;
+      cmap13->cur_group    = mid;
+
+      if ( !gindex )
+      {
+        tt_cmap13_next( cmap13 );
+
+        if ( cmap13->valid )
+          gindex = cmap13->cur_gindex;
+      }
+      else
+        cmap13->cur_gindex = gindex;
+
+      if ( gindex )
+        *pchar_code = cmap13->cur_charcode;
+    }
+
+    return gindex;
+  }
+
+
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap13_char_index( TT_CMap    cmap,
+                        FT_UInt32  char_code )
+  {
+    return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
+  }
+
+
+  FT_CALLBACK_DEF( FT_UInt32 )
+  tt_cmap13_char_next( TT_CMap     cmap,
+                       FT_UInt32  *pchar_code )
+  {
+    TT_CMap13  cmap13 = (TT_CMap13)cmap;
+    FT_UInt    gindex;
+
+
+    if ( cmap13->cur_charcode >= 0xFFFFFFFFUL )
+      return 0;
+
+    /* no need to search */
+    if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
+    {
+      tt_cmap13_next( cmap13 );
+      if ( cmap13->valid )
+      {
+        gindex = cmap13->cur_gindex;
+        if ( gindex )
+          *pchar_code = cmap13->cur_charcode;
+      }
+      else
+        gindex = 0;
+    }
+    else
+      gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
+
+    return gindex;
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  tt_cmap13_get_info( TT_CMap       cmap,
+                      TT_CMapInfo  *cmap_info )
+  {
+    FT_Byte*  p = cmap->data + 8;
+
+
+    cmap_info->format   = 13;
+    cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p );
+
+    return SFNT_Err_Ok;
+  }
+
+
+  FT_DEFINE_TT_CMAP(tt_cmap13_class_rec,
+      sizeof ( TT_CMap13Rec ),
+
+      (FT_CMap_InitFunc)     tt_cmap13_init,
+      (FT_CMap_DoneFunc)     NULL,
+      (FT_CMap_CharIndexFunc)tt_cmap13_char_index,
+      (FT_CMap_CharNextFunc) tt_cmap13_char_next,
+
+      NULL, NULL, NULL, NULL, NULL
+    ,
+    13,
+    (TT_CMap_ValidateFunc)   tt_cmap13_validate,
+    (TT_CMap_Info_GetFunc)   tt_cmap13_get_info
+  )
+
+#endif /* TT_CONFIG_CMAP_FORMAT_13 */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
   /*****                           FORMAT 14                           *****/
   /*****                                                               *****/
   /*************************************************************************/
@@ -2363,7 +2664,7 @@
      * cmap 14 query functions.  The data is overwritten
      * on each call to these functions.
      */
-    FT_UInt     max_results;
+    FT_UInt32   max_results;
     FT_UInt32*  results;
     FT_Memory   memory;
 
@@ -2384,10 +2685,10 @@
 
   static FT_Error
   tt_cmap14_ensure( TT_CMap14  cmap,
-                    FT_UInt    num_results,
+                    FT_UInt32  num_results,
                     FT_Memory  memory )
   {
-    FT_UInt   old_max = cmap->max_results;
+    FT_UInt32 old_max = cmap->max_results;
     FT_Error  error   = 0;
 
 
@@ -2429,7 +2730,8 @@
     FT_ULong  num_selectors = TT_NEXT_ULONG( p );
 
 
-    if ( table + length > valid->limit || length < 10 + 11 * num_selectors )
+    if ( length > (FT_ULong)( valid->limit - table ) ||
+         length < 10 + 11 * num_selectors            )
       FT_INVALID_TOO_SHORT;
 
     /* check selectors, they must be in increasing order */
@@ -2491,7 +2793,7 @@
           FT_ULong  i, lastUni = 0;
 
 
-          if ( ndp + numMappings * 4 > valid->limit )
+          if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) )
             FT_INVALID_TOO_SHORT;
 
           for ( i = 0; i < numMappings; ++i )
@@ -2532,7 +2834,7 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt )
+  FT_CALLBACK_DEF( FT_UInt32 )
   tt_cmap14_char_next( TT_CMap     cmap,
                        FT_UInt32  *pchar_code )
   {
@@ -2550,7 +2852,7 @@
   {
     FT_UNUSED( cmap );
 
-    cmap_info->format = 14;
+    cmap_info->format   = 14;
     /* subtable 14 does not define a language field */
     cmap_info->language = 0xFFFFFFFFUL;
 
@@ -2610,7 +2912,7 @@
     {
       FT_UInt32  mid = ( min + max ) >> 1;
       FT_Byte*   p   = base + 5 * mid;
-      FT_UInt32  uni = TT_NEXT_UINT24( p );
+      FT_UInt32  uni = (FT_UInt32)TT_NEXT_UINT24( p );
 
 
       if ( char_code < uni )
@@ -2659,10 +2961,10 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap14_char_var_index( TT_CMap   cmap,
-                            TT_CMap   ucmap,
-                            FT_ULong  charcode,
-                            FT_ULong  variantSelector)
+  tt_cmap14_char_var_index( TT_CMap    cmap,
+                            TT_CMap    ucmap,
+                            FT_UInt32  charcode,
+                            FT_UInt32  variantSelector)
   {
     FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
     FT_ULong  defOff;
@@ -2692,9 +2994,9 @@
 
 
   FT_CALLBACK_DEF( FT_Int )
-  tt_cmap14_char_var_isdefault( TT_CMap   cmap,
-                                FT_ULong  charcode,
-                                FT_ULong  variantSelector )
+  tt_cmap14_char_var_isdefault( TT_CMap    cmap,
+                                FT_UInt32  charcode,
+                                FT_UInt32  variantSelector )
   {
     FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
     FT_ULong  defOff;
@@ -2725,10 +3027,10 @@
                       FT_Memory  memory )
   {
     TT_CMap14   cmap14 = (TT_CMap14)cmap;
-    FT_UInt     count  = cmap14->num_selectors;
+    FT_UInt32   count  = cmap14->num_selectors;
     FT_Byte*    p      = cmap->data + 10;
     FT_UInt32*  result;
-    FT_UInt     i;
+    FT_UInt32   i;
 
 
     if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
@@ -2737,7 +3039,7 @@
     result = cmap14->results;
     for ( i = 0; i < count; ++i )
     {
-      result[i] = TT_NEXT_UINT24( p );
+      result[i] = (FT_UInt32)TT_NEXT_UINT24( p );
       p        += 8;
     }
     result[i] = 0;
@@ -2749,10 +3051,10 @@
   FT_CALLBACK_DEF( FT_UInt32 * )
   tt_cmap14_char_variants( TT_CMap    cmap,
                            FT_Memory  memory,
-                           FT_ULong   charCode )
+                           FT_UInt32  charCode )
   {
     TT_CMap14   cmap14 = (TT_CMap14)  cmap;
-    FT_UInt     count  = cmap14->num_selectors;
+    FT_UInt32   count  = cmap14->num_selectors;
     FT_Byte*    p      = cmap->data + 10;
     FT_UInt32*  q;
 
@@ -2787,7 +3089,7 @@
   static FT_UInt
   tt_cmap14_def_char_count( FT_Byte  *p )
   {
-    FT_UInt32  numRanges = TT_NEXT_ULONG( p );
+    FT_UInt32  numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
     FT_UInt    tot       = 0;
 
 
@@ -2814,14 +3116,14 @@
 
 
     cnt       = tt_cmap14_def_char_count( p );
-    numRanges = TT_NEXT_ULONG( p );
+    numRanges = (FT_UInt32)TT_NEXT_ULONG( p );
 
     if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) )
       return NULL;
 
     for ( q = cmap14->results; numRanges > 0; --numRanges )
     {
-      FT_UInt  uni = TT_NEXT_UINT24( p );
+      FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p );
 
 
       cnt = FT_NEXT_BYTE( p ) + 1;
@@ -2849,7 +3151,7 @@
     FT_UInt32  *ret;
 
 
-    numMappings = TT_NEXT_ULONG( p );
+    numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
 
     if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) )
       return NULL;
@@ -2857,7 +3159,7 @@
     ret = cmap14->results;
     for ( i = 0; i < numMappings; ++i )
     {
-      ret[i] = TT_NEXT_UINT24( p );
+      ret[i] = (FT_UInt32)TT_NEXT_UINT24( p );
       p += 2;
     }
     ret[i] = 0;
@@ -2869,7 +3171,7 @@
   FT_CALLBACK_DEF( FT_UInt32 * )
   tt_cmap14_variant_chars( TT_CMap    cmap,
                            FT_Memory  memory,
-                           FT_ULong   variantSelector )
+                           FT_UInt32  variantSelector )
   {
     FT_Byte    *p  = tt_cmap14_find_variant( cmap->data + 6,
                                              variantSelector );
@@ -2911,9 +3213,9 @@
       p  = cmap->data + nondefOff;
       dp = cmap->data + defOff;
 
-      numMappings = TT_NEXT_ULONG( p );
+      numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
       dcnt        = tt_cmap14_def_char_count( dp );
-      numRanges   = TT_NEXT_ULONG( dp );
+      numRanges   = (FT_UInt32)TT_NEXT_ULONG( dp );
 
       if ( numMappings == 0 )
         return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
@@ -2926,10 +3228,10 @@
         return NULL;
 
       ret  = cmap14->results;
-      duni = TT_NEXT_UINT24( dp );
+      duni = (FT_UInt32)TT_NEXT_UINT24( dp );
       dcnt = FT_NEXT_BYTE( dp );
       di   = 1;
-      nuni = TT_NEXT_UINT24( p );
+      nuni = (FT_UInt32)TT_NEXT_UINT24( p );
       p   += 2;
       ni   = 1;
       i    = 0;
@@ -2946,7 +3248,7 @@
           if ( di > numRanges )
             break;
 
-          duni = TT_NEXT_UINT24( dp );
+          duni = (FT_UInt32)TT_NEXT_UINT24( dp );
           dcnt = FT_NEXT_BYTE( dp );
         }
         else
@@ -2959,7 +3261,7 @@
           if ( ni > numMappings )
             break;
 
-          nuni = TT_NEXT_UINT24( p );
+          nuni = (FT_UInt32)TT_NEXT_UINT24( p );
           p += 2;
         }
       }
@@ -2972,7 +3274,7 @@
         ret[i++] = nuni;
         while ( ni < numMappings )
         {
-          ret[i++] = TT_NEXT_UINT24( p );
+          ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );
           p += 2;
           ++ni;
         }
@@ -2987,7 +3289,7 @@
 
         while ( di < numRanges )
         {
-          duni = TT_NEXT_UINT24( dp );
+          duni = (FT_UInt32)TT_NEXT_UINT24( dp );
           dcnt = FT_NEXT_BYTE( dp );
 
           for ( k = 0; k <= dcnt; ++k )
@@ -3003,10 +3305,7 @@
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const TT_CMap_ClassRec  tt_cmap14_class_rec =
-  {
-    {
+  FT_DEFINE_TT_CMAP(tt_cmap14_class_rec,
       sizeof ( TT_CMap14Rec ),
 
       (FT_CMap_InitFunc)     tt_cmap14_init,
@@ -3020,52 +3319,67 @@
       (FT_CMap_VariantListFunc)     tt_cmap14_variants,
       (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
       (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars
-    },
+    ,
     14,
     (TT_CMap_ValidateFunc)tt_cmap14_validate,
     (TT_CMap_Info_GetFunc)tt_cmap14_get_info
-  };
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_14 */
 
 
+#ifndef FT_CONFIG_OPTION_PIC
+
   static const TT_CMap_Class  tt_cmap_classes[] =
   {
-#ifdef TT_CONFIG_CMAP_FORMAT_0
-    &tt_cmap0_class_rec,
-#endif
-
-#ifdef TT_CONFIG_CMAP_FORMAT_2
-    &tt_cmap2_class_rec,
-#endif
-
-#ifdef TT_CONFIG_CMAP_FORMAT_4
-    &tt_cmap4_class_rec,
-#endif
-
-#ifdef TT_CONFIG_CMAP_FORMAT_6
-    &tt_cmap6_class_rec,
-#endif
-
-#ifdef TT_CONFIG_CMAP_FORMAT_8
-    &tt_cmap8_class_rec,
-#endif
-
-#ifdef TT_CONFIG_CMAP_FORMAT_10
-    &tt_cmap10_class_rec,
-#endif
-
-#ifdef TT_CONFIG_CMAP_FORMAT_12
-    &tt_cmap12_class_rec,
-#endif
-
-#ifdef TT_CONFIG_CMAP_FORMAT_14
-    &tt_cmap14_class_rec,
-#endif
-
+#define TTCMAPCITEM(a) &a,
+#include "ttcmapc.h"
     NULL,
   };
 
+#else /*FT_CONFIG_OPTION_PIC*/
+
+  void FT_Destroy_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class* clazz)
+  {
+    FT_Memory memory = library->memory;
+    if ( clazz )
+      FT_FREE( clazz );
+  }
+
+  FT_Error FT_Create_Class_tt_cmap_classes(FT_Library library, TT_CMap_Class** output_class)
+  {
+    TT_CMap_Class*  clazz;
+    TT_CMap_ClassRec* recs;
+    FT_Error          error;
+    FT_Memory memory = library->memory;
+    int i = 0;
+
+#define TTCMAPCITEM(a) i++;
+#include "ttcmapc.h"
+
+    /* allocate enough space for both the pointers +terminator and the class instances */
+    if ( FT_ALLOC( clazz, sizeof(*clazz)*(i+1)+sizeof(TT_CMap_ClassRec)*i ) )
+      return error;
+
+    /* the location of the class instances follows the array of pointers */
+    recs = (TT_CMap_ClassRec*) (((char*)clazz)+(sizeof(*clazz)*(i+1))); 
+    i=0;
+
+#undef TTCMAPCITEM
+#define TTCMAPCITEM(a)           \
+    FT_Init_Class_##a(&recs[i]); \
+    clazz[i] = &recs[i];         \
+    i++;
+#include "ttcmapc.h"
+
+    clazz[i] = NULL;
+
+    *output_class = clazz;
+    return FT_Err_Ok;
+  }
+
+#endif /*FT_CONFIG_OPTION_PIC*/
+
 
   /* parse the `cmap' table and build the corresponding TT_CMap objects */
   /* in the current face                                                */
@@ -3077,6 +3391,8 @@
     FT_Byte*           limit = table + face->cmap_size;
     FT_UInt volatile   num_cmaps;
     FT_Byte* volatile  p     = table;
+    FT_Library         library = FT_FACE_LIBRARY(face);
+    FT_UNUSED(library);
 
 
     if ( p + 4 > limit )
@@ -3086,7 +3402,8 @@
     if ( TT_NEXT_USHORT( p ) != 0 )
     {
       p -= 2;
-      FT_ERROR(( "tt_face_build_cmaps: unsupported `cmap' table format = %d\n",
+      FT_ERROR(( "tt_face_build_cmaps:"
+                 " unsupported `cmap' table format = %d\n",
                  TT_PEEK_USHORT( p ) ));
       return SFNT_Err_Invalid_Table;
     }
@@ -3109,7 +3426,7 @@
       {
         FT_Byte* volatile              cmap   = table + offset;
         volatile FT_UInt               format = TT_PEEK_USHORT( cmap );
-        const TT_CMap_Class* volatile  pclazz = tt_cmap_classes;
+        const TT_CMap_Class* volatile  pclazz = FT_TT_CMAP_CLASSES_GET;
         TT_CMap_Class volatile         clazz;
 
 
@@ -3153,8 +3470,8 @@
             }
             else
             {
-              FT_ERROR(( "tt_face_build_cmaps:" ));
-              FT_ERROR(( " broken cmap sub-table ignored!\n" ));
+              FT_TRACE0(( "tt_face_build_cmaps:"
+                          " broken cmap sub-table ignored\n" ));
             }
             break;
           }
@@ -3162,8 +3479,8 @@
 
         if ( *pclazz == NULL )
         {
-          FT_ERROR(( "tt_face_build_cmaps:" ));
-          FT_ERROR(( " unsupported cmap sub-table ignored!\n" ));
+          FT_TRACE0(( "tt_face_build_cmaps:"
+                      " unsupported cmap sub-table ignored\n" ));
         }
       }
     }
diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h
index a10a3e2..15a4a21 100644
--- a/src/sfnt/ttcmap.h
+++ b/src/sfnt/ttcmap.h
@@ -55,6 +55,46 @@
 
   } TT_CMap_ClassRec;
 
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_,          \
+    char_next_, char_var_index_, char_var_default_, variant_list_,           \
+    charvariant_list_,variantchar_list_,                                     \
+    format_, validate_, get_cmap_info_)                                      \
+  FT_CALLBACK_TABLE_DEF                                                      \
+  const TT_CMap_ClassRec class_ =                                            \
+  {                                                                          \
+    {size_, init_, done_, char_index_,                                       \
+     char_next_, char_var_index_, char_var_default_, variant_list_,          \
+     charvariant_list_, variantchar_list_},                                  \
+    format_, validate_, get_cmap_info_                                       \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */ 
+
+#define FT_DEFINE_TT_CMAP(class_, size_, init_, done_, char_index_,          \
+    char_next_, char_var_index_, char_var_default_, variant_list_,           \
+    charvariant_list_,variantchar_list_,                                     \
+    format_, validate_, get_cmap_info_)                                      \
+  void                                                                       \
+  FT_Init_Class_##class_( TT_CMap_ClassRec*  clazz )                         \
+  {                                                                          \
+    clazz->clazz.size = size_;                                               \
+    clazz->clazz.init = init_;                                               \
+    clazz->clazz.done = done_;                                               \
+    clazz->clazz.char_index = char_index_;                                   \
+    clazz->clazz.char_next = char_next_;                                     \
+    clazz->clazz.char_var_index = char_var_index_;                           \
+    clazz->clazz.char_var_default = char_var_default_;                       \
+    clazz->clazz.variant_list = variant_list_;                               \
+    clazz->clazz.charvariant_list = charvariant_list_;                       \
+    clazz->clazz.variantchar_list = variantchar_list_;                       \
+    clazz->format = format_;                                                 \
+    clazz->validate = validate_;                                             \
+    clazz->get_cmap_info = get_cmap_info_;                                   \
+  } 
+
+#endif /* FT_CONFIG_OPTION_PIC */ 
 
   typedef struct  TT_ValidatorRec_
   {
diff --git a/src/sfnt/ttcmapc.h b/src/sfnt/ttcmapc.h
new file mode 100644
index 0000000..4c9c6a5
--- /dev/null
+++ b/src/sfnt/ttcmapc.h
@@ -0,0 +1,55 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ttcmapc.h                                                              */
+/*                                                                         */
+/*    TT CMAP classes definitions (specification only).                    */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifdef TT_CONFIG_CMAP_FORMAT_0
+    TTCMAPCITEM(tt_cmap0_class_rec)
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_2
+    TTCMAPCITEM(tt_cmap2_class_rec)
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_4
+    TTCMAPCITEM(tt_cmap4_class_rec)
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_6
+    TTCMAPCITEM(tt_cmap6_class_rec)
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_8
+    TTCMAPCITEM(tt_cmap8_class_rec)
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_10
+    TTCMAPCITEM(tt_cmap10_class_rec)
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_12
+    TTCMAPCITEM(tt_cmap12_class_rec)
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_13
+    TTCMAPCITEM(tt_cmap13_class_rec)
+#endif
+
+#ifdef TT_CONFIG_CMAP_FORMAT_14
+    TTCMAPCITEM(tt_cmap14_class_rec)
+#endif
+
+  /* END */
diff --git a/src/sfnt/ttkern.c b/src/sfnt/ttkern.c
index 67d5115..c154080 100644
--- a/src/sfnt/ttkern.c
+++ b/src/sfnt/ttkern.c
@@ -22,7 +22,6 @@
 #include FT_INTERNAL_STREAM_H
 #include FT_TRUETYPE_TAGS_H
 #include "ttkern.h"
-#include "ttload.h"
 
 #include "sferrors.h"
 
@@ -60,14 +59,16 @@
 
     if ( table_size < 4 )  /* the case of a malformed table */
     {
-      FT_ERROR(( "kerning table is too small - ignored\n" ));
+      FT_ERROR(( "tt_face_load_kern:"
+                 " kerning table is too small - ignored\n" ));
       error = SFNT_Err_Table_Missing;
       goto Exit;
     }
 
     if ( FT_FRAME_EXTRACT( table_size, face->kern_table ) )
     {
-      FT_ERROR(( "could not extract kerning table\n" ));
+      FT_ERROR(( "tt_face_load_kern:"
+                 " could not extract kerning table\n" ));
       goto Exit;
     }
 
@@ -86,7 +87,7 @@
     {
       FT_UInt    num_pairs, length, coverage;
       FT_Byte*   p_next;
-      FT_UInt32  mask = 1UL << nn;
+      FT_UInt32  mask = (FT_UInt32)1UL << nn;
 
 
       if ( p + 6 > p_limit )
@@ -125,8 +126,8 @@
        */
       if ( num_pairs > 0 )
       {
-        FT_UInt  count;
-        FT_UInt  old_pair;
+        FT_ULong  count;
+        FT_ULong  old_pair;
 
 
         old_pair = FT_NEXT_ULONG( p );
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index c45a1ed..3ad33bd 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -5,7 +5,7 @@
 /*    Load the basic TrueType tables, i.e., tables that can be either in   */
 /*    TTF or OTF fonts (body).                                             */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by       */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -91,9 +91,9 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     if ( zero_length )
-      FT_TRACE4(( "ignoring empty table!\n" ));
+      FT_TRACE4(( "ignoring empty table\n" ));
     else
-      FT_TRACE4(( "could not find table!\n" ));
+      FT_TRACE4(( "could not find table\n" ));
 #endif
 
     return NULL;
@@ -168,10 +168,10 @@
   check_table_dir( SFNT_Header  sfnt,
                    FT_Stream    stream )
   {
-    FT_Error  error;
-    FT_UInt   nn, valid_entries = 0;
-    FT_UInt   has_head = 0, has_sing = 0, has_meta = 0;
-    FT_ULong  offset = sfnt->offset + 12;
+    FT_Error   error;
+    FT_UShort  nn, valid_entries = 0;
+    FT_UInt    has_head = 0, has_sing = 0, has_meta = 0;
+    FT_ULong   offset = sfnt->offset + 12;
 
     static const FT_Frame_Field  table_dir_entry_fields[] =
     {
@@ -364,7 +364,8 @@
     error = check_table_dir( &sfnt, stream );
     if ( error )
     {
-      FT_TRACE2(( "tt_face_load_font_dir: invalid table directory for TrueType!\n" ));
+      FT_TRACE2(( "tt_face_load_font_dir:"
+                  " invalid table directory for TrueType\n" ));
 
       goto Exit;
     }
@@ -685,8 +686,10 @@
       /* we add 4 phantom points later */
       if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) )
       {
-        FT_ERROR(( "Too much twilight points in `maxp' table;\n" ));
-        FT_ERROR(( "  some glyphs might be rendered incorrectly.\n" ));
+        FT_TRACE0(( "tt_face_load_maxp:"
+                    " too much twilight points in `maxp' table;\n"
+                    "                  "
+                    " some glyphs might be rendered incorrectly\n" ));
 
         maxProfile->maxTwilightPoints = 0xFFFFU - 4;
       }
@@ -779,7 +782,7 @@
 
     if ( storage_start > storage_limit )
     {
-      FT_ERROR(( "invalid `name' table\n" ));
+      FT_ERROR(( "tt_face_load_name: invalid `name' table\n" ));
       error = SFNT_Err_Name_Table_Missing;
       goto Exit;
     }
diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c
index 2a7d22c..53e6ac7 100644
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Load the metrics tables common to TTF and OTF fonts (body).          */
 /*                                                                         */
-/*  Copyright 2006, 2007, 2008 by                                          */
+/*  Copyright 2006, 2007, 2008, 2009 by                                    */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -161,7 +161,9 @@
 
     if ( num_shorts < 0 )
     {
-      FT_ERROR(( "%cmtx has more metrics than glyphs.\n" ));
+      FT_TRACE0(( "tt_face_load_hmtx:"
+                  " %cmtx has more metrics than glyphs.\n",
+                  vertical ? "v" : "h" ));
 
       /* Adobe simply ignores this problem.  So we shall do the same. */
 #if 0
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
index ce628e2..aa0bf1e 100644
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -5,7 +5,7 @@
 /*    Postcript name table processing for TrueType and OpenType fonts      */
 /*    (body).                                                              */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008 by                   */
+/*  Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2009 by             */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -29,7 +29,6 @@
 #include FT_INTERNAL_STREAM_H
 #include FT_TRUETYPE_TAGS_H
 #include "ttpost.h"
-#include "ttload.h"
 
 #include "sferrors.h"
 
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index eadaade..833bb2a 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -494,7 +494,7 @@
     if ( version     != 0x00020000L ||
          num_strikes >= 0x10000L    )
     {
-      FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" ));
+      FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
       error = SFNT_Err_Invalid_File_Format;
 
       goto Exit;
diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c
index 3ebcbbd..38bcf21 100644
--- a/src/sfnt/ttsbit0.c
+++ b/src/sfnt/ttsbit0.c
@@ -62,7 +62,7 @@
 
     if ( table_size < 8 )
     {
-      FT_ERROR(( "tt_face_load_sbit_strikes: table too short!\n" ));
+      FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
       error = SFNT_Err_Invalid_File_Format;
       goto Exit;
     }
@@ -80,7 +80,7 @@
 
     if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
     {
-      FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version!\n" ));
+      FT_ERROR(( "tt_face_load_sbit_strikes: invalid table version\n" ));
       error = SFNT_Err_Invalid_File_Format;
       goto Fail;
     }
@@ -469,6 +469,41 @@
   }
 
 
+  /*
+   * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
+   * (with pointer `write').  In the example below, the width is 3 pixel,
+   * and `x_pos' is 1 pixel.
+   *
+   *       p                               p+1
+   *     |                               |                               |
+   *     | 7   6   5   4   3   2   1   0 | 7   6   5   4   3   2   1   0 |...
+   *     |                               |                               |
+   *       +-------+   +-------+   +-------+ ...
+   *           .           .           .
+   *           .           .           .
+   *           v           .           .
+   *       +-------+       .           .
+   * |                               | .
+   * | 7   6   5   4   3   2   1   0 | .
+   * |                               | .
+   *   write               .           .
+   *                       .           .
+   *                       v           .
+   *                   +-------+       .
+   *             |                               |
+   *             | 7   6   5   4   3   2   1   0 |
+   *             |                               |
+   *               write+1             .
+   *                                   .
+   *                                   v
+   *                               +-------+
+   *                         |                               |
+   *                         | 7   6   5   4   3   2   1   0 |
+   *                         |                               |
+   *                           write+2
+   *
+   */
+
   static FT_Error
   tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder  decoder,
                                     FT_Byte*        p,
@@ -514,6 +549,8 @@
     }
 
     /* now do the blit */
+
+    /* adjust `line' to point to the first byte of the bitmap */
     line  += y_pos * pitch + ( x_pos >> 3 );
     x_pos &= 7;
 
@@ -524,21 +561,23 @@
     for ( h = height; h > 0; h--, line += pitch )
     {
       FT_Byte*  write = line;
-      FT_Int    w = width;
+      FT_Int    w     = width;
 
 
+      /* handle initial byte (in target bitmap) specially if necessary */
       if ( x_pos )
       {
         w = ( width < 8 - x_pos ) ? width : 8 - x_pos;
 
         if ( h == height )
         {
-          rval  |= *p++;
-          nbits += x_pos;
+          rval  = *p++;
+          nbits = x_pos;
         }
         else if ( nbits < w )
         {
-          rval  |= *p++;
+          if ( p < limit )
+            rval |= *p++;
           nbits += 8 - w;
         }
         else
@@ -554,6 +593,7 @@
         w = width - w;
       }
 
+      /* handle medial bytes */
       for ( ; w >= 8; w -= 8 )
       {
         rval     |= *p++;
@@ -562,11 +602,13 @@
         rval <<= 8;
       }
 
+      /* handle final byte if necessary */
       if ( w > 0 )
       {
         if ( nbits < w )
         {
-          rval   |= *p++;
+          if ( p < limit )
+            rval |= *p++;
           *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
           nbits  += 8 - w;
 
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 10fa2ae..846e454 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    A new `perfect' anti-aliasing renderer (body).                       */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008 by             */
+/*  Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 by       */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -170,6 +170,34 @@
 #endif /* !FT_DEBUG_LEVEL_TRACE */
 
 
+#define FT_DEFINE_OUTLINE_FUNCS( class_,               \
+                                 move_to_, line_to_,   \
+                                 conic_to_, cubic_to_, \
+                                 shift_, delta_ )      \
+          static const FT_Outline_Funcs class_ =       \
+          {                                            \
+            move_to_,                                  \
+            line_to_,                                  \
+            conic_to_,                                 \
+            cubic_to_,                                 \
+            shift_,                                    \
+            delta_                                     \
+         };
+                                          
+#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_,            \
+                                raster_new_, raster_reset_,       \
+                                raster_set_mode_, raster_render_, \
+                                raster_done_ )                    \
+          const FT_Raster_Funcs class_ =                          \
+          {                                                       \
+            glyph_format_,                                        \
+            raster_new_,                                          \
+            raster_reset_,                                        \
+            raster_set_mode_,                                     \
+            raster_render_,                                       \
+            raster_done_                                          \
+         };
+
 #else /* !_STANDALONE_ */
 
 
@@ -181,6 +209,8 @@
 
 #include "ftsmerrs.h"
 
+#include "ftspic.h"
+
 #define ErrRaster_Invalid_Mode      Smooth_Err_Cannot_Render_Glyph
 #define ErrRaster_Invalid_Outline   Smooth_Err_Invalid_Outline
 #define ErrRaster_Memory_Overflow   Smooth_Err_Out_Of_Memory
@@ -188,7 +218,6 @@
 
 #endif /* !_STANDALONE_ */
 
-
 #ifndef FT_MEM_SET
 #define FT_MEM_SET( d, s, c )  ft_memset( d, s, c )
 #endif
@@ -201,27 +230,19 @@
 
 #ifndef FT_STATIC_RASTER
 
-
 #define RAS_ARG   PWorker  worker
 #define RAS_ARG_  PWorker  worker,
 
 #define RAS_VAR   worker
 #define RAS_VAR_  worker,
 
-#define ras       (*worker)
-
-
 #else /* FT_STATIC_RASTER */
 
-
 #define RAS_ARG   /* empty */
 #define RAS_ARG_  /* empty */
 #define RAS_VAR   /* empty */
 #define RAS_VAR_  /* empty */
 
-  static TWorker  ras;
-
-
 #endif /* FT_STATIC_RASTER */
 
 
@@ -254,7 +275,7 @@
   /* need to define them to "float" or "double" when experimenting with   */
   /* new algorithms                                                       */
 
-  typedef int   TCoord;   /* integer scanline/pixel coordinate */
+  typedef long  TCoord;   /* integer scanline/pixel coordinate */
   typedef long  TPos;     /* sub-pixel coordinate              */
 
   /* determine the type used to store cell areas.  This normally takes at */
@@ -285,8 +306,8 @@
 
   typedef struct  TCell_
   {
-    int    x;
-    int    cover;
+    TPos   x;     /* same with TWorker.ex */
+    TCoord cover; /* same with TWorker.cover */
     TArea  area;
     PCell  next;
 
@@ -301,12 +322,12 @@
     TPos    count_ex, count_ey;
 
     TArea   area;
-    int     cover;
+    TCoord  cover;
     int     invalid;
 
     PCell   cells;
-    int     max_cells;
-    int     num_cells;
+    FT_PtrDist  max_cells;
+    FT_PtrDist  num_cells;
 
     TCoord  cx, cy;
     TPos    x,  y;
@@ -338,11 +359,18 @@
     long        buffer_size;
 
     PCell*     ycells;
-    int        ycount;
+    TPos       ycount;
 
   } TWorker, *PWorker;
 
 
+#ifndef FT_STATIC_RASTER
+#define ras  (*worker)
+#else
+  static TWorker  ras;
+#endif
+
+
   typedef struct TRaster_
   {
     void*    buffer;
@@ -428,7 +456,7 @@
   gray_find_cell( RAS_ARG )
   {
     PCell  *pcell, cell;
-    int     x = ras.ex;
+    TPos    x = ras.ex;
 
 
     if ( x > ras.count_ex )
@@ -560,9 +588,9 @@
                                  TPos    x2,
                                  TCoord  y2 )
   {
-    TCoord  ex1, ex2, fx1, fx2, delta;
+    TCoord  ex1, ex2, fx1, fx2, delta, mod, lift, rem;
     long    p, first, dx;
-    int     incr, lift, mod, rem;
+    int     incr;
 
 
     dx = x2 - x1;
@@ -584,7 +612,7 @@
     if ( ex1 == ex2 )
     {
       delta      = y2 - y1;
-      ras.area  += (TArea)( fx1 + fx2 ) * delta;
+      ras.area  += (TArea)(( fx1 + fx2 ) * delta);
       ras.cover += delta;
       return;
     }
@@ -612,7 +640,7 @@
       mod += (TCoord)dx;
     }
 
-    ras.area  += (TArea)( fx1 + first ) * delta;
+    ras.area  += (TArea)(( fx1 + first ) * delta);
     ras.cover += delta;
 
     ex1 += incr;
@@ -642,7 +670,7 @@
           delta++;
         }
 
-        ras.area  += (TArea)ONE_PIXEL * delta;
+        ras.area  += (TArea)(ONE_PIXEL * delta);
         ras.cover += delta;
         y1        += delta;
         ex1       += incr;
@@ -651,7 +679,7 @@
     }
 
     delta      = y2 - y1;
-    ras.area  += (TArea)( fx2 + ONE_PIXEL - first ) * delta;
+    ras.area  += (TArea)(( fx2 + ONE_PIXEL - first ) * delta);
     ras.cover += delta;
   }
 
@@ -664,10 +692,10 @@
   gray_render_line( RAS_ARG_ TPos  to_x,
                              TPos  to_y )
   {
-    TCoord  ey1, ey2, fy1, fy2;
+    TCoord  ey1, ey2, fy1, fy2, mod;
     TPos    dx, dy, x, x2;
     long    p, first;
-    int     delta, rem, mod, lift, incr;
+    int     delta, rem, lift, incr;
 
 
     ey1 = TRUNC( ras.last_ey );
@@ -711,7 +739,7 @@
     {
       TCoord  ex     = TRUNC( ras.x );
       TCoord  two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );
-      TPos    area;
+      TArea   area;
 
 
       first = ONE_PIXEL;
@@ -726,7 +754,7 @@
       ras.cover += delta;
       ey1       += incr;
 
-      gray_set_cell( &ras, ex, ey1 );
+      gray_set_cell( RAS_VAR_ ex, ey1 );
 
       delta = (int)( first + first - ONE_PIXEL );
       area  = (TArea)two_fx * delta;
@@ -736,7 +764,7 @@
         ras.cover += delta;
         ey1       += incr;
 
-        gray_set_cell( &ras, ex, ey1 );
+        gray_set_cell( RAS_VAR_ ex, ey1 );
       }
 
       delta      = (int)( fy2 - ONE_PIXEL + first );
@@ -1104,13 +1132,13 @@
 
 
     /* record current cell, if any */
-    gray_record_cell( worker );
+    gray_record_cell( RAS_VAR );
 
     /* start to a new position */
     x = UPSCALE( to->x );
     y = UPSCALE( to->y );
 
-    gray_start_cell( worker, TRUNC( x ), TRUNC( y ) );
+    gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
 
     worker->x = x;
     worker->y = y;
@@ -1122,7 +1150,7 @@
   gray_line_to( const FT_Vector*  to,
                 PWorker           worker )
   {
-    gray_render_line( worker, UPSCALE( to->x ), UPSCALE( to->y ) );
+    gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
     return 0;
   }
 
@@ -1132,7 +1160,7 @@
                  const FT_Vector*  to,
                  PWorker           worker )
   {
-    gray_render_conic( worker, control, to );
+    gray_render_conic( RAS_VAR_ control, to );
     return 0;
   }
 
@@ -1143,7 +1171,7 @@
                  const FT_Vector*  to,
                  PWorker           worker )
   {
-    gray_render_cubic( worker, control1, control2, to );
+    gray_render_cubic( RAS_VAR_ control1, control2, to );
     return 0;
   }
 
@@ -1203,7 +1231,7 @@
   gray_hline( RAS_ARG_ TCoord  x,
                        TCoord  y,
                        TPos    area,
-                       int     acount )
+                       TCoord  acount )
   {
     FT_Span*  span;
     int       count;
@@ -1243,6 +1271,10 @@
     if ( x >= 32767 )
       x = 32767;
 
+    /* FT_Span.y is an integer, so limit our coordinates appropriately */
+    if ( y >= FT_INT_MAX )
+      y = FT_INT_MAX;
+
     if ( coverage )
     {
       /* see whether we can add this span to the current list */
@@ -1281,7 +1313,7 @@
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
         ras.num_gray_spans = 0;
-        ras.span_y         = y;
+        ras.span_y         = (int)y;
 
         count = 0;
         span  = ras.gray_spans;
@@ -1317,7 +1349,7 @@
       printf( "%3d:", yindex );
 
       for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
-        printf( " (%3d, c:%4d, a:%6d)", cell->x, cell->cover, cell->area );
+        printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area );
       printf( "\n" );
     }
   }
@@ -1349,7 +1381,7 @@
 
       for ( ; cell != NULL; cell = cell->next )
       {
-        TArea  area;
+        TPos  area;
 
 
         if ( cell->x > x && cover != 0 )
@@ -1666,23 +1698,25 @@
 
   } TBand;
 
-
-  static int
-  gray_convert_glyph_inner( RAS_ARG )
-  {
-    static
-    const FT_Outline_Funcs  func_interface =
-    {
+    FT_DEFINE_OUTLINE_FUNCS(func_interface,
       (FT_Outline_MoveTo_Func) gray_move_to,
       (FT_Outline_LineTo_Func) gray_line_to,
       (FT_Outline_ConicTo_Func)gray_conic_to,
       (FT_Outline_CubicTo_Func)gray_cubic_to,
       0,
       0
-    };
+    )
+
+  static int
+  gray_convert_glyph_inner( RAS_ARG )
+  {
 
     volatile int  error = 0;
 
+#ifdef FT_CONFIG_OPTION_PIC
+      FT_Outline_Funcs func_interface;
+      Init_Class_func_interface(&func_interface);
+#endif
 
     if ( ft_setjmp( ras.jump_buffer ) == 0 )
     {
@@ -1829,7 +1863,7 @@
         if ( middle == bottom )
         {
 #ifdef FT_DEBUG_LEVEL_TRACE
-          FT_TRACE7(( "gray_convert_glyph: Rotten glyph!\n" ));
+          FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
 #endif
           return 1;
         }
@@ -1917,7 +1951,7 @@
       ras.clip_box.yMax =  32767L;
     }
 
-    gray_init_cells( worker, raster->buffer, raster->buffer_size );
+    gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );
 
     ras.outline        = *outline;
     ras.num_cells      = 0;
@@ -1937,7 +1971,7 @@
       ras.render_span_data = &ras;
     }
 
-    return gray_convert_glyph( worker );
+    return gray_convert_glyph( RAS_VAR );
   }
 
 
@@ -2037,8 +2071,7 @@
   }
 
 
-  const FT_Raster_Funcs  ft_grays_raster =
-  {
+  FT_DEFINE_RASTER_FUNCS(ft_grays_raster,
     FT_GLYPH_FORMAT_OUTLINE,
 
     (FT_Raster_New_Func)     gray_raster_new,
@@ -2046,7 +2079,7 @@
     (FT_Raster_Set_Mode_Func)0,
     (FT_Raster_Render_Func)  gray_raster_render,
     (FT_Raster_Done_Func)    gray_raster_done
-  };
+  )
 
 
 /* END */
diff --git a/src/smooth/ftgrays.h b/src/smooth/ftgrays.h
index 2d40954..f20f55f 100644
--- a/src/smooth/ftgrays.h
+++ b/src/smooth/ftgrays.h
@@ -28,6 +28,7 @@
 #include "ftimage.h"
 #else
 #include <ft2build.h>
+#include FT_CONFIG_CONFIG_H /* for FT_CONFIG_OPTION_PIC */
 #include FT_IMAGE_H
 #endif
 
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index a6db504..eed6353 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -17,10 +17,12 @@
 
 
 #include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_OUTLINE_H
 #include "ftsmooth.h"
 #include "ftgrays.h"
+#include "ftspic.h"
 
 #include "ftsmerrs.h"
 
@@ -153,7 +155,7 @@
       slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
     }
 
-    /* allocate new one, depends on pixel format */
+    /* allocate new one */
     pitch = width;
     if ( hmul )
     {
@@ -194,6 +196,19 @@
 
 #endif
 
+#if FT_UINT_MAX > 0xFFFFU
+
+    /* Required check is ( pitch * height < FT_ULONG_MAX ),     */
+    /* but we care realistic cases only. Always pitch <= width. */
+    if ( width > 0xFFFFU || height > 0xFFFFU )
+    {
+      FT_ERROR(( "ft_smooth_render_generic: glyph too large: %d x %d\n",
+                 width, height ));
+      return Smooth_Err_Raster_Overflow;
+    }
+
+#endif
+
     bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
     bitmap->num_grays  = 256;
     bitmap->width      = width;
@@ -310,12 +325,19 @@
 
     FT_Outline_Translate( outline, x_shift, y_shift );
 
+    /*
+     * XXX: on 16bit system, we return an error for huge bitmap
+     * to prevent an overflow.
+     */
+    if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX )
+      return Smooth_Err_Invalid_Pixel_Size;
+
     if ( error )
       goto Exit;
 
     slot->format      = FT_GLYPH_FORMAT_BITMAP;
-    slot->bitmap_left = x_left;
-    slot->bitmap_top  = y_top;
+    slot->bitmap_left = (FT_Int)x_left;
+    slot->bitmap_top  = (FT_Int)y_top;
 
   Exit:
     if ( outline && origin )
@@ -376,10 +398,8 @@
   }
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Renderer_Class  ft_smooth_renderer_class =
-  {
-    {
+  FT_DEFINE_RENDERER(ft_smooth_renderer_class,
+
       FT_MODULE_RENDERER,
       sizeof( FT_RendererRec ),
 
@@ -392,7 +412,7 @@
       (FT_Module_Constructor)ft_smooth_init,
       (FT_Module_Destructor) 0,
       (FT_Module_Requester)  0
-    },
+    ,
 
     FT_GLYPH_FORMAT_OUTLINE,
 
@@ -401,14 +421,12 @@
     (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,
     (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,
 
-    (FT_Raster_Funcs*)    &ft_grays_raster
-  };
+    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET
+  )
 
 
-  FT_CALLBACK_TABLE_DEF
-  const FT_Renderer_Class  ft_smooth_lcd_renderer_class =
-  {
-    {
+  FT_DEFINE_RENDERER(ft_smooth_lcd_renderer_class,
+  
       FT_MODULE_RENDERER,
       sizeof( FT_RendererRec ),
 
@@ -421,7 +439,7 @@
       (FT_Module_Constructor)ft_smooth_init,
       (FT_Module_Destructor) 0,
       (FT_Module_Requester)  0
-    },
+    ,
 
     FT_GLYPH_FORMAT_OUTLINE,
 
@@ -430,15 +448,11 @@
     (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,
     (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,
 
-    (FT_Raster_Funcs*)    &ft_grays_raster
-  };
+    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET
+  )
 
+  FT_DEFINE_RENDERER(ft_smooth_lcdv_renderer_class,
 
-
-  FT_CALLBACK_TABLE_DEF
-  const FT_Renderer_Class  ft_smooth_lcdv_renderer_class =
-  {
-    {
       FT_MODULE_RENDERER,
       sizeof( FT_RendererRec ),
 
@@ -451,7 +465,7 @@
       (FT_Module_Constructor)ft_smooth_init,
       (FT_Module_Destructor) 0,
       (FT_Module_Requester)  0
-    },
+    ,
 
     FT_GLYPH_FORMAT_OUTLINE,
 
@@ -460,8 +474,8 @@
     (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,
     (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,
 
-    (FT_Raster_Funcs*)    &ft_grays_raster
-  };
+    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET
+  )
 
 
 /* END */
diff --git a/src/smooth/ftsmooth.h b/src/smooth/ftsmooth.h
index 62cced4..3708790 100644
--- a/src/smooth/ftsmooth.h
+++ b/src/smooth/ftsmooth.h
@@ -28,15 +28,15 @@
 
 
 #ifndef FT_CONFIG_OPTION_NO_STD_RASTER
-  FT_EXPORT_VAR( const FT_Renderer_Class )  ft_std_renderer_class;
+  FT_DECLARE_RENDERER( ft_std_renderer_class )
 #endif
 
 #ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER
-  FT_EXPORT_VAR( const FT_Renderer_Class )  ft_smooth_renderer_class;
+  FT_DECLARE_RENDERER( ft_smooth_renderer_class )
 
-  FT_EXPORT_VAR( const FT_Renderer_Class )  ft_smooth_lcd_renderer_class;
+  FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class )
 
-  FT_EXPORT_VAR( const FT_Renderer_Class )  ft_smooth_lcd_v_renderer_class;
+  FT_DECLARE_RENDERER( ft_smooth_lcd_v_renderer_class )
 #endif
 
 
diff --git a/src/smooth/ftspic.c b/src/smooth/ftspic.c
new file mode 100644
index 0000000..aa547fc
--- /dev/null
+++ b/src/smooth/ftspic.c
@@ -0,0 +1,97 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftspic.c                                                               */
+/*                                                                         */
+/*    The FreeType position independent code services for smooth module.   */
+/*                                                                         */
+/*  Copyright 2009 by                                                      */
+/*  Oran Agra and Mickey Gabel.                                            */
+/*                                                                         */
+/*  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.                                        */
+/*                                                                         */
<