diff --git a/README b/README
index 3391a573f5d4c655e1b72dd61a1fb6b68cb55b02..8f3e2bc03bfd22ab27ed70878a6b27112f6812da 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-  FreeType 2.10.0
+  FreeType 2.10.1
   ===============
 
   Homepage: https://www.freetype.org
@@ -24,9 +24,9 @@
 
   and download one of the following files.
 
-    freetype-doc-2.10.0.tar.bz2
-    freetype-doc-2.10.0.tar.gz
-    ftdoc2100.zip
+    freetype-doc-2.10.1.tar.xz
+    freetype-doc-2.10.1.tar.gz
+    ftdoc2101.zip
 
   To view the documentation online, go to
 
diff --git a/builds/windows/ftdebug.c b/builds/windows/ftdebug.c
index 783f46e0617a2eefe6da9f6794dfab11244e8af9..f374fcacb70fa291b2525768d2ce259a967376a2 100644
--- a/builds/windows/ftdebug.c
+++ b/builds/windows/ftdebug.c
@@ -41,7 +41,6 @@
    */
 
 
-
 #include <vtkfreetype/include/ft2build.h>
 #include FT_FREETYPE_H
 #include FT_INTERNAL_DEBUG_H
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index 189afad7467e780625921bf86cfce372207ca4df..de674d12cb1cd9a9a8773659bcc96be3fe8c89b6 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -645,7 +645,7 @@ FT_BEGIN_HEADER
    *   FT_ENCODING_MS_SYMBOL ::
    *     Microsoft Symbol encoding, used to encode mathematical symbols and
    *     wingdings.  For more information, see
-   *     'https://www.microsoft.com/typography/otspec/recom.htm',
+   *     'https://www.microsoft.com/typography/otspec/recom.htm#non-standard-symbol-fonts',
    *     'http://www.kostis.net/charsets/symbol.htm', and
    *     'http://www.kostis.net/charsets/wingding.htm'.
    *
@@ -1766,6 +1766,13 @@ FT_BEGIN_HEADER
    *     transformed, distorted, emboldened, etc.  However, it must not be
    *     freed.
    *
+   *     [Since 2.10.1] If @FT_LOAD_NO_SCALE is set, outline coordinates of
+   *     OpenType variation fonts for a selected instance are internally
+   *     handled as 26.6 fractional font units but returned as (rounded)
+   *     integers, as expected.  To get unrounded font units, don't use
+   *     @FT_LOAD_NO_SCALE but load the glyph with @FT_LOAD_NO_HINTING and
+   *     scale it, using the font's `units_per_EM` value as the ppem.
+   *
    *   num_subglyphs ::
    *     The number of subglyphs in a composite glyph.  This field is only
    *     valid for the composite glyph format that should normally only be
@@ -3932,8 +3939,8 @@ FT_BEGIN_HEADER
    *   The glyph index.  0~means 'undefined character code'.
    */
   FT_EXPORT( FT_UInt )
-  FT_Get_Name_Index( FT_Face     face,
-                     FT_String*  glyph_name );
+  FT_Get_Name_Index( FT_Face           face,
+                     const FT_String*  glyph_name );
 
 
   /**************************************************************************
@@ -4774,7 +4781,7 @@ FT_BEGIN_HEADER
    */
 #define FREETYPE_MAJOR  2
 #define FREETYPE_MINOR  10
-#define FREETYPE_PATCH  0
+#define FREETYPE_PATCH  1
 
 
   /**************************************************************************
diff --git a/include/freetype/fterrors.h b/include/freetype/fterrors.h
index 58f5a3ead12e406160c9b30dd4d39784cfb403cc..2b47eb2096ea6560d4428aa4e9e603bc2d3f80ac 100644
--- a/include/freetype/fterrors.h
+++ b/include/freetype/fterrors.h
@@ -244,6 +244,8 @@
 #define FT_ERR_PROTOS_DEFINED
 
 
+FT_BEGIN_HEADER
+
   /**************************************************************************
    *
    * @function:
@@ -274,6 +276,8 @@
   FT_EXPORT( const char* )
   FT_Error_String( FT_Error  error_code );
 
+FT_END_HEADER
+
 
 #endif /* FT_ERR_PROTOS_DEFINED */
 
diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h
index b48e2ab1ff6962503b88a55977c19cdd4289cbe6..4ef92f19094fea4de28c1e56e8a70558a7abc714 100644
--- a/include/freetype/ftglyph.h
+++ b/include/freetype/ftglyph.h
@@ -210,7 +210,7 @@ FT_BEGIN_HEADER
    *
    *   As the outline is extracted from a glyph slot, its coordinates are
    *   expressed normally in 26.6 pixels, unless the flag @FT_LOAD_NO_SCALE
-   *   was used in @FT_Load_Glyph() or @FT_Load_Char().
+   *   was used in @FT_Load_Glyph or @FT_Load_Char.
    *
    *   The outline's tables are always owned by the object and are destroyed
    *   with it.
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
index 40f2bf1952a6aead58c572478ba042b5d389e754..46f0ad2dab2388d64a08086c41f8c09b8e652955 100644
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -869,7 +869,7 @@ FT_BEGIN_HEADER
    *
    * @input:
    *   y ::
-   *     The scanline's y~coordinate.
+   *     The scanline's upward y~coordinate.
    *
    *   count ::
    *     The number of spans to draw on this scanline.
@@ -945,19 +945,16 @@ FT_BEGIN_HEADER
    *     This flag is set to indicate direct rendering.  In this mode, client
    *     applications must provide their own span callback.  This lets them
    *     directly draw or compose over an existing bitmap.  If this bit is
-   *     not set, the target pixmap's buffer _must_ be zeroed before
-   *     rendering.
+   *     _not_ set, the target pixmap's buffer _must_ be zeroed before
+   *     rendering and the output will be clipped to its size.
    *
    *     Direct rendering is only possible with anti-aliased glyphs.
    *
    *   FT_RASTER_FLAG_CLIP ::
    *     This flag is only used in direct rendering mode.  If set, the output
    *     will be clipped to a box specified in the `clip_box` field of the
-   *     @FT_Raster_Params structure.
-   *
-   *     Note that by default, the glyph bitmap is clipped to the target
-   *     pixmap, except in direct rendering mode where all spans are
-   *     generated if no clipping box is set.
+   *     @FT_Raster_Params structure.  Otherwise, the `clip_box` is
+   *     effectively set to the bounding box and all spans are generated.
    */
 #define FT_RASTER_FLAG_DEFAULT  0x0
 #define FT_RASTER_FLAG_AA       0x1
@@ -978,7 +975,8 @@ FT_BEGIN_HEADER
    *   FT_Raster_Params
    *
    * @description:
-   *   A structure to hold the arguments used by a raster's render function.
+   *   A structure to hold the parameters used by a raster's render function,
+   *   passed as an argument to @FT_Outline_Render.
    *
    * @fields:
    *   target ::
diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h
index cdbdcb75024cf5d72c361fb5f366697302cb5e71..34212435ba9ba5ba688ce8c72bedcb17e6319292 100644
--- a/include/freetype/ftmodapi.h
+++ b/include/freetype/ftmodapi.h
@@ -623,7 +623,7 @@ FT_BEGIN_HEADER
    *     it is bytecode interpreter's execution context, `TT_ExecContext`,
    *     which is declared in FreeType's internal header file `tttypes.h`.
    */
-  typedef void
+  typedef FT_Error
   (*FT_DebugHook_Func)( void*  arg );
 
 
diff --git a/include/freetype/ftoutln.h b/include/freetype/ftoutln.h
index 6a26d9c652afd077947d74a72d9feca55c40b17d..9ae60e30f994029e7cf086a27e7f92da632b7606 100644
--- a/include/freetype/ftoutln.h
+++ b/include/freetype/ftoutln.h
@@ -466,8 +466,6 @@ FT_BEGIN_HEADER
    *
    * @description:
    *   Render an outline within a bitmap using the current scan-convert.
-   *   This function uses an @FT_Raster_Params structure as an argument,
-   *   allowing advanced features like direct composition, translucency, etc.
    *
    * @input:
    *   library ::
@@ -485,8 +483,10 @@ FT_BEGIN_HEADER
    *   FreeType error code.  0~means success.
    *
    * @note:
-   *   You should know what you are doing and how @FT_Raster_Params works to
-   *   use this function.
+   *   This advanced function uses @FT_Raster_Params as an argument,
+   *   allowing FreeType rasterizer to be used for direct composition,
+   *   translucency, etc.  You should know how to set up @FT_Raster_Params
+   *   for this function to work.
    *
    *   The field `params.source` will be set to `outline` before the scan
    *   converter is called, which means that the value you give to it is
diff --git a/include/freetype/ftwinfnt.h b/include/freetype/ftwinfnt.h
index 079e5472fb477fbd0ddc428957b2d48c0639a024..5aa6cb262f1bec3f76f111a52cfbd22fa771c20e 100644
--- a/include/freetype/ftwinfnt.h
+++ b/include/freetype/ftwinfnt.h
@@ -58,7 +58,7 @@ FT_BEGIN_HEADER
    * @description:
    *   A list of valid values for the `charset` byte in @FT_WinFNT_HeaderRec. 
    *   Exact mapping tables for the various 'cpXXXX' encodings (except for
-   *   'cp1361') can be found at 'ftp://ftp.unicode.org/Public' in the
+   *   'cp1361') can be found at 'ftp://ftp.unicode.org/Public/' in the
    *   `MAPPINGS/VENDORS/MICSFT/WINDOWS` subdirectory.  'cp1361' is roughly a
    *   superset of `MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT`.
    *
diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h
index 2986ec359b18072f44aa3bd936e0bf9afb6011d7..1811fcd1ea2653a30bc8972b505cf03d9a591f75 100644
--- a/include/freetype/internal/ftcalc.h
+++ b/include/freetype/internal/ftcalc.h
@@ -378,6 +378,7 @@ FT_BEGIN_HEADER
 #if FT_SIZEOF_INT == 4
 
 #include <intrin.h>
+#pragma intrinsic( _BitScanReverse )
 
   static __inline FT_Int32
   FT_MSB_i386( FT_UInt32  x )
@@ -385,7 +386,6 @@ FT_BEGIN_HEADER
     unsigned long  where;
 
 
-    /* not available in older VC versions */
     _BitScanReverse( &where, x );
 
     return (FT_Int32)where;
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index f3a41b35aba5bf5b3e10c7b929b92ea41c39a256..0c1d3e5bf24f4e88f1f82a325fad4478b2898d5d 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -278,14 +278,12 @@ FT_BEGIN_HEADER
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
 
   typedef void  (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap*      bitmap,
-                                            FT_Render_Mode  render_mode,
                                             FT_Byte*        weights );
 
 
   /* This is the default LCD filter, an in-place, 5-tap FIR filter. */
   FT_BASE( void )
   ft_lcd_filter_fir( FT_Bitmap*           bitmap,
-                     FT_Render_Mode       mode,
                      FT_LcdFiveTapFilter  weights );
 
 #endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
@@ -941,8 +939,8 @@ FT_BEGIN_HEADER
                                FT_UInt     buffer_max );
 
   typedef FT_UInt
-  (*FT_Face_GetGlyphNameIndexFunc)( FT_Face     face,
-                                    FT_String*  glyph_name );
+  (*FT_Face_GetGlyphNameIndexFunc)( FT_Face           face,
+                                    const FT_String*  glyph_name );
 
 
 #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h
index e4dca0b0a5d971169b905ebc330a229633a0d325..a579a039b9cff5da8dd6ab59981943ab81912ab2 100644
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -165,6 +165,17 @@ FT_BEGIN_HEADER
 #define FT_BYTE_U32( p, i, s )  ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) )
 
 
+  /*
+   *    function      acts on      increases  does range   for    emits
+   *                                pointer    checking   frames  error
+   *  -------------------------------------------------------------------
+   *   FT_PEEK_XXX  buffer pointer      no         no        no     no
+   *   FT_NEXT_XXX  buffer pointer     yes         no        no     no
+   *   FT_GET_XXX   stream->cursor     yes        yes       yes     no
+   *   FT_READ_XXX  stream->pos        yes        yes        no    yes
+   */
+
+
   /*
    * `FT_PEEK_XXX' are generic macros to get data from a buffer position.  No
    * safety checks are performed.
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index 8089babfb6c201f55fb59f4dbdcca01651532407..f5f95980461bfa4194f20e6c92ac369492f13628 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -48,6 +48,7 @@ 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( sfwoff )    /* WOFF format handler     (sfwoff.c)   */
 FT_TRACE_DEF( ttbdf )     /* TrueType embedded BDF   (ttbdf.c)    */
 FT_TRACE_DEF( ttcmap )    /* charmap handler         (ttcmap.c)   */
 FT_TRACE_DEF( ttcolr )    /* glyph layer table       (ttcolr.c)   */
diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h
index 173d8ad906d5a5a08e925148af76174bd27f5ede..3c8830f7e462b3438b9fbcbe860e2fc96008b251 100644
--- a/include/freetype/internal/internal.h
+++ b/include/freetype/internal/internal.h
@@ -40,6 +40,7 @@
 
 #define FT_INTERNAL_TRUETYPE_TYPES_H      <freetype/internal/tttypes.h>
 #define FT_INTERNAL_TYPE1_TYPES_H         <freetype/internal/t1types.h>
+#define FT_INTERNAL_WOFF_TYPES_H          <freetype/internal/wofftypes.h>
 
 #define FT_INTERNAL_POSTSCRIPT_AUX_H      <freetype/internal/psaux.h>
 #define FT_INTERNAL_POSTSCRIPT_HINTS_H    <freetype/internal/pshints.h>
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index 3ab01c3e688b7624d53c35213705fca2e45424e7..f962a973de8573f673304f29ddddbc1f1537ea34 100644
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -96,10 +96,10 @@ FT_BEGIN_HEADER
     (*done)( PS_Table  table );
 
     FT_Error
-    (*add)( PS_Table  table,
-            FT_Int    idx,
-            void*     object,
-            FT_UInt   length );
+    (*add)( PS_Table     table,
+            FT_Int       idx,
+            const void*  object,
+            FT_UInt      length );
 
     void
     (*release)( PS_Table  table );
diff --git a/include/freetype/internal/services/svgldict.h b/include/freetype/internal/services/svgldict.h
index ca8edf0eb5535c030bf82c3801edc093859e517f..09496218350e59af96ee10e38c7832087d292512 100644
--- a/include/freetype/internal/services/svgldict.h
+++ b/include/freetype/internal/services/svgldict.h
@@ -41,8 +41,8 @@ FT_BEGIN_HEADER
                                FT_UInt     buffer_max );
 
   typedef FT_UInt
-  (*FT_GlyphDict_NameIndexFunc)( FT_Face     face,
-                                 FT_String*  glyph_name );
+  (*FT_GlyphDict_NameIndexFunc)( FT_Face           face,
+                                 const FT_String*  glyph_name );
 
 
   FT_DEFINE_SERVICE( GlyphDict )
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index 225f40df6eb2318e4f75ed3dedb5f4bd96011b7e..b19241c3063954e1a5eb832b44e691374cd26d22 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -23,6 +23,7 @@
 #include <ft2build.h>
 #include FT_INTERNAL_DRIVER_H
 #include FT_INTERNAL_TRUETYPE_TYPES_H
+#include FT_INTERNAL_WOFF_TYPES_H
 
 
 FT_BEGIN_HEADER
diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h
index e197a1afca3dca5a9c6801d3d9cbb3622f443906..d94c8c12841e0d697bc312de966a2b9a71709bf7 100644
--- a/include/freetype/internal/t1types.h
+++ b/include/freetype/internal/t1types.h
@@ -76,8 +76,8 @@ FT_BEGIN_HEADER
     FT_Int       code_first;
     FT_Int       code_last;
 
-    FT_UShort*   char_index;
-    FT_String**  char_name;
+    FT_UShort*         char_index;
+    const FT_String**  char_name;
 
   } T1_EncodingRec, *T1_Encoding;
 
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 5e9f40ec3f75248b9738c1cd9d344ac827e42315..23db240e7c57af8fe3cc4fba022701f6654fef5e 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -150,81 +150,6 @@ FT_BEGIN_HEADER
   } TT_TableRec, *TT_Table;
 
 
-  /**************************************************************************
-   *
-   * @struct:
-   *   WOFF_HeaderRec
-   *
-   * @description:
-   *   WOFF file format header.
-   *
-   * @fields:
-   *   See
-   *
-   *     https://www.w3.org/TR/WOFF/#WOFFHeader
-   */
-  typedef struct  WOFF_HeaderRec_
-  {
-    FT_ULong   signature;
-    FT_ULong   flavor;
-    FT_ULong   length;
-    FT_UShort  num_tables;
-    FT_UShort  reserved;
-    FT_ULong   totalSfntSize;
-    FT_UShort  majorVersion;
-    FT_UShort  minorVersion;
-    FT_ULong   metaOffset;
-    FT_ULong   metaLength;
-    FT_ULong   metaOrigLength;
-    FT_ULong   privOffset;
-    FT_ULong   privLength;
-
-  } WOFF_HeaderRec, *WOFF_Header;
-
-
-  /**************************************************************************
-   *
-   * @struct:
-   *   WOFF_TableRec
-   *
-   * @description:
-   *   This structure describes a given table of a WOFF font.
-   *
-   * @fields:
-   *   Tag ::
-   *     A four-bytes tag describing the table.
-   *
-   *   Offset ::
-   *     The offset of the table from the start of the WOFF font in its
-   *     resource.
-   *
-   *   CompLength ::
-   *     Compressed table length (in bytes).
-   *
-   *   OrigLength ::
-   *     Uncompressed table length (in bytes).
-   *
-   *   CheckSum ::
-   *     The table checksum.  This value can be ignored.
-   *
-   *   OrigOffset ::
-   *     The uncompressed table file offset.  This value gets computed while
-   *     constructing the (uncompressed) SFNT header.  It is not contained in
-   *     the WOFF file.
-   */
-  typedef struct  WOFF_TableRec_
-  {
-    FT_ULong  Tag;           /* table ID                  */
-    FT_ULong  Offset;        /* table file offset         */
-    FT_ULong  CompLength;    /* compressed table length   */
-    FT_ULong  OrigLength;    /* uncompressed table length */
-    FT_ULong  CheckSum;      /* uncompressed checksum     */
-
-    FT_ULong  OrigOffset;    /* uncompressed table file offset */
-                             /* (not in the WOFF file)         */
-  } WOFF_TableRec, *WOFF_Table;
-
-
   /**************************************************************************
    *
    * @struct:
@@ -1395,8 +1320,10 @@ FT_BEGIN_HEADER
    *
    *   cvt ::
    *     The face's original control value table.  Coordinates are expressed
-   *     in unscaled font units.  Comes from the 'cvt~' table.  Ignored for
-   *     Type 2 fonts.
+   *     in unscaled font units (in 26.6 format).  Comes from the 'cvt~'
+   *     table.  Ignored for Type 2 fonts.
+   *
+   *     If varied by the `CVAR' table, non-integer values are possible.
    *
    *   interpreter ::
    *     A pointer to the TrueType bytecode interpreters field is also used
@@ -1633,7 +1560,7 @@ FT_BEGIN_HEADER
 
     /* the original, unscaled, control value table */
     FT_ULong              cvt_size;
-    FT_Short*             cvt;
+    FT_Int32*             cvt;
 
     /* A pointer to the bytecode interpreter to use.  This is also */
     /* used to hook the debugger for the `ttdebug' utility.        */
diff --git a/include/freetype/internal/wofftypes.h b/include/freetype/internal/wofftypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba55bf883e452c3d2cc12be8f14aa0dd0f376020
--- /dev/null
+++ b/include/freetype/internal/wofftypes.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+ *
+ * wofftypes.h
+ *
+ *   Basic WOFF/WOFF2 type definitions and interface (specification
+ *   only).
+ *
+ * Copyright (C) 1996-2019 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#ifndef WOFFTYPES_H_
+#define WOFFTYPES_H_
+
+
+#include <ft2build.h>
+#include FT_TRUETYPE_TABLES_H
+#include FT_INTERNAL_OBJECTS_H
+
+
+FT_BEGIN_HEADER
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF_HeaderRec
+   *
+   * @description:
+   *   WOFF file format header.
+   *
+   * @fields:
+   *   See
+   *
+   *     https://www.w3.org/TR/WOFF/#WOFFHeader
+   */
+  typedef struct  WOFF_HeaderRec_
+  {
+    FT_ULong   signature;
+    FT_ULong   flavor;
+    FT_ULong   length;
+    FT_UShort  num_tables;
+    FT_UShort  reserved;
+    FT_ULong   totalSfntSize;
+    FT_UShort  majorVersion;
+    FT_UShort  minorVersion;
+    FT_ULong   metaOffset;
+    FT_ULong   metaLength;
+    FT_ULong   metaOrigLength;
+    FT_ULong   privOffset;
+    FT_ULong   privLength;
+
+  } WOFF_HeaderRec, *WOFF_Header;
+
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   WOFF_TableRec
+   *
+   * @description:
+   *   This structure describes a given table of a WOFF font.
+   *
+   * @fields:
+   *   Tag ::
+   *     A four-bytes tag describing the table.
+   *
+   *   Offset ::
+   *     The offset of the table from the start of the WOFF font in its
+   *     resource.
+   *
+   *   CompLength ::
+   *     Compressed table length (in bytes).
+   *
+   *   OrigLength ::
+   *     Uncompressed table length (in bytes).
+   *
+   *   CheckSum ::
+   *     The table checksum.  This value can be ignored.
+   *
+   *   OrigOffset ::
+   *     The uncompressed table file offset.  This value gets computed while
+   *     constructing the (uncompressed) SFNT header.  It is not contained in
+   *     the WOFF file.
+   */
+  typedef struct  WOFF_TableRec_
+  {
+    FT_ULong  Tag;           /* table ID                  */
+    FT_ULong  Offset;        /* table file offset         */
+    FT_ULong  CompLength;    /* compressed table length   */
+    FT_ULong  OrigLength;    /* uncompressed table length */
+    FT_ULong  CheckSum;      /* uncompressed checksum     */
+
+    FT_ULong  OrigOffset;    /* uncompressed table file offset */
+                             /* (not in the WOFF file)         */
+  } WOFF_TableRec, *WOFF_Table;
+
+
+FT_END_HEADER
+
+#endif /* WOFFTYPES_H_ */
+
+
+/* END */
diff --git a/include/vtk_freetype_mangle.h b/include/vtk_freetype_mangle.h
index 2aee500a502c7e94e85e9af2eeaa82975967a528..052eb86314265a622cac1493bbd1a7351fed897f 100644
--- a/include/vtk_freetype_mangle.h
+++ b/include/vtk_freetype_mangle.h
@@ -1,75 +1,71 @@
 #ifndef vtk_freetype_mangle_h
 #define vtk_freetype_mangle_h
 
-#define afm_parser_funcs vtkfreetype_afm_parser_funcs
-#define bdf_driver_class vtkfreetype_bdf_driver_class
-#define cff_cmap_encoding_class_rec vtkfreetype_cff_cmap_encoding_class_rec
-#define cff_cmap_unicode_class_rec vtkfreetype_cff_cmap_unicode_class_rec
-#define cff_driver_class vtkfreetype_cff_driver_class
+#define FTC_CMapCache_Lookup vtkfreetype_FTC_CMapCache_Lookup
+#define FTC_CMapCache_New vtkfreetype_FTC_CMapCache_New
+#define FTC_ImageCache_Lookup vtkfreetype_FTC_ImageCache_Lookup
+#define FTC_ImageCache_LookupScaler vtkfreetype_FTC_ImageCache_LookupScaler
+#define FTC_ImageCache_New vtkfreetype_FTC_ImageCache_New
+#define FTC_Manager_Done vtkfreetype_FTC_Manager_Done
+#define FTC_Manager_LookupFace vtkfreetype_FTC_Manager_LookupFace
+#define FTC_Manager_LookupSize vtkfreetype_FTC_Manager_LookupSize
+#define FTC_Manager_New vtkfreetype_FTC_Manager_New
+#define FTC_Manager_RemoveFaceID vtkfreetype_FTC_Manager_RemoveFaceID
+#define FTC_Manager_Reset vtkfreetype_FTC_Manager_Reset
+#define FTC_Node_Unref vtkfreetype_FTC_Node_Unref
+#define FTC_SBitCache_Lookup vtkfreetype_FTC_SBitCache_Lookup
+#define FTC_SBitCache_LookupScaler vtkfreetype_FTC_SBitCache_LookupScaler
+#define FTC_SBitCache_New vtkfreetype_FTC_SBitCache_New
 #define FT_Activate_Size vtkfreetype_FT_Activate_Size
 #define FT_Add_Default_Modules vtkfreetype_FT_Add_Default_Modules
 #define FT_Add_Module vtkfreetype_FT_Add_Module
-#define ft_adobe_glyph_list vtkfreetype_ft_adobe_glyph_list
 #define FT_Angle_Diff vtkfreetype_FT_Angle_Diff
 #define FT_Atan2 vtkfreetype_FT_Atan2
 #define FT_Attach_File vtkfreetype_FT_Attach_File
 #define FT_Attach_Stream vtkfreetype_FT_Attach_Stream
+#define FT_Bitmap_Blend vtkfreetype_FT_Bitmap_Blend
 #define FT_Bitmap_Convert vtkfreetype_FT_Bitmap_Convert
 #define FT_Bitmap_Copy vtkfreetype_FT_Bitmap_Copy
 #define FT_Bitmap_Done vtkfreetype_FT_Bitmap_Done
 #define FT_Bitmap_Embolden vtkfreetype_FT_Bitmap_Embolden
-#define ft_bitmap_glyph_class vtkfreetype_ft_bitmap_glyph_class
 #define FT_Bitmap_Init vtkfreetype_FT_Bitmap_Init
 #define FT_Bitmap_New vtkfreetype_FT_Bitmap_New
-#define FTC_CMapCache_Lookup vtkfreetype_FTC_CMapCache_Lookup
-#define FTC_CMapCache_New vtkfreetype_FTC_CMapCache_New
-#define FT_CeilFix vtkfreetype_FT_CeilFix
-#define FTC_ImageCache_Lookup vtkfreetype_FTC_ImageCache_Lookup
-#define FTC_ImageCache_LookupScaler vtkfreetype_FTC_ImageCache_LookupScaler
-#define FTC_ImageCache_New vtkfreetype_FTC_ImageCache_New
-#define FTC_Manager_Done vtkfreetype_FTC_Manager_Done
-#define FTC_Manager_LookupFace vtkfreetype_FTC_Manager_LookupFace
-#define FTC_Manager_LookupSize vtkfreetype_FTC_Manager_LookupSize
-#define FTC_Manager_New vtkfreetype_FTC_Manager_New
-#define FTC_Manager_RemoveFaceID vtkfreetype_FTC_Manager_RemoveFaceID
-#define FTC_Manager_Reset vtkfreetype_FTC_Manager_Reset
 #define FT_CMap_Done vtkfreetype_FT_CMap_Done
 #define FT_CMap_New vtkfreetype_FT_CMap_New
-#define FTC_Node_Unref vtkfreetype_FTC_Node_Unref
-#define ft_corner_is_flat vtkfreetype_ft_corner_is_flat
-#define ft_corner_orientation vtkfreetype_ft_corner_orientation
+#define FT_CeilFix vtkfreetype_FT_CeilFix
 #define FT_Cos vtkfreetype_FT_Cos
-#define FTC_SBitCache_Lookup vtkfreetype_FTC_SBitCache_Lookup
-#define FTC_SBitCache_LookupScaler vtkfreetype_FTC_SBitCache_LookupScaler
-#define FTC_SBitCache_New vtkfreetype_FTC_SBitCache_New
-#define ft_debug_init vtkfreetype_ft_debug_init
 #define FT_DivFix vtkfreetype_FT_DivFix
 #define FT_Done_Face vtkfreetype_FT_Done_Face
 #define FT_Done_FreeType vtkfreetype_FT_Done_FreeType
 #define FT_Done_Glyph vtkfreetype_FT_Done_Glyph
 #define FT_Done_GlyphSlot vtkfreetype_FT_Done_GlyphSlot
 #define FT_Done_Library vtkfreetype_FT_Done_Library
+#define FT_Done_MM_Var vtkfreetype_FT_Done_MM_Var
 #define FT_Done_Memory vtkfreetype_FT_Done_Memory
 #define FT_Done_Size vtkfreetype_FT_Done_Size
-#define FT_Face_GetCharsOfVariant vtkfreetype_FT_Face_GetCharsOfVariant
+#define FT_Error_String vtkfreetype_FT_Error_String
 #define FT_Face_GetCharVariantIndex vtkfreetype_FT_Face_GetCharVariantIndex
 #define FT_Face_GetCharVariantIsDefault vtkfreetype_FT_Face_GetCharVariantIsDefault
+#define FT_Face_GetCharsOfVariant vtkfreetype_FT_Face_GetCharsOfVariant
 #define FT_Face_GetVariantSelectors vtkfreetype_FT_Face_GetVariantSelectors
 #define FT_Face_GetVariantsOfChar vtkfreetype_FT_Face_GetVariantsOfChar
 #define FT_Face_Properties vtkfreetype_FT_Face_Properties
 #define FT_FloorFix vtkfreetype_FT_FloorFix
 #define FT_Get_Advance vtkfreetype_FT_Get_Advance
 #define FT_Get_Advances vtkfreetype_FT_Get_Advances
-#define FT_Get_Char_Index vtkfreetype_FT_Get_Char_Index
-#define FT_Get_Charmap_Index vtkfreetype_FT_Get_Charmap_Index
 #define FT_Get_CMap_Format vtkfreetype_FT_Get_CMap_Format
 #define FT_Get_CMap_Language_ID vtkfreetype_FT_Get_CMap_Language_ID
+#define FT_Get_Char_Index vtkfreetype_FT_Get_Char_Index
+#define FT_Get_Charmap_Index vtkfreetype_FT_Get_Charmap_Index
+#define FT_Get_Color_Glyph_Layer vtkfreetype_FT_Get_Color_Glyph_Layer
 #define FT_Get_First_Char vtkfreetype_FT_Get_First_Char
+#define FT_Get_Font_Format vtkfreetype_FT_Get_Font_Format
 #define FT_Get_Glyph vtkfreetype_FT_Get_Glyph
 #define FT_Get_Glyph_Name vtkfreetype_FT_Get_Glyph_Name
 #define FT_Get_Kerning vtkfreetype_FT_Get_Kerning
 #define FT_Get_MM_Blend_Coordinates vtkfreetype_FT_Get_MM_Blend_Coordinates
 #define FT_Get_MM_Var vtkfreetype_FT_Get_MM_Var
+#define FT_Get_MM_WeightVector vtkfreetype_FT_Get_MM_WeightVector
 #define FT_Get_Module vtkfreetype_FT_Get_Module
 #define FT_Get_Module_Interface vtkfreetype_FT_Get_Module_Interface
 #define FT_Get_Multi_Master vtkfreetype_FT_Get_Multi_Master
@@ -87,8 +83,7 @@
 #define FT_Get_Var_Axis_Flags vtkfreetype_FT_Get_Var_Axis_Flags
 #define FT_Get_Var_Blend_Coordinates vtkfreetype_FT_Get_Var_Blend_Coordinates
 #define FT_Get_Var_Design_Coordinates vtkfreetype_FT_Get_Var_Design_Coordinates
-#define FT_Glyph_Copy vtkfreetype_FT_Glyph_Copy
-#define FT_Glyph_Get_CBox vtkfreetype_FT_Glyph_Get_CBox
+#define FT_Get_X11_Font_Format vtkfreetype_FT_Get_X11_Font_Format
 #define FT_GlyphLoader_Add vtkfreetype_FT_GlyphLoader_Add
 #define FT_GlyphLoader_CheckPoints vtkfreetype_FT_GlyphLoader_CheckPoints
 #define FT_GlyphLoader_CheckSubGlyphs vtkfreetype_FT_GlyphLoader_CheckSubGlyphs
@@ -99,23 +94,17 @@
 #define FT_GlyphLoader_Prepare vtkfreetype_FT_GlyphLoader_Prepare
 #define FT_GlyphLoader_Reset vtkfreetype_FT_GlyphLoader_Reset
 #define FT_GlyphLoader_Rewind vtkfreetype_FT_GlyphLoader_Rewind
-#define ft_glyphslot_alloc_bitmap vtkfreetype_ft_glyphslot_alloc_bitmap
-#define ft_glyphslot_free_bitmap vtkfreetype_ft_glyphslot_free_bitmap
 #define FT_GlyphSlot_Own_Bitmap vtkfreetype_FT_GlyphSlot_Own_Bitmap
-#define ft_glyphslot_set_bitmap vtkfreetype_ft_glyphslot_set_bitmap
+#define FT_Glyph_Copy vtkfreetype_FT_Glyph_Copy
+#define FT_Glyph_Get_CBox vtkfreetype_FT_Glyph_Get_CBox
 #define FT_Glyph_To_Bitmap vtkfreetype_FT_Glyph_To_Bitmap
 #define FT_Glyph_Transform vtkfreetype_FT_Glyph_Transform
-#define ft_grays_raster vtkfreetype_ft_grays_raster
 #define FT_Gzip_Uncompress vtkfreetype_FT_Gzip_Uncompress
-#define ft_hash_num_init vtkfreetype_ft_hash_num_init
-#define ft_hash_num_insert vtkfreetype_ft_hash_num_insert
-#define ft_hash_num_lookup vtkfreetype_ft_hash_num_lookup
-#define ft_hash_str_free vtkfreetype_ft_hash_str_free
-#define ft_hash_str_init vtkfreetype_ft_hash_str_init
-#define ft_hash_str_insert vtkfreetype_ft_hash_str_insert
-#define ft_hash_str_lookup vtkfreetype_ft_hash_str_lookup
 #define FT_Hypot vtkfreetype_FT_Hypot
 #define FT_Init_FreeType vtkfreetype_FT_Init_FreeType
+#define FT_Library_SetLcdFilter vtkfreetype_FT_Library_SetLcdFilter
+#define FT_Library_SetLcdFilterWeights vtkfreetype_FT_Library_SetLcdFilterWeights
+#define FT_Library_SetLcdGeometry vtkfreetype_FT_Library_SetLcdGeometry
 #define FT_Library_Version vtkfreetype_FT_Library_Version
 #define FT_List_Add vtkfreetype_FT_List_Add
 #define FT_List_Finalize vtkfreetype_FT_List_Finalize
@@ -128,27 +117,15 @@
 #define FT_Load_Glyph vtkfreetype_FT_Load_Glyph
 #define FT_Load_Sfnt_Table vtkfreetype_FT_Load_Sfnt_Table
 #define FT_Lookup_Renderer vtkfreetype_FT_Lookup_Renderer
-#define ft_lzwstate_done vtkfreetype_ft_lzwstate_done
-#define ft_lzwstate_init vtkfreetype_ft_lzwstate_init
-#define ft_lzwstate_io vtkfreetype_ft_lzwstate_io
-#define ft_lzwstate_reset vtkfreetype_ft_lzwstate_reset
-#define ft_mac_names vtkfreetype_ft_mac_names
 #define FT_Match_Size vtkfreetype_FT_Match_Size
+#define FT_Matrix_Check vtkfreetype_FT_Matrix_Check
 #define FT_Matrix_Invert vtkfreetype_FT_Matrix_Invert
 #define FT_Matrix_Multiply vtkfreetype_FT_Matrix_Multiply
 #define FT_Matrix_Multiply_Scaled vtkfreetype_FT_Matrix_Multiply_Scaled
-#define ft_mem_alloc vtkfreetype_ft_mem_alloc
-#define ft_mem_dup vtkfreetype_ft_mem_dup
-#define ft_mem_free vtkfreetype_ft_mem_free
-#define ft_mem_qalloc vtkfreetype_ft_mem_qalloc
-#define ft_mem_qrealloc vtkfreetype_ft_mem_qrealloc
-#define ft_mem_realloc vtkfreetype_ft_mem_realloc
-#define ft_mem_strcpyn vtkfreetype_ft_mem_strcpyn
-#define ft_mem_strdup vtkfreetype_ft_mem_strdup
-#define ft_module_get_service vtkfreetype_ft_module_get_service
 #define FT_MulDiv vtkfreetype_FT_MulDiv
 #define FT_MulDiv_No_Round vtkfreetype_FT_MulDiv_No_Round
 #define FT_New_Face vtkfreetype_FT_New_Face
+#define FT_New_Glyph vtkfreetype_FT_New_Glyph
 #define FT_New_GlyphSlot vtkfreetype_FT_New_GlyphSlot
 #define FT_New_Library vtkfreetype_FT_New_Library
 #define FT_New_Memory vtkfreetype_FT_New_Memory
@@ -166,20 +143,20 @@
 #define FT_Outline_Get_Bitmap vtkfreetype_FT_Outline_Get_Bitmap
 #define FT_Outline_Get_CBox vtkfreetype_FT_Outline_Get_CBox
 #define FT_Outline_Get_Orientation vtkfreetype_FT_Outline_Get_Orientation
-#define ft_outline_glyph_class vtkfreetype_ft_outline_glyph_class
 #define FT_Outline_New vtkfreetype_FT_Outline_New
 #define FT_Outline_New_Internal vtkfreetype_FT_Outline_New_Internal
 #define FT_Outline_Render vtkfreetype_FT_Outline_Render
 #define FT_Outline_Reverse vtkfreetype_FT_Outline_Reverse
 #define FT_Outline_Transform vtkfreetype_FT_Outline_Transform
 #define FT_Outline_Translate vtkfreetype_FT_Outline_Translate
+#define FT_Palette_Data_Get vtkfreetype_FT_Palette_Data_Get
+#define FT_Palette_Select vtkfreetype_FT_Palette_Select
+#define FT_Palette_Set_Foreground_Color vtkfreetype_FT_Palette_Set_Foreground_Color
 #define FT_Property_Get vtkfreetype_FT_Property_Get
 #define FT_Property_Set vtkfreetype_FT_Property_Set
-#define ft_property_string_set vtkfreetype_ft_property_string_set
 #define FT_Raccess_Get_DataOffsets vtkfreetype_FT_Raccess_Get_DataOffsets
 #define FT_Raccess_Get_HeaderInfo vtkfreetype_FT_Raccess_Get_HeaderInfo
 #define FT_Raccess_Guess vtkfreetype_FT_Raccess_Guess
-#define ft_raster1_renderer_class vtkfreetype_ft_raster1_renderer_class
 #define FT_Reference_Face vtkfreetype_FT_Reference_Face
 #define FT_Reference_Library vtkfreetype_FT_Reference_Library
 #define FT_Remove_Module vtkfreetype_FT_Remove_Module
@@ -191,26 +168,21 @@
 #define FT_Select_Charmap vtkfreetype_FT_Select_Charmap
 #define FT_Select_Metrics vtkfreetype_FT_Select_Metrics
 #define FT_Select_Size vtkfreetype_FT_Select_Size
-#define ft_service_list_lookup vtkfreetype_ft_service_list_lookup
-#define FT_Set_Charmap vtkfreetype_FT_Set_Charmap
 #define FT_Set_Char_Size vtkfreetype_FT_Set_Char_Size
+#define FT_Set_Charmap vtkfreetype_FT_Set_Charmap
 #define FT_Set_Debug_Hook vtkfreetype_FT_Set_Debug_Hook
 #define FT_Set_Default_Properties vtkfreetype_FT_Set_Default_Properties
 #define FT_Set_MM_Blend_Coordinates vtkfreetype_FT_Set_MM_Blend_Coordinates
 #define FT_Set_MM_Design_Coordinates vtkfreetype_FT_Set_MM_Design_Coordinates
+#define FT_Set_MM_WeightVector vtkfreetype_FT_Set_MM_WeightVector
+#define FT_Set_Named_Instance vtkfreetype_FT_Set_Named_Instance
 #define FT_Set_Pixel_Sizes vtkfreetype_FT_Set_Pixel_Sizes
 #define FT_Set_Renderer vtkfreetype_FT_Set_Renderer
 #define FT_Set_Transform vtkfreetype_FT_Set_Transform
 #define FT_Set_Var_Blend_Coordinates vtkfreetype_FT_Set_Var_Blend_Coordinates
 #define FT_Set_Var_Design_Coordinates vtkfreetype_FT_Set_Var_Design_Coordinates
 #define FT_Sfnt_Table_Info vtkfreetype_FT_Sfnt_Table_Info
-#define ft_sid_names vtkfreetype_ft_sid_names
 #define FT_Sin vtkfreetype_FT_Sin
-#define ft_smooth_lcd_renderer_class vtkfreetype_ft_smooth_lcd_renderer_class
-#define ft_smooth_lcdv_renderer_class vtkfreetype_ft_smooth_lcdv_renderer_class
-#define ft_smooth_renderer_class vtkfreetype_ft_smooth_renderer_class
-#define ft_standard_glyph_names vtkfreetype_ft_standard_glyph_names
-#define ft_standard_raster vtkfreetype_ft_standard_raster
 #define FT_Stream_Close vtkfreetype_FT_Stream_Close
 #define FT_Stream_EnterFrame vtkfreetype_FT_Stream_EnterFrame
 #define FT_Stream_ExitFrame vtkfreetype_FT_Stream_ExitFrame
@@ -241,13 +213,11 @@
 #define FT_Stream_Seek vtkfreetype_FT_Stream_Seek
 #define FT_Stream_Skip vtkfreetype_FT_Stream_Skip
 #define FT_Stream_TryRead vtkfreetype_FT_Stream_TryRead
-#define ft_synthesize_vertical_metrics vtkfreetype_ft_synthesize_vertical_metrics
 #define FT_Tan vtkfreetype_FT_Tan
+#define FT_Trace_Disable vtkfreetype_FT_Trace_Disable
+#define FT_Trace_Enable vtkfreetype_FT_Trace_Enable
 #define FT_Trace_Get_Count vtkfreetype_FT_Trace_Get_Count
 #define FT_Trace_Get_Name vtkfreetype_FT_Trace_Get_Name
-#define ft_validator_error vtkfreetype_ft_validator_error
-#define ft_validator_init vtkfreetype_ft_validator_init
-#define ft_validator_run vtkfreetype_ft_validator_run
 #define FT_Vector_From_Polar vtkfreetype_FT_Vector_From_Polar
 #define FT_Vector_Length vtkfreetype_FT_Vector_Length
 #define FT_Vector_NormLen vtkfreetype_FT_Vector_NormLen
@@ -256,18 +226,72 @@
 #define FT_Vector_Transform vtkfreetype_FT_Vector_Transform
 #define FT_Vector_Transform_Scaled vtkfreetype_FT_Vector_Transform_Scaled
 #define FT_Vector_Unit vtkfreetype_FT_Vector_Unit
+#define TT_New_Context vtkfreetype_TT_New_Context
+#define TT_RunIns vtkfreetype_TT_RunIns
+#define afm_parser_funcs vtkfreetype_afm_parser_funcs
+#define bdf_driver_class vtkfreetype_bdf_driver_class
+#define cff_cmap_encoding_class_rec vtkfreetype_cff_cmap_encoding_class_rec
+#define cff_cmap_unicode_class_rec vtkfreetype_cff_cmap_unicode_class_rec
+#define cff_driver_class vtkfreetype_cff_driver_class
+#define ft_adobe_glyph_list vtkfreetype_ft_adobe_glyph_list
+#define ft_bitmap_glyph_class vtkfreetype_ft_bitmap_glyph_class
+#define ft_corner_is_flat vtkfreetype_ft_corner_is_flat
+#define ft_corner_orientation vtkfreetype_ft_corner_orientation
+#define ft_debug_init vtkfreetype_ft_debug_init
+#define ft_glyphslot_alloc_bitmap vtkfreetype_ft_glyphslot_alloc_bitmap
+#define ft_glyphslot_free_bitmap vtkfreetype_ft_glyphslot_free_bitmap
+#define ft_glyphslot_preset_bitmap vtkfreetype_ft_glyphslot_preset_bitmap
+#define ft_glyphslot_set_bitmap vtkfreetype_ft_glyphslot_set_bitmap
+#define ft_grays_raster vtkfreetype_ft_grays_raster
+#define ft_hash_num_init vtkfreetype_ft_hash_num_init
+#define ft_hash_num_insert vtkfreetype_ft_hash_num_insert
+#define ft_hash_num_lookup vtkfreetype_ft_hash_num_lookup
+#define ft_hash_str_free vtkfreetype_ft_hash_str_free
+#define ft_hash_str_init vtkfreetype_ft_hash_str_init
+#define ft_hash_str_insert vtkfreetype_ft_hash_str_insert
+#define ft_hash_str_lookup vtkfreetype_ft_hash_str_lookup
+#define ft_lcd_padding vtkfreetype_ft_lcd_padding
+#define ft_lzwstate_done vtkfreetype_ft_lzwstate_done
+#define ft_lzwstate_init vtkfreetype_ft_lzwstate_init
+#define ft_lzwstate_io vtkfreetype_ft_lzwstate_io
+#define ft_lzwstate_reset vtkfreetype_ft_lzwstate_reset
+#define ft_mac_names vtkfreetype_ft_mac_names
+#define ft_mem_alloc vtkfreetype_ft_mem_alloc
+#define ft_mem_dup vtkfreetype_ft_mem_dup
+#define ft_mem_free vtkfreetype_ft_mem_free
+#define ft_mem_qalloc vtkfreetype_ft_mem_qalloc
+#define ft_mem_qrealloc vtkfreetype_ft_mem_qrealloc
+#define ft_mem_realloc vtkfreetype_ft_mem_realloc
+#define ft_mem_strcpyn vtkfreetype_ft_mem_strcpyn
+#define ft_mem_strdup vtkfreetype_ft_mem_strdup
+#define ft_module_get_service vtkfreetype_ft_module_get_service
+#define ft_outline_glyph_class vtkfreetype_ft_outline_glyph_class
+#define ft_property_string_set vtkfreetype_ft_property_string_set
+#define ft_raster1_renderer_class vtkfreetype_ft_raster1_renderer_class
+#define ft_service_list_lookup vtkfreetype_ft_service_list_lookup
+#define ft_sid_names vtkfreetype_ft_sid_names
+#define ft_smooth_lcd_renderer_class vtkfreetype_ft_smooth_lcd_renderer_class
+#define ft_smooth_lcdv_renderer_class vtkfreetype_ft_smooth_lcdv_renderer_class
+#define ft_smooth_renderer_class vtkfreetype_ft_smooth_renderer_class
+#define ft_standard_glyph_names vtkfreetype_ft_standard_glyph_names
+#define ft_standard_raster vtkfreetype_ft_standard_raster
+#define ft_synthesize_vertical_metrics vtkfreetype_ft_synthesize_vertical_metrics
+#define ft_validator_error vtkfreetype_ft_validator_error
+#define ft_validator_init vtkfreetype_ft_validator_init
+#define ft_validator_run vtkfreetype_ft_validator_run
 #define pcf_driver_class vtkfreetype_pcf_driver_class
 #define pfr_cmap_class_rec vtkfreetype_pfr_cmap_class_rec
 #define pfr_driver_class vtkfreetype_pfr_driver_class
-#define psaux_module_class vtkfreetype_psaux_module_class
-#define pshinter_module_class vtkfreetype_pshinter_module_class
 #define ps_hints_apply vtkfreetype_ps_hints_apply
-#define psnames_module_class vtkfreetype_psnames_module_class
 #define ps_parser_funcs vtkfreetype_ps_parser_funcs
+#define ps_property_get vtkfreetype_ps_property_get
+#define ps_property_set vtkfreetype_ps_property_set
 #define ps_table_funcs vtkfreetype_ps_table_funcs
+#define psaux_module_class vtkfreetype_psaux_module_class
+#define pshinter_module_class vtkfreetype_pshinter_module_class
+#define psnames_module_class vtkfreetype_psnames_module_class
 #define sfnt_module_class vtkfreetype_sfnt_module_class
 #define t1_builder_funcs vtkfreetype_t1_builder_funcs
-#define t1cid_driver_class vtkfreetype_t1cid_driver_class
 #define t1_cmap_classes vtkfreetype_t1_cmap_classes
 #define t1_cmap_custom_class_rec vtkfreetype_t1_cmap_custom_class_rec
 #define t1_cmap_expert_class_rec vtkfreetype_t1_cmap_expert_class_rec
@@ -277,6 +301,7 @@
 #define t1_driver_class vtkfreetype_t1_driver_class
 #define t1_expert_encoding vtkfreetype_t1_expert_encoding
 #define t1_standard_encoding vtkfreetype_t1_standard_encoding
+#define t1cid_driver_class vtkfreetype_t1cid_driver_class
 #define t42_driver_class vtkfreetype_t42_driver_class
 #define tt_cmap0_class_rec vtkfreetype_tt_cmap0_class_rec
 #define tt_cmap10_class_rec vtkfreetype_tt_cmap10_class_rec
@@ -290,8 +315,6 @@
 #define tt_cmap_unicode_class_rec vtkfreetype_tt_cmap_unicode_class_rec
 #define tt_default_graphics_state vtkfreetype_tt_default_graphics_state
 #define tt_driver_class vtkfreetype_tt_driver_class
-#define TT_New_Context vtkfreetype_TT_New_Context
-#define TT_RunIns vtkfreetype_TT_RunIns
 #define vtkfreetype_FT_MulFix vtkfreetype_vtkfreetype_FT_MulFix
 #define winfnt_driver_class vtkfreetype_winfnt_driver_class
 
diff --git a/src/autofit/afblue.c b/src/autofit/afblue.c
index 28da159008e11bca38eecd31b18fe1cd9bc5f8eb..b99dbeb19c03cceecbf6ec629cc26e27f12d76ba 100644
--- a/src/autofit/afblue.c
+++ b/src/autofit/afblue.c
@@ -296,6 +296,10 @@
     '\0',
     '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xA7', ' ', '\xE0', '\xB4', '\xB6', ' ', '\xE0', '\xB4', '\x98', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xA5', ' ', '\xE0', '\xB4', '\xB2',  /* à´Ÿ à´  à´§ à´¶ à´˜ à´š à´¥ à´² */
     '\0',
+    '\xE1', '\xA0', '\xB3', ' ', '\xE1', '\xA0', '\xB4', ' ', '\xE1', '\xA0', '\xB6', ' ', '\xE1', '\xA0', '\xBD', ' ', '\xE1', '\xA1', '\x82', ' ', '\xE1', '\xA1', '\x8A', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xA1', '\xE2', '\x80', '\x8D', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xB3', '\xE2', '\x80', '\x8D',  /* ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍ */
+    '\0',
+    '\xE1', '\xA1', '\x83',  /* ᡃ */
+    '\0',
     '\xE1', '\x80', '\x81', ' ', '\xE1', '\x80', '\x82', ' ', '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\xA5', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B',  /* ခ ဂ င ဒ ဝ ၥ ၊ ။ */
     '\0',
     '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x8E', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x95', ' ', '\xE1', '\x80', '\x97', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B',  /* င ဎ ဒ ပ ဗ ဝ ၊ ။ */
@@ -649,6 +653,9 @@
     { AF_BLUE_STRING_MALAYALAM_TOP,    AF_BLUE_PROPERTY_LATIN_TOP },
     { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0                          },
     { AF_BLUE_STRING_MAX,              0                          },
+    { AF_BLUE_STRING_MONGOLIAN_TOP_BASE,    AF_BLUE_PROPERTY_LATIN_TOP },
+    { AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE, 0                          },
+    { AF_BLUE_STRING_MAX,                   0                          },
     { AF_BLUE_STRING_MYANMAR_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
                                         AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
     { AF_BLUE_STRING_MYANMAR_BOTTOM,    0                                 },
diff --git a/src/autofit/afblue.dat b/src/autofit/afblue.dat
index 14a0993b61d93069d587b7dfea0dec45030c65ff..46db43fe22409842bc57c9ada4a7791b459ccd41 100644
--- a/src/autofit/afblue.dat
+++ b/src/autofit/afblue.dat
@@ -392,6 +392,11 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
   AF_BLUE_STRING_MALAYALAM_BOTTOM
     "à´Ÿ à´  à´§ à´¶ à´˜ à´š à´¥ à´²"
 
+  AF_BLUE_STRING_MONGOLIAN_TOP_BASE
+    "ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍"
+  AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE
+    "ᡃ"
+
   AF_BLUE_STRING_MYANMAR_TOP
     "ခ ဂ င ဒ ဝ ၥ ၊ ။"
   AF_BLUE_STRING_MYANMAR_BOTTOM
@@ -947,6 +952,11 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
     { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0                          }
     { AF_BLUE_STRING_MAX,              0                          }
 
+  AF_BLUE_STRINGSET_MONG
+    { AF_BLUE_STRING_MONGOLIAN_TOP_BASE,    AF_BLUE_PROPERTY_LATIN_TOP }
+    { AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE, 0                          }
+    { AF_BLUE_STRING_MAX,                   0                          }
+
   AF_BLUE_STRINGSET_MYMR
     { AF_BLUE_STRING_MYANMAR_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
                                         AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
diff --git a/src/autofit/afblue.h b/src/autofit/afblue.h
index a2ff597b8eb84b3da7c81eba91d88c07db310e0b..b69b1df521f20403c66748a566a0678e4cb551c5 100644
--- a/src/autofit/afblue.h
+++ b/src/autofit/afblue.h
@@ -212,56 +212,58 @@ FT_BEGIN_HEADER
     AF_BLUE_STRING_LISU_BOTTOM = 3506,
     AF_BLUE_STRING_MALAYALAM_TOP = 3538,
     AF_BLUE_STRING_MALAYALAM_BOTTOM = 3582,
-    AF_BLUE_STRING_MYANMAR_TOP = 3614,
-    AF_BLUE_STRING_MYANMAR_BOTTOM = 3646,
-    AF_BLUE_STRING_MYANMAR_ASCENDER = 3678,
-    AF_BLUE_STRING_MYANMAR_DESCENDER = 3706,
-    AF_BLUE_STRING_NKO_TOP = 3738,
-    AF_BLUE_STRING_NKO_BOTTOM = 3762,
-    AF_BLUE_STRING_NKO_SMALL_TOP = 3777,
-    AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3786,
-    AF_BLUE_STRING_OL_CHIKI = 3798,
-    AF_BLUE_STRING_OLD_TURKIC_TOP = 3822,
-    AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3837,
-    AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3857,
-    AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3897,
-    AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3927,
-    AF_BLUE_STRING_OSAGE_SMALL_TOP = 3942,
-    AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 3982,
-    AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4022,
-    AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4047,
-    AF_BLUE_STRING_OSMANYA_TOP = 4062,
-    AF_BLUE_STRING_OSMANYA_BOTTOM = 4102,
-    AF_BLUE_STRING_SAURASHTRA_TOP = 4142,
-    AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4174,
-    AF_BLUE_STRING_SHAVIAN_TOP = 4194,
-    AF_BLUE_STRING_SHAVIAN_BOTTOM = 4204,
-    AF_BLUE_STRING_SHAVIAN_DESCENDER = 4229,
-    AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4239,
-    AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4274,
-    AF_BLUE_STRING_SINHALA_TOP = 4289,
-    AF_BLUE_STRING_SINHALA_BOTTOM = 4321,
-    AF_BLUE_STRING_SINHALA_DESCENDER = 4353,
-    AF_BLUE_STRING_SUNDANESE_TOP = 4397,
-    AF_BLUE_STRING_SUNDANESE_BOTTOM = 4421,
-    AF_BLUE_STRING_SUNDANESE_DESCENDER = 4453,
-    AF_BLUE_STRING_TAI_VIET_TOP = 4461,
-    AF_BLUE_STRING_TAI_VIET_BOTTOM = 4481,
-    AF_BLUE_STRING_TAMIL_TOP = 4493,
-    AF_BLUE_STRING_TAMIL_BOTTOM = 4525,
-    AF_BLUE_STRING_TELUGU_TOP = 4557,
-    AF_BLUE_STRING_TELUGU_BOTTOM = 4585,
-    AF_BLUE_STRING_THAI_TOP = 4613,
-    AF_BLUE_STRING_THAI_BOTTOM = 4637,
-    AF_BLUE_STRING_THAI_ASCENDER = 4665,
-    AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4677,
-    AF_BLUE_STRING_THAI_DESCENDER = 4689,
-    AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4705,
-    AF_BLUE_STRING_THAI_DIGIT_TOP = 4713,
-    AF_BLUE_STRING_TIFINAGH = 4725,
-    AF_BLUE_STRING_VAI_TOP = 4757,
-    AF_BLUE_STRING_VAI_BOTTOM = 4789,
-    af_blue_1_1 = 4820,
+    AF_BLUE_STRING_MONGOLIAN_TOP_BASE = 3614,
+    AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE = 3658,
+    AF_BLUE_STRING_MYANMAR_TOP = 3662,
+    AF_BLUE_STRING_MYANMAR_BOTTOM = 3694,
+    AF_BLUE_STRING_MYANMAR_ASCENDER = 3726,
+    AF_BLUE_STRING_MYANMAR_DESCENDER = 3754,
+    AF_BLUE_STRING_NKO_TOP = 3786,
+    AF_BLUE_STRING_NKO_BOTTOM = 3810,
+    AF_BLUE_STRING_NKO_SMALL_TOP = 3825,
+    AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3834,
+    AF_BLUE_STRING_OL_CHIKI = 3846,
+    AF_BLUE_STRING_OLD_TURKIC_TOP = 3870,
+    AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3885,
+    AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3905,
+    AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3945,
+    AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3975,
+    AF_BLUE_STRING_OSAGE_SMALL_TOP = 3990,
+    AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 4030,
+    AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4070,
+    AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4095,
+    AF_BLUE_STRING_OSMANYA_TOP = 4110,
+    AF_BLUE_STRING_OSMANYA_BOTTOM = 4150,
+    AF_BLUE_STRING_SAURASHTRA_TOP = 4190,
+    AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4222,
+    AF_BLUE_STRING_SHAVIAN_TOP = 4242,
+    AF_BLUE_STRING_SHAVIAN_BOTTOM = 4252,
+    AF_BLUE_STRING_SHAVIAN_DESCENDER = 4277,
+    AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4287,
+    AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4322,
+    AF_BLUE_STRING_SINHALA_TOP = 4337,
+    AF_BLUE_STRING_SINHALA_BOTTOM = 4369,
+    AF_BLUE_STRING_SINHALA_DESCENDER = 4401,
+    AF_BLUE_STRING_SUNDANESE_TOP = 4445,
+    AF_BLUE_STRING_SUNDANESE_BOTTOM = 4469,
+    AF_BLUE_STRING_SUNDANESE_DESCENDER = 4501,
+    AF_BLUE_STRING_TAI_VIET_TOP = 4509,
+    AF_BLUE_STRING_TAI_VIET_BOTTOM = 4529,
+    AF_BLUE_STRING_TAMIL_TOP = 4541,
+    AF_BLUE_STRING_TAMIL_BOTTOM = 4573,
+    AF_BLUE_STRING_TELUGU_TOP = 4605,
+    AF_BLUE_STRING_TELUGU_BOTTOM = 4633,
+    AF_BLUE_STRING_THAI_TOP = 4661,
+    AF_BLUE_STRING_THAI_BOTTOM = 4685,
+    AF_BLUE_STRING_THAI_ASCENDER = 4713,
+    AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4725,
+    AF_BLUE_STRING_THAI_DESCENDER = 4737,
+    AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4753,
+    AF_BLUE_STRING_THAI_DIGIT_TOP = 4761,
+    AF_BLUE_STRING_TIFINAGH = 4773,
+    AF_BLUE_STRING_VAI_TOP = 4805,
+    AF_BLUE_STRING_VAI_BOTTOM = 4837,
+    af_blue_1_1 = 4868,
 #ifdef AF_CONFIG_OPTION_CJK
     AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
     AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203,
@@ -355,24 +357,25 @@ FT_BEGIN_HEADER
     AF_BLUE_STRINGSET_LATP = 166,
     AF_BLUE_STRINGSET_LISU = 173,
     AF_BLUE_STRINGSET_MLYM = 176,
-    AF_BLUE_STRINGSET_MYMR = 179,
-    AF_BLUE_STRINGSET_NKOO = 184,
-    AF_BLUE_STRINGSET_NONE = 189,
-    AF_BLUE_STRINGSET_OLCK = 190,
-    AF_BLUE_STRINGSET_ORKH = 193,
-    AF_BLUE_STRINGSET_OSGE = 196,
-    AF_BLUE_STRINGSET_OSMA = 204,
-    AF_BLUE_STRINGSET_SAUR = 207,
-    AF_BLUE_STRINGSET_SHAW = 210,
-    AF_BLUE_STRINGSET_SINH = 216,
-    AF_BLUE_STRINGSET_SUND = 220,
-    AF_BLUE_STRINGSET_TAML = 224,
-    AF_BLUE_STRINGSET_TAVT = 227,
-    AF_BLUE_STRINGSET_TELU = 230,
-    AF_BLUE_STRINGSET_TFNG = 233,
-    AF_BLUE_STRINGSET_THAI = 236,
-    AF_BLUE_STRINGSET_VAII = 244,
-    af_blue_2_1 = 247,
+    AF_BLUE_STRINGSET_MONG = 179,
+    AF_BLUE_STRINGSET_MYMR = 182,
+    AF_BLUE_STRINGSET_NKOO = 187,
+    AF_BLUE_STRINGSET_NONE = 192,
+    AF_BLUE_STRINGSET_OLCK = 193,
+    AF_BLUE_STRINGSET_ORKH = 196,
+    AF_BLUE_STRINGSET_OSGE = 199,
+    AF_BLUE_STRINGSET_OSMA = 207,
+    AF_BLUE_STRINGSET_SAUR = 210,
+    AF_BLUE_STRINGSET_SHAW = 213,
+    AF_BLUE_STRINGSET_SINH = 219,
+    AF_BLUE_STRINGSET_SUND = 223,
+    AF_BLUE_STRINGSET_TAML = 227,
+    AF_BLUE_STRINGSET_TAVT = 230,
+    AF_BLUE_STRINGSET_TELU = 233,
+    AF_BLUE_STRINGSET_TFNG = 236,
+    AF_BLUE_STRINGSET_THAI = 239,
+    AF_BLUE_STRINGSET_VAII = 247,
+    af_blue_2_1 = 250,
 #ifdef AF_CONFIG_OPTION_CJK
     AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
     af_blue_2_1_1 = af_blue_2_1 + 2,
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 3b2b1cf24cec11e92b9fe48fc1fef46f532e8077..a61689bee350e3b9f4e12b49241f01baf485a3eb 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -1184,6 +1184,8 @@
 
 
         seg = edge->first;
+        if ( !seg )
+          goto Skip_Loop;
 
         do
         {
@@ -1239,13 +1241,14 @@
               edge2->flags |= AF_EDGE_SERIF;
             }
             else
-              edge->link  = edge2;
+              edge->link = edge2;
           }
 
           seg = seg->edge_next;
 
         } while ( seg != edge->first );
 
+      Skip_Loop:
         /* set the round/straight flags */
         edge->flags = AF_EDGE_NORMAL;
 
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index 7183ce4a780f5e46437349787243ff2334df101a..6a9a1e5aaaa0df491eda9a3328490d531ab9d7d5 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -443,6 +443,7 @@
       style = (AF_Style)( globals->glyph_styles[gindex] &
                           AF_STYLE_UNASSIGNED           );
 
+  Again:
     style_class          = af_style_classes[style];
     writing_system_class = af_writing_system_classes
                              [style_class->writing_system];
@@ -470,6 +471,16 @@
             writing_system_class->style_metrics_done( metrics );
 
           FT_FREE( metrics );
+
+          /* internal error code -1 indicates   */
+          /* that no blue zones have been found */
+          if ( error == -1 )
+          {
+            style = (AF_Style)( globals->glyph_styles[gindex] &
+                                AF_STYLE_UNASSIGNED           );
+            goto Again;
+          }
+
           goto Exit;
         }
       }
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index dccdcaf3457e08aee72bccfa3d82d247f9082b77..27d40248829b42ba4823b3f17f6eb5292122a5a8 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -149,7 +149,11 @@
       af_shaper_buf_destroy( face, shaper_buf );
 
       if ( !glyph_index )
+      {
+        FT_TRACE5(( "standard character missing;"
+                    " using fallback stem widths\n" ));
         goto Exit;
+      }
 
       FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
                   ch, glyph_index ));
@@ -312,7 +316,7 @@
   /* Find all blue zones.  Flat segments give the reference points, */
   /* round segments the overshoot positions.                        */
 
-  static void
+  static int
   af_latin_metrics_init_blues( AF_LatinMetrics  metrics,
                                FT_Face          face )
   {
@@ -981,10 +985,11 @@
 
     af_shaper_buf_destroy( face, shaper_buf );
 
-    /* we finally check whether blue zones are ordered; */
-    /* `ref' and `shoot' values of two blue zones must not overlap */
     if ( axis->blue_count )
     {
+      /* we finally check whether blue zones are ordered;            */
+      /* `ref' and `shoot' values of two blue zones must not overlap */
+
       FT_UInt       i;
       AF_LatinBlue  blue_sorted[AF_BLUE_STRINGSET_MAX_LEN + 2];
 
@@ -1033,11 +1038,34 @@
                       *a ));
         }
       }
+
+      FT_TRACE5(( "\n" ));
+
+      return 0;
     }
+    else
+    {
+      /* disable hinting for the current style if there are no blue zones */
 
-    FT_TRACE5(( "\n" ));
+      AF_FaceGlobals  globals = metrics->root.globals;
+      FT_UShort*      gstyles = globals->glyph_styles;
+
+      FT_Long  i;
+
+
+      FT_TRACE5(( "no blue zones found:"
+                  " hinting disabled for this style\n" ));
 
-    return;
+      for ( i = 0; i < globals->glyph_count; i++ )
+      {
+        if ( ( gstyles[i] & AF_STYLE_MASK ) == sc->style )
+          gstyles[i] = AF_STYLE_NONE_DFLT;
+      }
+
+      FT_TRACE5(( "\n" ));
+
+      return 1;
+    }
   }
 
 
@@ -1116,6 +1144,8 @@
   af_latin_metrics_init( AF_LatinMetrics  metrics,
                          FT_Face          face )
   {
+    FT_Error  error = FT_Err_Ok;
+
     FT_CharMap  oldmap = face->charmap;
 
 
@@ -1124,12 +1154,18 @@
     if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) )
     {
       af_latin_metrics_init_widths( metrics, face );
-      af_latin_metrics_init_blues( metrics, face );
+      if ( af_latin_metrics_init_blues( metrics, face ) )
+      {
+        /* use internal error code to indicate missing blue zones */
+        error = -1;
+        goto Exit;
+      }
       af_latin_metrics_check_digits( metrics, face );
     }
 
+  Exit:
     FT_Set_Charmap( face, oldmap );
-    return FT_Err_Ok;
+    return error;
   }
 
 
@@ -1443,13 +1479,13 @@
                     nn,
                     blue->ref.org,
                     blue->ref.fit / 64.0,
-                    blue->flags & AF_LATIN_BLUE_ACTIVE ? ""
-                                                       : " (inactive)",
+                    ( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? ""
+                                                           : " (inactive)",
                     nn,
                     blue->shoot.org,
                     blue->shoot.fit / 64.0,
-                    blue->flags & AF_LATIN_BLUE_ACTIVE ? ""
-                                                       : " (inactive)" ));
+                    ( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? ""
+                                                           : " (inactive)" ));
       }
 #endif
     }
diff --git a/src/autofit/afranges.c b/src/autofit/afranges.c
index c0dba818a1346fb79130f60015ca445a845d07f2..45c8bbfc95b713e9c14331f0ecaced8da390791e 100644
--- a/src/autofit/afranges.c
+++ b/src/autofit/afranges.c
@@ -664,6 +664,21 @@
   };
 
 
+  const AF_Script_UniRangeRec  af_mong_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x1800,  0x18AF ),  /* Mongolian            */
+    AF_UNIRANGE_REC( 0x11660, 0x1167F ),  /* Mongolian Supplement */
+    AF_UNIRANGE_REC(       0,       0 )
+  };
+
+  const AF_Script_UniRangeRec  af_mong_nonbase_uniranges[] =
+  {
+    AF_UNIRANGE_REC(  0x1885,  0x1886 ),
+    AF_UNIRANGE_REC(  0x18A9,  0x18A9 ),
+    AF_UNIRANGE_REC(       0,       0 )
+  };
+
+
   const AF_Script_UniRangeRec  af_mymr_uniranges[] =
   {
     AF_UNIRANGE_REC(  0x1000,  0x109F ),    /* Myanmar            */
diff --git a/src/autofit/afscript.h b/src/autofit/afscript.h
index c2f0c7ac60a312ccce8fa05c2f3aa8276efe1538..2da8c701834c662913a1f369b8decbd557c75bd1 100644
--- a/src/autofit/afscript.h
+++ b/src/autofit/afscript.h
@@ -243,6 +243,12 @@
           HINTING_BOTTOM_TO_TOP,
           "\xE0\xB4\xA0 \xE0\xB4\xB1" ) /* à´  à´± */
 
+  SCRIPT( mong, MONG,
+          "Mongolian",
+          HB_SCRIPT_MONGOLIAN,
+          HINTING_TOP_TO_BOTTOM,
+          "\xE1\xA1\x82 \xE1\xA0\xAA" ) /* á¡‚ á ª */
+
   SCRIPT( mymr, MYMR,
           "Myanmar",
           HB_SCRIPT_MYANMAR,
diff --git a/src/autofit/afstyles.h b/src/autofit/afstyles.h
index edf4f54edd72e7fa269dc636bb382bd139ba9e85..8d1d70812f1ef1aa7224096532497358d5ab6729 100644
--- a/src/autofit/afstyles.h
+++ b/src/autofit/afstyles.h
@@ -322,6 +322,13 @@
          AF_BLUE_STRINGSET_MLYM,
          AF_COVERAGE_DEFAULT )
 
+  STYLE( mong_dflt, MONG_DFLT,
+         "Mongolian default style",
+         AF_WRITING_SYSTEM_LATIN,
+         AF_SCRIPT_MONG,
+         AF_BLUE_STRINGSET_MONG,
+         AF_COVERAGE_DEFAULT )
+
   STYLE( mymr_dflt, MYMR_DFLT,
          "Myanmar default style",
          AF_WRITING_SYSTEM_LATIN,
diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c
index 0b04fde6359570dde0a4d41137372c9fb9b1d61d..a0b2c46f7b743b380e90170e53b2573a7192de61 100644
--- a/src/base/ftbbox.c
+++ b/src/base/ftbbox.c
@@ -319,9 +319,9 @@
         q2 = q2 + q1;
         q4 = q4 + q3;
         q3 = q3 + q2;
-        q4 = ( q4 + q3 ) / 8;
-        q3 = q3 / 4;
-        q2 = q2 / 2;
+        q4 = ( q4 + q3 ) >> 3;
+        q3 = q3 >> 2;
+        q2 = q2 >> 1;
       }
       else                     /* second half */
       {
@@ -330,9 +330,9 @@
         q3 = q3 + q4;
         q1 = q1 + q2;
         q2 = q2 + q3;
-        q1 = ( q1 + q2 ) / 8;
-        q2 = q2 / 4;
-        q3 = q3 / 2;
+        q1 = ( q1 + q2 ) >> 3;
+        q2 = q2 >> 2;
+        q3 = q3 >> 1;
       }
 
       /* check whether either end reached the maximum */
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index 1bdcd9eff3eb31a6bd675c0222456cff389c2486..0e0a76fe4039bb84ffa708bd52b748834ea15963 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -922,12 +922,18 @@
     else
       FT_TRACE5(( "  target bitmap: empty\n" ));
 
-    FT_TRACE5(( "  final bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
-      final_llx / 64, final_lly / 64,
-      final_urx / 64, final_ury / 64,
-      final_width, final_rows ));
+    if ( final_width && final_rows )
+      FT_TRACE5(( "  final bitmap: (%d, %d) -- (%d, %d); %d x %d\n",
+        final_llx / 64, final_lly / 64,
+        final_urx / 64, final_ury / 64,
+        final_width, final_rows ));
+    else
+      FT_TRACE5(( "  final bitmap: empty\n" ));
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
+    if ( !( final_width && final_rows ) )
+      return FT_Err_Ok;               /* nothing to do */
+
     /* for blending, set offset vector of final bitmap */
     /* temporarily to (0,0)                            */
     source_llx -= final_llx;
@@ -971,6 +977,7 @@
 
 
       pitch = target->pitch;
+
       if ( pitch < 0 )
         pitch = -pitch;
 
diff --git a/src/base/fterrors.c b/src/base/fterrors.c
index 4ef326d8e28ad2923584c5124372ee11208c29bb..84fe59028965449af149220c16cdefb9c13e2141 100644
--- a/src/base/fterrors.c
+++ b/src/base/fterrors.c
@@ -17,6 +17,7 @@
 
 
 #include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
 #include FT_ERRORS_H
 
 
diff --git a/src/base/ftinit.c b/src/base/ftinit.c
index 9d524effa925a8fcbfc070c53f22c05b1f7f4821..c73cd78b8354598ceca1cc53bf56929e0f5ee1af 100644
--- a/src/base/ftinit.c
+++ b/src/base/ftinit.c
@@ -176,6 +176,9 @@
                               module_name,
                               property_name,
                               property_value );
+
+      if ( !*p )
+        break;
     }
   }
 
diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
index 9fb49ba116edf7b3d03efbdea39796146b86089d..d9f4af4293a10f8eb6a969b6b4f26cbc6118c9b2 100644
--- a/src/base/ftlcdfil.c
+++ b/src/base/ftlcdfil.c
@@ -77,13 +77,13 @@
   /* FIR filter used by the default and light filters */
   FT_BASE_DEF( void )
   ft_lcd_filter_fir( FT_Bitmap*           bitmap,
-                     FT_Render_Mode       mode,
                      FT_LcdFiveTapFilter  weights )
   {
     FT_UInt   width  = (FT_UInt)bitmap->width;
     FT_UInt   height = (FT_UInt)bitmap->rows;
     FT_Int    pitch  = bitmap->pitch;
     FT_Byte*  origin = bitmap->buffer;
+    FT_Byte   mode   = bitmap->pixel_mode;
 
 
     /* take care of bitmap flow */
@@ -91,7 +91,7 @@
       origin += pitch * (FT_Int)( height - 1 );
 
     /* horizontal in-place FIR filter */
-    if ( mode == FT_RENDER_MODE_LCD && width >= 2 )
+    if ( mode == FT_PIXEL_MODE_LCD && width >= 2 )
     {
       FT_Byte*  line = origin;
 
@@ -134,7 +134,7 @@
     }
 
     /* vertical in-place FIR filter */
-    else if ( mode == FT_RENDER_MODE_LCD_V && height >= 2 )
+    else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 2 )
     {
       FT_Byte*  column = origin;
 
@@ -183,13 +183,13 @@
   /* intra-pixel filter used by the legacy filter */
   static void
   _ft_lcd_filter_legacy( FT_Bitmap*      bitmap,
-                         FT_Render_Mode  mode,
                          FT_Byte*        weights )
   {
     FT_UInt   width  = (FT_UInt)bitmap->width;
     FT_UInt   height = (FT_UInt)bitmap->rows;
     FT_Int    pitch  = bitmap->pitch;
     FT_Byte*  origin = bitmap->buffer;
+    FT_Byte   mode   = bitmap->pixel_mode;
 
     static const unsigned int  filters[3][3] =
     {
@@ -206,7 +206,7 @@
       origin += pitch * (FT_Int)( height - 1 );
 
     /* horizontal in-place intra-pixel filter */
-    if ( mode == FT_RENDER_MODE_LCD && width >= 3 )
+    if ( mode == FT_PIXEL_MODE_LCD && width >= 3 )
     {
       FT_Byte*  line = origin;
 
@@ -243,7 +243,7 @@
         }
       }
     }
-    else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 )
+    else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 3 )
     {
       FT_Byte*  column = origin;
 
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 3f8619d3b3cdcc9639fa606a109814632e0d5e6f..e301f8f11a42af27e55de211e59aeb0f7873a2bb 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -4059,8 +4059,8 @@
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_UInt )
-  FT_Get_Name_Index( FT_Face     face,
-                     FT_String*  glyph_name )
+  FT_Get_Name_Index( FT_Face           face,
+                     const FT_String*  glyph_name )
   {
     FT_UInt  result = 0;
 
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index 00329b46c64ddfbdba05f946dfe37145ea4157ef..0e2ba3475dad725e358e024cb9e891da3aea5cf2 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -46,8 +46,7 @@
                         void*                    user )
   {
 #undef  SCALED
-#define SCALED( x )  ( ( (x) < 0 ? -( -(x) << shift )             \
-                                 :  (  (x) << shift ) ) - delta )
+#define SCALED( x )  ( (x) * ( 1L << shift ) - delta )
 
     FT_Vector   v_last;
     FT_Vector   v_control;
@@ -621,6 +620,16 @@
 
     params->source = (void*)outline;
 
+    /* preset clip_box for direct mode */
+    if ( params->flags & FT_RASTER_FLAG_DIRECT    &&
+         !( params->flags & FT_RASTER_FLAG_CLIP ) )
+    {
+      params->clip_box.xMin = cbox.xMin >> 6;
+      params->clip_box.yMin = cbox.yMin >> 6;
+      params->clip_box.xMax = ( cbox.xMax + 63 ) >> 6;
+      params->clip_box.yMax = ( cbox.yMax + 63 ) >> 6;
+    }
+
     error = FT_ERR( Cannot_Render_Glyph );
     while ( renderer )
     {
diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c
index 826062c94ec118310e32388a66f48fcc45d49838..1b2c0f657ca24863cbb5d8ccd553066c332f3fef 100644
--- a/src/base/ftstroke.c
+++ b/src/base/ftstroke.c
@@ -86,16 +86,18 @@
 
 
     base[4].x = base[2].x;
-    b = base[1].x;
-    a = base[3].x = ( base[2].x + b ) / 2;
-    b = base[1].x = ( base[0].x + b ) / 2;
-    base[2].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    base[3].x = b >> 1;
+    base[2].x = ( a + b ) >> 2;
+    base[1].x = a >> 1;
 
     base[4].y = base[2].y;
-    b = base[1].y;
-    a = base[3].y = ( base[2].y + b ) / 2;
-    b = base[1].y = ( base[0].y + b ) / 2;
-    base[2].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    base[3].y = b >> 1;
+    base[2].y = ( a + b ) >> 2;
+    base[1].y = a >> 1;
   }
 
 
@@ -153,28 +155,32 @@
   static void
   ft_cubic_split( FT_Vector*  base )
   {
-    FT_Pos  a, b, c, d;
+    FT_Pos  a, b, c;
 
 
     base[6].x = base[3].x;
-    c = base[1].x;
-    d = base[2].x;
-    base[1].x = a = ( base[0].x + c ) / 2;
-    base[5].x = b = ( base[3].x + d ) / 2;
-    c = ( c + d ) / 2;
-    base[2].x = a = ( a + c ) / 2;
-    base[4].x = b = ( b + c ) / 2;
-    base[3].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    c = base[2].x + base[3].x;
+    base[5].x = c >> 1;
+    c += b;
+    base[4].x = c >> 2;
+    base[1].x = a >> 1;
+    a += b;
+    base[2].x = a >> 2;
+    base[3].x = ( a + c ) >> 3;
 
     base[6].y = base[3].y;
-    c = base[1].y;
-    d = base[2].y;
-    base[1].y = a = ( base[0].y + c ) / 2;
-    base[5].y = b = ( base[3].y + d ) / 2;
-    c = ( c + d ) / 2;
-    base[2].y = a = ( a + c ) / 2;
-    base[4].y = b = ( b + c ) / 2;
-    base[3].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    c = base[2].y + base[3].y;
+    base[5].y = c >> 1;
+    c += b;
+    base[4].y = c >> 2;
+    base[1].y = a >> 1;
+    a += b;
+    base[2].y = a >> 2;
+    base[3].y = ( a + c ) >> 3;
   }
 
 
diff --git a/src/base/ftver.rc b/src/base/ftver.rc
index e02a88652c78348028691c0b76be27c7e0dba0b3..13544974230e39f84440e1ab8176bfe6c857b16f 100644
--- a/src/base/ftver.rc
+++ b/src/base/ftver.rc
@@ -18,8 +18,8 @@
 
 #include<windows.h>
 
-#define FT_VERSION      2,10,0,0
-#define FT_VERSION_STR  "2.10.0"
+#define FT_VERSION      2,10,1,0
+#define FT_VERSION_STR  "2.10.1"
 
 VS_VERSION_INFO      VERSIONINFO
 FILEVERSION          FT_VERSION
diff --git a/src/bdf/bdf.h b/src/bdf/bdf.h
index 4018756f723048e4c24a379c1fdf6a16850763e8..d9abd2378fcf12c88f7c42f49b20873afc406830 100644
--- a/src/bdf/bdf.h
+++ b/src/bdf/bdf.h
@@ -109,9 +109,9 @@ FT_BEGIN_HEADER
   /* There are a set of defaults and each font has their own.   */
   typedef struct  bdf_property_t_
   {
-    char*  name;         /* Name of the property.   */
-    int    format;       /* Format of the property. */
-    int    builtin;      /* A builtin property.     */
+    const char*  name;         /* Name of the property.   */
+    int          format;       /* Format of the property. */
+    int          builtin;      /* A builtin property.     */
     union
     {
       char*          atom;
diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c
index 4a11843a1cbff61b32dc40b7a208450f93a67190..60eb93305e53df751a858cc338f7ec575e1358ad 100644
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -106,7 +106,7 @@ THE SOFTWARE.
       FT_ULong  code;
 
 
-      if ( mid > max || mid < min )
+      if ( mid >= max || mid < min )
         mid = ( min + max ) >> 1;
 
       code = encodings[mid].enc;
@@ -152,7 +152,7 @@ THE SOFTWARE.
       FT_ULong  code; /* same as BDF_encoding_el.enc */
 
 
-      if ( mid > max || mid < min )
+      if ( mid >= max || mid < min )
         mid = ( min + max ) >> 1;
 
       code = encodings[mid].enc;
@@ -216,13 +216,13 @@ THE SOFTWARE.
     bdf_font_t*      font   = bdf->bdffont;
     bdf_property_t*  prop;
 
-    char*   strings[4] = { NULL, NULL, NULL, NULL };
-    size_t  nn, len, lengths[4];
+    const char*   strings[4] = { NULL, NULL, NULL, NULL };
+    size_t        lengths[4], nn, len;
 
 
     face->style_flags = 0;
 
-    prop = bdf_get_font_property( font, (char *)"SLANT" );
+    prop = bdf_get_font_property( font, "SLANT" );
     if ( prop && prop->format == BDF_ATOM                             &&
          prop->value.atom                                             &&
          ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ||
@@ -230,30 +230,30 @@ THE SOFTWARE.
     {
       face->style_flags |= FT_STYLE_FLAG_ITALIC;
       strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' )
-                   ? (char *)"Oblique"
-                   : (char *)"Italic";
+                   ? "Oblique"
+                   : "Italic";
     }
 
-    prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" );
+    prop = bdf_get_font_property( font, "WEIGHT_NAME" );
     if ( prop && prop->format == BDF_ATOM                             &&
          prop->value.atom                                             &&
          ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
     {
       face->style_flags |= FT_STYLE_FLAG_BOLD;
-      strings[1] = (char *)"Bold";
+      strings[1] = "Bold";
     }
 
-    prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" );
+    prop = bdf_get_font_property( font, "SETWIDTH_NAME" );
     if ( prop && prop->format == BDF_ATOM                              &&
          prop->value.atom && *(prop->value.atom)                       &&
          !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
-      strings[3] = (char *)(prop->value.atom);
+      strings[3] = (const char *)(prop->value.atom);
 
-    prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" );
+    prop = bdf_get_font_property( font, "ADD_STYLE_NAME" );
     if ( prop && prop->format == BDF_ATOM                              &&
          prop->value.atom && *(prop->value.atom)                       &&
          !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
-      strings[0] = (char *)(prop->value.atom);
+      strings[0] = (const char *)(prop->value.atom);
 
     for ( len = 0, nn = 0; nn < 4; nn++ )
     {
@@ -267,7 +267,7 @@ THE SOFTWARE.
 
     if ( len == 0 )
     {
-      strings[0] = (char *)"Regular";
+      strings[0] = "Regular";
       lengths[0] = ft_strlen( strings[0] );
       len        = lengths[0] + 1;
     }
@@ -283,7 +283,7 @@ THE SOFTWARE.
 
       for ( nn = 0; nn < 4; nn++ )
       {
-        char*  src = strings[nn];
+        const char*  src = strings[nn];
 
 
         len = lengths[nn];
diff --git a/src/bdf/bdflib.c b/src/bdf/bdflib.c
index 0898b0d470d9ae18814fa1082f71ebec2a23ae23..63813f7edc9cc981996aa7f178b1207339b07ebf 100644
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -79,89 +79,89 @@
 
   static const bdf_property_t  _bdf_properties[] =
   {
-    { (char *)"ADD_STYLE_NAME",          BDF_ATOM,     1, { 0 } },
-    { (char *)"AVERAGE_WIDTH",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"AVG_CAPITAL_WIDTH",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"AVG_LOWERCASE_WIDTH",     BDF_INTEGER,  1, { 0 } },
-    { (char *)"CAP_HEIGHT",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"CHARSET_COLLECTIONS",     BDF_ATOM,     1, { 0 } },
-    { (char *)"CHARSET_ENCODING",        BDF_ATOM,     1, { 0 } },
-    { (char *)"CHARSET_REGISTRY",        BDF_ATOM,     1, { 0 } },
-    { (char *)"COMMENT",                 BDF_ATOM,     1, { 0 } },
-    { (char *)"COPYRIGHT",               BDF_ATOM,     1, { 0 } },
-    { (char *)"DEFAULT_CHAR",            BDF_CARDINAL, 1, { 0 } },
-    { (char *)"DESTINATION",             BDF_CARDINAL, 1, { 0 } },
-    { (char *)"DEVICE_FONT_NAME",        BDF_ATOM,     1, { 0 } },
-    { (char *)"END_SPACE",               BDF_INTEGER,  1, { 0 } },
-    { (char *)"FACE_NAME",               BDF_ATOM,     1, { 0 } },
-    { (char *)"FAMILY_NAME",             BDF_ATOM,     1, { 0 } },
-    { (char *)"FIGURE_WIDTH",            BDF_INTEGER,  1, { 0 } },
-    { (char *)"FONT",                    BDF_ATOM,     1, { 0 } },
-    { (char *)"FONTNAME_REGISTRY",       BDF_ATOM,     1, { 0 } },
-    { (char *)"FONT_ASCENT",             BDF_INTEGER,  1, { 0 } },
-    { (char *)"FONT_DESCENT",            BDF_INTEGER,  1, { 0 } },
-    { (char *)"FOUNDRY",                 BDF_ATOM,     1, { 0 } },
-    { (char *)"FULL_NAME",               BDF_ATOM,     1, { 0 } },
-    { (char *)"ITALIC_ANGLE",            BDF_INTEGER,  1, { 0 } },
-    { (char *)"MAX_SPACE",               BDF_INTEGER,  1, { 0 } },
-    { (char *)"MIN_SPACE",               BDF_INTEGER,  1, { 0 } },
-    { (char *)"NORM_SPACE",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"NOTICE",                  BDF_ATOM,     1, { 0 } },
-    { (char *)"PIXEL_SIZE",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"POINT_SIZE",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"QUAD_WIDTH",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_ASCENT",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_AVERAGE_WIDTH",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_AVG_CAPITAL_WIDTH",   BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_CAP_HEIGHT",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_DESCENT",             BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_END_SPACE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_FIGURE_WIDTH",        BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_MAX_SPACE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_MIN_SPACE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_NORM_SPACE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_PIXEL_SIZE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_POINT_SIZE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_PIXELSIZE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_POINTSIZE",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_QUAD_WIDTH",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SMALL_CAP_SIZE",      BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_STRIKEOUT_ASCENT",    BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_STRIKEOUT_DESCENT",   BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUBSCRIPT_SIZE",      BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUBSCRIPT_X",         BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUBSCRIPT_Y",         BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUPERSCRIPT_SIZE",    BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUPERSCRIPT_X",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_SUPERSCRIPT_Y",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_UNDERLINE_POSITION",  BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER,  1, { 0 } },
-    { (char *)"RAW_X_HEIGHT",            BDF_INTEGER,  1, { 0 } },
-    { (char *)"RELATIVE_SETWIDTH",       BDF_CARDINAL, 1, { 0 } },
-    { (char *)"RELATIVE_WEIGHT",         BDF_CARDINAL, 1, { 0 } },
-    { (char *)"RESOLUTION",              BDF_INTEGER,  1, { 0 } },
-    { (char *)"RESOLUTION_X",            BDF_CARDINAL, 1, { 0 } },
-    { (char *)"RESOLUTION_Y",            BDF_CARDINAL, 1, { 0 } },
-    { (char *)"SETWIDTH_NAME",           BDF_ATOM,     1, { 0 } },
-    { (char *)"SLANT",                   BDF_ATOM,     1, { 0 } },
-    { (char *)"SMALL_CAP_SIZE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"SPACING",                 BDF_ATOM,     1, { 0 } },
-    { (char *)"STRIKEOUT_ASCENT",        BDF_INTEGER,  1, { 0 } },
-    { (char *)"STRIKEOUT_DESCENT",       BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUBSCRIPT_SIZE",          BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUBSCRIPT_X",             BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUBSCRIPT_Y",             BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUPERSCRIPT_SIZE",        BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUPERSCRIPT_X",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"SUPERSCRIPT_Y",           BDF_INTEGER,  1, { 0 } },
-    { (char *)"UNDERLINE_POSITION",      BDF_INTEGER,  1, { 0 } },
-    { (char *)"UNDERLINE_THICKNESS",     BDF_INTEGER,  1, { 0 } },
-    { (char *)"WEIGHT",                  BDF_CARDINAL, 1, { 0 } },
-    { (char *)"WEIGHT_NAME",             BDF_ATOM,     1, { 0 } },
-    { (char *)"X_HEIGHT",                BDF_INTEGER,  1, { 0 } },
-    { (char *)"_MULE_BASELINE_OFFSET",   BDF_INTEGER,  1, { 0 } },
-    { (char *)"_MULE_RELATIVE_COMPOSE",  BDF_INTEGER,  1, { 0 } },
+    { "ADD_STYLE_NAME",          BDF_ATOM,     1, { 0 } },
+    { "AVERAGE_WIDTH",           BDF_INTEGER,  1, { 0 } },
+    { "AVG_CAPITAL_WIDTH",       BDF_INTEGER,  1, { 0 } },
+    { "AVG_LOWERCASE_WIDTH",     BDF_INTEGER,  1, { 0 } },
+    { "CAP_HEIGHT",              BDF_INTEGER,  1, { 0 } },
+    { "CHARSET_COLLECTIONS",     BDF_ATOM,     1, { 0 } },
+    { "CHARSET_ENCODING",        BDF_ATOM,     1, { 0 } },
+    { "CHARSET_REGISTRY",        BDF_ATOM,     1, { 0 } },
+    { "COMMENT",                 BDF_ATOM,     1, { 0 } },
+    { "COPYRIGHT",               BDF_ATOM,     1, { 0 } },
+    { "DEFAULT_CHAR",            BDF_CARDINAL, 1, { 0 } },
+    { "DESTINATION",             BDF_CARDINAL, 1, { 0 } },
+    { "DEVICE_FONT_NAME",        BDF_ATOM,     1, { 0 } },
+    { "END_SPACE",               BDF_INTEGER,  1, { 0 } },
+    { "FACE_NAME",               BDF_ATOM,     1, { 0 } },
+    { "FAMILY_NAME",             BDF_ATOM,     1, { 0 } },
+    { "FIGURE_WIDTH",            BDF_INTEGER,  1, { 0 } },
+    { "FONT",                    BDF_ATOM,     1, { 0 } },
+    { "FONTNAME_REGISTRY",       BDF_ATOM,     1, { 0 } },
+    { "FONT_ASCENT",             BDF_INTEGER,  1, { 0 } },
+    { "FONT_DESCENT",            BDF_INTEGER,  1, { 0 } },
+    { "FOUNDRY",                 BDF_ATOM,     1, { 0 } },
+    { "FULL_NAME",               BDF_ATOM,     1, { 0 } },
+    { "ITALIC_ANGLE",            BDF_INTEGER,  1, { 0 } },
+    { "MAX_SPACE",               BDF_INTEGER,  1, { 0 } },
+    { "MIN_SPACE",               BDF_INTEGER,  1, { 0 } },
+    { "NORM_SPACE",              BDF_INTEGER,  1, { 0 } },
+    { "NOTICE",                  BDF_ATOM,     1, { 0 } },
+    { "PIXEL_SIZE",              BDF_INTEGER,  1, { 0 } },
+    { "POINT_SIZE",              BDF_INTEGER,  1, { 0 } },
+    { "QUAD_WIDTH",              BDF_INTEGER,  1, { 0 } },
+    { "RAW_ASCENT",              BDF_INTEGER,  1, { 0 } },
+    { "RAW_AVERAGE_WIDTH",       BDF_INTEGER,  1, { 0 } },
+    { "RAW_AVG_CAPITAL_WIDTH",   BDF_INTEGER,  1, { 0 } },
+    { "RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER,  1, { 0 } },
+    { "RAW_CAP_HEIGHT",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_DESCENT",             BDF_INTEGER,  1, { 0 } },
+    { "RAW_END_SPACE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_FIGURE_WIDTH",        BDF_INTEGER,  1, { 0 } },
+    { "RAW_MAX_SPACE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_MIN_SPACE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_NORM_SPACE",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_PIXEL_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_POINT_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_PIXELSIZE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_POINTSIZE",           BDF_INTEGER,  1, { 0 } },
+    { "RAW_QUAD_WIDTH",          BDF_INTEGER,  1, { 0 } },
+    { "RAW_SMALL_CAP_SIZE",      BDF_INTEGER,  1, { 0 } },
+    { "RAW_STRIKEOUT_ASCENT",    BDF_INTEGER,  1, { 0 } },
+    { "RAW_STRIKEOUT_DESCENT",   BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUBSCRIPT_SIZE",      BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUBSCRIPT_X",         BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUBSCRIPT_Y",         BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUPERSCRIPT_SIZE",    BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUPERSCRIPT_X",       BDF_INTEGER,  1, { 0 } },
+    { "RAW_SUPERSCRIPT_Y",       BDF_INTEGER,  1, { 0 } },
+    { "RAW_UNDERLINE_POSITION",  BDF_INTEGER,  1, { 0 } },
+    { "RAW_UNDERLINE_THICKNESS", BDF_INTEGER,  1, { 0 } },
+    { "RAW_X_HEIGHT",            BDF_INTEGER,  1, { 0 } },
+    { "RELATIVE_SETWIDTH",       BDF_CARDINAL, 1, { 0 } },
+    { "RELATIVE_WEIGHT",         BDF_CARDINAL, 1, { 0 } },
+    { "RESOLUTION",              BDF_INTEGER,  1, { 0 } },
+    { "RESOLUTION_X",            BDF_CARDINAL, 1, { 0 } },
+    { "RESOLUTION_Y",            BDF_CARDINAL, 1, { 0 } },
+    { "SETWIDTH_NAME",           BDF_ATOM,     1, { 0 } },
+    { "SLANT",                   BDF_ATOM,     1, { 0 } },
+    { "SMALL_CAP_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { "SPACING",                 BDF_ATOM,     1, { 0 } },
+    { "STRIKEOUT_ASCENT",        BDF_INTEGER,  1, { 0 } },
+    { "STRIKEOUT_DESCENT",       BDF_INTEGER,  1, { 0 } },
+    { "SUBSCRIPT_SIZE",          BDF_INTEGER,  1, { 0 } },
+    { "SUBSCRIPT_X",             BDF_INTEGER,  1, { 0 } },
+    { "SUBSCRIPT_Y",             BDF_INTEGER,  1, { 0 } },
+    { "SUPERSCRIPT_SIZE",        BDF_INTEGER,  1, { 0 } },
+    { "SUPERSCRIPT_X",           BDF_INTEGER,  1, { 0 } },
+    { "SUPERSCRIPT_Y",           BDF_INTEGER,  1, { 0 } },
+    { "UNDERLINE_POSITION",      BDF_INTEGER,  1, { 0 } },
+    { "UNDERLINE_THICKNESS",     BDF_INTEGER,  1, { 0 } },
+    { "WEIGHT",                  BDF_CARDINAL, 1, { 0 } },
+    { "WEIGHT_NAME",             BDF_ATOM,     1, { 0 } },
+    { "X_HEIGHT",                BDF_INTEGER,  1, { 0 } },
+    { "_MULE_BASELINE_OFFSET",   BDF_INTEGER,  1, { 0 } },
+    { "_MULE_RELATIVE_COMPOSE",  BDF_INTEGER,  1, { 0 } },
   };
 
   static const unsigned long
@@ -364,7 +364,7 @@
 
   /* An empty string for empty fields. */
 
-  static const char  empty[1] = { 0 };      /* XXX eliminate this */
+  static const char  empty[] = "";      /* XXX eliminate this */
 
 
   static char *
@@ -407,13 +407,14 @@
 
   static FT_Error
   _bdf_list_split( _bdf_list_t*   list,
-                   char*          separators,
+                   const char*    separators,
                    char*          line,
                    unsigned long  linelen )
   {
     unsigned long  final_empty;
     int            mult;
-    char           *sp, *ep, *end;
+    const char     *sp, *end;
+    char           *ep;
     char           seps[32];
     FT_Error       error = FT_Err_Ok;
 
@@ -473,7 +474,7 @@
       }
 
       /* Assign the field appropriately. */
-      list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty;
+      list->field[list->used++] = ( ep > sp ) ? (char*)sp : (char*)empty;
 
       sp = ep;
 
@@ -692,7 +693,7 @@
 
   /* Routine to convert a decimal ASCII string to an unsigned long integer. */
   static unsigned long
-  _bdf_atoul( char*  s )
+  _bdf_atoul( const char*  s )
   {
     unsigned long  v;
 
@@ -717,7 +718,7 @@
 
   /* Routine to convert a decimal ASCII string to a signed long integer. */
   static long
-  _bdf_atol( char*  s )
+  _bdf_atol( const char*  s )
   {
     long  v, neg;
 
@@ -750,7 +751,7 @@
 
   /* Routine to convert a decimal ASCII string to an unsigned short integer. */
   static unsigned short
-  _bdf_atous( char*  s )
+  _bdf_atous( const char*  s )
   {
     unsigned short  v;
 
@@ -775,7 +776,7 @@
 
   /* Routine to convert a decimal ASCII string to a signed short integer. */
   static short
-  _bdf_atos( char*  s )
+  _bdf_atos( const char*  s )
   {
     short  v, neg;
 
@@ -828,7 +829,7 @@
 
 
   static FT_Error
-  bdf_create_property( char*        name,
+  bdf_create_property( const char*  name,
                        int          format,
                        bdf_font_t*  font )
   {
@@ -998,7 +999,7 @@
 
     FT_MEM_COPY( name, font->name, len );
 
-    error = _bdf_list_split( &list, (char *)"-", name, (unsigned long)len );
+    error = _bdf_list_split( &list, "-", name, (unsigned long)len );
     if ( error )
       goto Fail;
 
@@ -1097,7 +1098,7 @@
 
   static FT_Error
   _bdf_add_property( bdf_font_t*    font,
-                     char*          name,
+                     const char*    name,
                      char*          value,
                      unsigned long  lineno )
   {
@@ -1336,7 +1337,7 @@
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
       p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1] );
@@ -1423,7 +1424,7 @@
       /* encoding can be checked for an unencoded character.      */
       FT_FREE( p->glyph_name );
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
@@ -1461,7 +1462,7 @@
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
@@ -1615,7 +1616,7 @@
     /* Expect the SWIDTH (scalable width) field next. */
     if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 )
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
@@ -1628,7 +1629,7 @@
     /* Expect the DWIDTH (scalable width) field next. */
     if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 )
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
@@ -1653,7 +1654,7 @@
     /* Expect the BBX field next. */
     if ( _bdf_strncmp( line, "BBX", 3 ) == 0 )
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
@@ -1796,7 +1797,7 @@
       {
         p->font->font_ascent = p->font->bbx.ascent;
         ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
-        error = _bdf_add_property( p->font, (char *)"FONT_ASCENT",
+        error = _bdf_add_property( p->font, "FONT_ASCENT",
                                    nbuf, lineno );
         if ( error )
           goto Exit;
@@ -1808,7 +1809,7 @@
       {
         p->font->font_descent = p->font->bbx.descent;
         ft_sprintf( nbuf, "%hd", p->font->bbx.descent );
-        error = _bdf_add_property( p->font, (char *)"FONT_DESCENT",
+        error = _bdf_add_property( p->font, "FONT_DESCENT",
                                    nbuf, lineno );
         if ( error )
           goto Exit;
@@ -1846,7 +1847,7 @@
     }
     else
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
       name = p->list.field[0];
@@ -1976,7 +1977,7 @@
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
@@ -2015,7 +2016,7 @@
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
@@ -2038,7 +2039,7 @@
     /* The next thing to check for is the FONT field. */
     if ( _bdf_strncmp( line, "FONT", 4 ) == 0 )
     {
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
       _bdf_list_shift( &p->list, 1 );
@@ -2081,7 +2082,7 @@
         goto Exit;
       }
 
-      error = _bdf_list_split( &p->list, (char *)" +", line, linelen );
+      error = _bdf_list_split( &p->list, " +", line, linelen );
       if ( error )
         goto Exit;
 
@@ -2136,7 +2137,7 @@
       /* for compiling fonts.                                   */
       p->font->font_ascent = p->font->bbx.ascent;
       ft_sprintf( nbuf, "%hd", p->font->bbx.ascent );
-      error = _bdf_add_property( p->font, (char *)"FONT_ASCENT",
+      error = _bdf_add_property( p->font, "FONT_ASCENT",
                                  nbuf, lineno );
       if ( error )
         goto Exit;
@@ -2144,7 +2145,7 @@
 
       p->font->font_descent = p->font->bbx.descent;
       ft_sprintf( nbuf, "%hd", p->font->bbx.descent );
-      error = _bdf_add_property( p->font, (char *)"FONT_DESCENT",
+      error = _bdf_add_property( p->font, "FONT_DESCENT",
                                  nbuf, lineno );
       if ( error )
         goto Exit;
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index bbd5c40329715d0768fbce0303e73c04846797ee..23249898115e61071091b767dde7b3b520fd6109 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -381,8 +381,8 @@
 
 
   static FT_UInt
-  cff_get_name_index( CFF_Face    face,
-                      FT_String*  glyph_name )
+  cff_get_name_index( CFF_Face          face,
+                      const FT_String*  glyph_name )
   {
     CFF_Font            cff;
     CFF_Charset         charset;
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 1a1030c06509fa92c564922f8b010a1827190330..f76245f30b0ac460447127c3a799e850dcec6eec 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -962,7 +962,7 @@
           cffface->style_name = style_name;
         else
           /* assume "Regular" style if we don't know better */
-          cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
+          cffface->style_name = cff_strcpy( memory, "Regular" );
 
         /********************************************************************
          *
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index fa806f1a9059a7c726af6b679b34f117de71671d..008752c3aea2e7e0ede3385f652a1749dd433e98 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -77,6 +77,23 @@
   }
 
 
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+  static void
+  finalize_t2_strings( FT_Memory  memory,
+                       void*      data,
+                       void*      user )
+  {
+    CFF_T2_String  t2 = (CFF_T2_String)data;
+
+
+    FT_UNUSED( user );
+
+    memory->free( memory, t2->start );
+    memory->free( memory, data );
+  }
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
+
   FT_LOCAL_DEF( void )
   cff_parser_done( CFF_Parser  parser )
   {
@@ -84,13 +101,65 @@
 
 
     FT_FREE( parser->stack );
+
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+    FT_List_Finalize( &parser->t2_strings,
+                      finalize_t2_strings,
+                      memory,
+                      NULL );
+#endif
+  }
+
+
+  /* Assuming `first >= last'. */
+
+  static FT_Error
+  cff_parser_within_limits( CFF_Parser  parser,
+                            FT_Byte*    first,
+                            FT_Byte*    last )
+  {
+#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
+
+    /* Fast path for regular FreeType builds with the "new" engine; */
+    /*   `first >= parser->start' can be assumed.                   */
+
+    FT_UNUSED( first );
+
+    return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument );
+
+#else /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
+    FT_ListNode  node;
+
+
+    if ( first >= parser->start &&
+         last  <  parser->limit )
+      return FT_Err_Ok;
+
+    node = parser->t2_strings.head;
+
+    while ( node )
+    {
+      CFF_T2_String  t2 = (CFF_T2_String)node->data;
+
+
+      if ( first >= t2->start &&
+           last  <  t2->limit )
+        return FT_Err_Ok;
+
+      node = node->next;
+    }
+
+    return FT_THROW( Invalid_Argument );
+
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
   }
 
 
   /* read an integer */
   static FT_Long
-  cff_parse_integer( FT_Byte*  start,
-                     FT_Byte*  limit )
+  cff_parse_integer( CFF_Parser  parser,
+                     FT_Byte*    start )
   {
     FT_Byte*  p   = start;
     FT_Int    v   = *p++;
@@ -99,14 +168,14 @@
 
     if ( v == 28 )
     {
-      if ( p + 2 > limit )
+      if ( cff_parser_within_limits( parser, p, p + 1 ) )
         goto Bad;
 
       val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
     }
     else if ( v == 29 )
     {
-      if ( p + 4 > limit )
+      if ( cff_parser_within_limits( parser, p, p + 3 ) )
         goto Bad;
 
       val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
@@ -120,14 +189,14 @@
     }
     else if ( v < 251 )
     {
-      if ( p + 1 > limit )
+      if ( cff_parser_within_limits( parser, p, p ) )
         goto Bad;
 
       val = ( v - 247 ) * 256 + p[0] + 108;
     }
     else
     {
-      if ( p + 1 > limit )
+      if ( cff_parser_within_limits( parser, p, p ) )
         goto Bad;
 
       val = -( v - 251 ) * 256 - p[0] - 108;
@@ -176,10 +245,10 @@
 
   /* read a real */
   static FT_Fixed
-  cff_parse_real( FT_Byte*  start,
-                  FT_Byte*  limit,
-                  FT_Long   power_ten,
-                  FT_Long*  scaling )
+  cff_parse_real( CFF_Parser  parser,
+                  FT_Byte*    start,
+                  FT_Long     power_ten,
+                  FT_Long*    scaling )
   {
     FT_Byte*  p = start;
     FT_Int    nib;
@@ -214,7 +283,7 @@
         p++;
 
         /* Make sure we don't read past the end. */
-        if ( p >= limit )
+        if ( cff_parser_within_limits( parser, p, p ) )
           goto Bad;
       }
 
@@ -251,7 +320,7 @@
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( p >= limit )
+          if ( cff_parser_within_limits( parser, p, p ) )
             goto Bad;
         }
 
@@ -290,7 +359,7 @@
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( p >= limit )
+          if ( cff_parser_within_limits( parser, p, p ) )
             goto Bad;
         }
 
@@ -457,7 +526,7 @@
     if ( **d == 30 )
     {
       /* binary-coded decimal is truncated to integer */
-      return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
+      return cff_parse_real( parser, *d, 0, NULL ) >> 16;
     }
 
     else if ( **d == 255 )
@@ -483,7 +552,7 @@
     }
 
     else
-      return cff_parse_integer( *d, parser->limit );
+      return cff_parse_integer( parser, *d );
   }
 
 
@@ -494,10 +563,10 @@
             FT_Long     scaling )
   {
     if ( **d == 30 )
-      return cff_parse_real( *d, parser->limit, scaling, NULL );
+      return cff_parse_real( parser, *d, scaling, NULL );
     else
     {
-      FT_Long  val = cff_parse_integer( *d, parser->limit );
+      FT_Long  val = cff_parse_integer( parser, *d );
 
 
       if ( scaling )
@@ -562,14 +631,14 @@
     FT_ASSERT( scaling );
 
     if ( **d == 30 )
-      return cff_parse_real( *d, parser->limit, 0, scaling );
+      return cff_parse_real( parser, *d, 0, scaling );
     else
     {
       FT_Long  number;
       FT_Int   integer_length;
 
 
-      number = cff_parse_integer( d[0], d[1] );
+      number = cff_parse_integer( parser, d[0] );
 
       if ( number > 0x7FFFL )
       {
@@ -1122,18 +1191,6 @@
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
 
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-  static void
-  destruct_t2s_item( FT_Memory  memory,
-                     void*      data,
-                     void*      user )
-  {
-    FT_UNUSED( user );
-    memory->free( memory, data );
-  }
-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
-
-
   FT_LOCAL_DEF( FT_Error )
   cff_parser_run( CFF_Parser  parser,
                   FT_Byte*    start,
@@ -1147,11 +1204,6 @@
 
     FT_Library  library = parser->library;
     FT_Memory   memory  = library->memory;
-
-    FT_ListRec  t2s;
-
-
-    FT_ZERO( &t2s );
 #endif
 
     parser->top    = parser->stack;
@@ -1212,9 +1264,11 @@
         FT_Byte*     charstring_base;
         FT_ULong     charstring_len;
 
-        FT_Fixed*    stack;
-        FT_ListNode  node;
-        FT_Byte*     q;
+        FT_Fixed*     stack;
+        FT_ListNode   node;
+        CFF_T2_String t2;
+        size_t        t2_size;
+        FT_Byte*      q;
 
 
         charstring_base = ++p;
@@ -1261,16 +1315,26 @@
         if ( !node )
           goto Out_Of_Memory_Error;
 
+        FT_List_Add( &parser->t2_strings, node );
+
+        t2 = (CFF_T2_String)memory->alloc( memory,
+                                           sizeof ( CFF_T2_StringRec ) );
+        if ( !t2 )
+          goto Out_Of_Memory_Error;
+
+        node->data = t2;
+
         /* `5' is the conservative upper bound of required bytes per stack */
         /* element.                                                        */
-        q = (FT_Byte*)memory->alloc( memory,
-                                     5 * ( decoder.top - decoder.stack ) );
+
+        t2_size = 5 * ( decoder.top - decoder.stack );
+
+        q = (FT_Byte*)memory->alloc( memory, t2_size );
         if ( !q )
           goto Out_Of_Memory_Error;
 
-        node->data = q;
-
-        FT_List_Add( &t2s, node );
+        t2->start = q;
+        t2->limit = q + t2_size;
 
         stack = decoder.stack;
 
@@ -1531,9 +1595,6 @@
     } /* while ( p < limit ) */
 
   Exit:
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-    FT_List_Finalize( &t2s, destruct_t2s_item, memory, NULL );
-#endif
     return error;
 
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
diff --git a/src/cff/cffparse.h b/src/cff/cffparse.h
index bac32f9449113270c45f07303e5faaadc93f2919..4e74709a2d6006043fd64e49e16a9594840f3b04 100644
--- a/src/cff/cffparse.h
+++ b/src/cff/cffparse.h
@@ -60,6 +60,10 @@ FT_BEGIN_HEADER
     FT_Byte**   top;
     FT_UInt     stackSize;  /* allocated size */
 
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+    FT_ListRec  t2_strings;
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
     FT_UInt     object_code;
     void*       object;
 
@@ -130,6 +134,15 @@ FT_BEGIN_HEADER
 FT_END_HEADER
 
 
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+  typedef struct  CFF_T2_String_
+  {
+    FT_Byte*  start;
+    FT_Byte*  limit;
+
+  } CFF_T2_StringRec, *CFF_T2_String;
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
 #endif /* CFFPARSE_H_ */
 
 
diff --git a/src/gzip/ftgzip.c b/src/gzip/ftgzip.c
index 7494c2aac9af66a715a40c853450003755f038f3..ed68745c2c14630fa941dcfd4745cd424c17a309 100644
--- a/src/gzip/ftgzip.c
+++ b/src/gzip/ftgzip.c
@@ -747,7 +747,7 @@
     stream.zfree  = (free_func) ft_gzip_free;
     stream.opaque = memory;
 
-    err = inflateInit2( &stream, MAX_WBITS );
+    err = inflateInit2( &stream, MAX_WBITS|32 );
     if ( err != Z_OK )
       return FT_THROW( Invalid_Argument );
 
diff --git a/src/pcf/pcf.h b/src/pcf/pcf.h
index 529dd3adf867e50e4c2c8bfb7b851e6448da6a1c..33be4bcd85f625026b04badf188599791a76c11e 100644
--- a/src/pcf/pcf.h
+++ b/src/pcf/pcf.h
@@ -99,7 +99,8 @@ FT_BEGIN_HEADER
     FT_Short  ascent;
     FT_Short  descent;
     FT_Short  attributes;
-    FT_ULong  bits;
+
+    FT_ULong  bits;  /* offset into the PCF_BITMAPS table */
 
   } PCF_MetricRec, *PCF_Metric;
 
diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c
index 54bbb9d119c17a4d279ed3723b54e3cef6f095ae..b39592c794bb6219bb79e0ea12123ff9491a2cad 100644
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -122,9 +122,9 @@ THE SOFTWARE.
          charcodeCol > enc->lastCol  )
       return 0;
 
-    return (FT_UInt)enc->offset[ ( charcodeRow - enc->firstRow ) *
-                                 ( enc->lastCol - enc->firstCol + 1 ) +
-                                   charcodeCol - enc->firstCol          ];
+    return (FT_UInt)enc->offset[( charcodeRow - enc->firstRow ) *
+                                  ( enc->lastCol - enc->firstCol + 1 ) +
+                                charcodeCol - enc->firstCol];
   }
 
 
@@ -160,9 +160,9 @@ THE SOFTWARE.
 
       charcode = (FT_UInt32)( charcodeRow * 256 + charcodeCol );
 
-      result = (FT_UInt)enc->offset[ ( charcodeRow - enc->firstRow ) *
-                                     ( enc->lastCol - enc->firstCol + 1 ) +
-                                       charcodeCol - enc->firstCol          ];
+      result = (FT_UInt)enc->offset[( charcodeRow - enc->firstRow ) *
+                                      ( enc->lastCol - enc->firstCol + 1 ) +
+                                    charcodeCol - enc->firstCol];
       if ( result != 0xFFFFU )
         break;
     }
diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c
index 71143ecfb54f3124acc8b73dbb635b3c8785cda0..2ffe22d71c986eabfb7020857e5304617881eeb4 100644
--- a/src/pcf/pcfread.c
+++ b/src/pcf/pcfread.c
@@ -743,33 +743,39 @@ THE SOFTWARE.
     if ( !orig_nmetrics )
       return FT_THROW( Invalid_Table );
 
-    /* PCF is a format from ancient times; Unicode was in its       */
-    /* infancy, and widely used two-byte character sets for CJK     */
-    /* scripts (Big 5, GB 2312, JIS X 0208, etc.) did have at most  */
-    /* 15000 characters.  Even the more exotic CNS 11643 and CCCII  */
-    /* standards, which were essentially three-byte character sets, */
-    /* provided less then 65536 assigned characters.                */
-    /*                                                              */
-    /* While technically possible to have a larger number of glyphs */
-    /* in PCF files, we thus limit the number to 65536.             */
-    if ( orig_nmetrics > 65536 )
+    /*
+     * PCF is a format from ancient times; Unicode was in its infancy, and
+     * widely used two-byte character sets for CJK scripts (Big 5, GB 2312,
+     * JIS X 0208, etc.) did have at most 15000 characters.  Even the more
+     * exotic CNS 11643 and CCCII standards, which were essentially
+     * three-byte character sets, provided less then 65536 assigned
+     * characters.
+     *
+     * While technically possible to have a larger number of glyphs in PCF
+     * files, we thus limit the number to 65535, taking into account that we
+     * synthesize the metrics of glyph 0 to be a copy of the `default
+     * character', and that 0xFFFF in the encodings array indicates a
+     * missing glyph.
+     */
+    if ( orig_nmetrics > 65534 )
     {
       FT_TRACE0(( "pcf_get_metrics:"
-                  " only loading first 65536 metrics\n" ));
-      nmetrics = 65536;
+                  " only loading first 65534 metrics\n" ));
+      nmetrics = 65534;
     }
     else
       nmetrics = orig_nmetrics;
 
-    face->nmetrics = nmetrics;
+    face->nmetrics = nmetrics + 1;
 
-    if ( FT_NEW_ARRAY( face->metrics, nmetrics ) )
+    if ( FT_NEW_ARRAY( face->metrics, face->nmetrics ) )
       return error;
 
-    metrics = face->metrics;
+    /* we handle glyph index 0 later on */
+    metrics = face->metrics + 1;
 
     FT_TRACE4(( "\n" ));
-    for ( i = 0; i < nmetrics; i++, metrics++ )
+    for ( i = 1; i < face->nmetrics; i++, metrics++ )
     {
       FT_TRACE5(( "  idx %ld:", i ));
       error = pcf_get_metric( stream, format, metrics );
@@ -808,12 +814,10 @@ THE SOFTWARE.
   pcf_get_bitmaps( FT_Stream  stream,
                    PCF_Face   face )
   {
-    FT_Error   error;
-    FT_Memory  memory  = FT_FACE( face )->memory;
-    FT_ULong*  offsets = NULL;
-    FT_ULong   bitmapSizes[GLYPHPADOPTIONS];
-    FT_ULong   format, size;
-    FT_ULong   nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
+    FT_Error  error;
+    FT_ULong  bitmapSizes[GLYPHPADOPTIONS];
+    FT_ULong  format, size, pos;
+    FT_ULong  nbitmaps, orig_nbitmaps, i, sizebitmaps = 0;
 
 
     error = pcf_seek_to_table_type( stream,
@@ -859,31 +863,46 @@ THE SOFTWARE.
     FT_TRACE4(( "  number of bitmaps: %ld\n", orig_nbitmaps ));
 
     /* see comment in `pcf_get_metrics' */
-    if ( orig_nbitmaps > 65536 )
+    if ( orig_nbitmaps > 65534 )
     {
       FT_TRACE0(( "pcf_get_bitmaps:"
-                  " only loading first 65536 bitmaps\n" ));
-      nbitmaps = 65536;
+                  " only loading first 65534 bitmaps\n" ));
+      nbitmaps = 65534;
     }
     else
       nbitmaps = orig_nbitmaps;
 
-    if ( nbitmaps != face->nmetrics )
+    /* no extra bitmap for glyph 0 */
+    if ( nbitmaps != face->nmetrics - 1 )
       return FT_THROW( Invalid_File_Format );
 
-    if ( FT_NEW_ARRAY( offsets, nbitmaps ) )
-      return error;
+    /* start position of bitmap data */
+    pos = stream->pos + nbitmaps * 4 + 4 * 4;
 
     FT_TRACE5(( "\n" ));
-    for ( i = 0; i < nbitmaps; i++ )
+    for ( i = 1; i <= nbitmaps; i++ )
     {
+      FT_ULong  offset;
+
+
       if ( PCF_BYTE_ORDER( format ) == MSBFirst )
-        (void)FT_READ_ULONG( offsets[i] );
+        (void)FT_READ_ULONG( offset );
       else
-        (void)FT_READ_ULONG_LE( offsets[i] );
+        (void)FT_READ_ULONG_LE( offset );
 
       FT_TRACE5(( "  bitmap %lu: offset %lu (0x%lX)\n",
-                  i, offsets[i], offsets[i] ));
+                  i, offset, offset ));
+
+      /* right now, we only check the offset with a rough estimate; */
+      /* actual bitmaps are only loaded on demand                   */
+      if ( offset > size )
+      {
+        FT_TRACE0(( "pcf_get_bitmaps:"
+                    " invalid offset to bitmap data of glyph %lu\n", i ));
+        face->metrics[i].bits = pos;
+      }
+      else
+        face->metrics[i].bits = pos + offset;
     }
     if ( error )
       goto Bail;
@@ -910,24 +929,9 @@ THE SOFTWARE.
 
     FT_UNUSED( sizebitmaps );       /* only used for debugging */
 
-    /* right now, we only check the bitmap offsets; */
-    /* actual bitmaps are only loaded on demand     */
-    for ( i = 0; i < nbitmaps; i++ )
-    {
-      /* rough estimate */
-      if ( offsets[i] > size )
-      {
-        FT_TRACE0(( "pcf_get_bitmaps:"
-                    " invalid offset to bitmap data of glyph %lu\n", i ));
-      }
-      else
-        face->metrics[i].bits = stream->pos + offsets[i];
-    }
-
     face->bitmapsFormat = format;
 
   Bail:
-    FT_FREE( offsets );
     return error;
   }
 
@@ -1062,41 +1066,52 @@ THE SOFTWARE.
       defaultCharCol = enc->firstCol;
     }
 
-    /* FreeType mandates that glyph index 0 is the `undefined glyph',  */
-    /* which PCF calls the `default character'.  For this reason, we   */
-    /* swap the positions of glyph index 0 and the index corresponding */
-    /* to `defaultChar' in case they are different.                    */
-
-    /* `stream->cursor' still points at the beginning of the frame; */
-    /* we can thus easily get the offset to the default character   */
+    /*
+     * FreeType mandates that glyph index 0 is the `undefined glyph', which
+     * PCF calls the `default character'.  However, FreeType needs glyph
+     * index 0 to be used for the undefined glyph only, which is is not the
+     * case for PCF.  For this reason, we add one slot for glyph index 0 and
+     * simply copy the default character to it.
+     *
+     * `stream->cursor' still points to the beginning of the frame; we can
+     * thus easily get the offset to the default character.
+     */
     pos = stream->cursor +
             2 * ( ( defaultCharRow - enc->firstRow ) *
-                  ( enc->lastCol - enc->firstCol + 1 ) +
-                    defaultCharCol - enc->firstCol       );
+                    ( enc->lastCol - enc->firstCol + 1 ) +
+                  defaultCharCol - enc->firstCol );
 
     if ( PCF_BYTE_ORDER( format ) == MSBFirst )
       defaultCharEncodingOffset = FT_PEEK_USHORT( pos );
     else
       defaultCharEncodingOffset = FT_PEEK_USHORT_LE( pos );
 
-    if ( defaultCharEncodingOffset >= face->nmetrics )
+    if ( defaultCharEncodingOffset == 0xFFFF )
     {
       FT_TRACE0(( "pcf_get_encodings:"
-                  " Invalid glyph index for default character,"
-                  " setting to zero\n" ));
-      defaultCharEncodingOffset = 0;
+                  " No glyph for default character,\n"
+                  "                  "
+                  " setting it to the first glyph of the font\n" ));
+      defaultCharEncodingOffset = 1;
     }
-
-    if ( defaultCharEncodingOffset )
+    else
     {
-      /* do the swapping */
-      PCF_MetricRec  tmp = face->metrics[defaultCharEncodingOffset];
-
+      defaultCharEncodingOffset++;
 
-      face->metrics[defaultCharEncodingOffset] = face->metrics[0];
-      face->metrics[0]                         = tmp;
+      if ( defaultCharEncodingOffset >= face->nmetrics )
+      {
+        FT_TRACE0(( "pcf_get_encodings:"
+                    " Invalid glyph index for default character,\n"
+                    "                  "
+                    " setting it to the first glyph of the font\n" ));
+        defaultCharEncodingOffset = 1;
+      }
     }
 
+    /* copy metrics of default character to index 0 */
+    face->metrics[0] = face->metrics[defaultCharEncodingOffset];
+
+    /* now loop over all values */
     offset = enc->offset;
     for ( i = enc->firstRow; i <= enc->lastRow; i++ )
     {
@@ -1111,15 +1126,9 @@ THE SOFTWARE.
         else
           encodingOffset = FT_GET_USHORT_LE();
 
-        if ( encodingOffset != 0xFFFFU )
-        {
-          if ( encodingOffset == defaultCharEncodingOffset )
-            encodingOffset = 0;
-          else if ( encodingOffset == 0 )
-            encodingOffset = defaultCharEncodingOffset;
-        }
-
-        *offset++ = encodingOffset;
+        /* everything is off by 1 due to the artificial glyph 0 */
+        *offset++ = encodingOffset == 0xFFFF ? 0xFFFF
+                                             : encodingOffset + 1;
       }
     }
     FT_Stream_ExitFrame( stream );
@@ -1303,9 +1312,8 @@ THE SOFTWARE.
 
     PCF_Property  prop;
 
-    size_t  nn, len;
-    char*   strings[4] = { NULL, NULL, NULL, NULL };
-    size_t  lengths[4];
+    const char*  strings[4] = { NULL, NULL, NULL, NULL };
+    size_t       lengths[4], nn, len;
 
 
     face->style_flags = 0;
@@ -1317,8 +1325,8 @@ THE SOFTWARE.
     {
       face->style_flags |= FT_STYLE_FLAG_ITALIC;
       strings[2] = ( *(prop->value.atom) == 'O' ||
-                     *(prop->value.atom) == 'o' ) ? (char *)"Oblique"
-                                                  : (char *)"Italic";
+                     *(prop->value.atom) == 'o' ) ? "Oblique"
+                                                  : "Italic";
     }
 
     prop = pcf_find_property( pcf, "WEIGHT_NAME" );
@@ -1326,20 +1334,20 @@ THE SOFTWARE.
          ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) )
     {
       face->style_flags |= FT_STYLE_FLAG_BOLD;
-      strings[1] = (char*)"Bold";
+      strings[1] = "Bold";
     }
 
     prop = pcf_find_property( pcf, "SETWIDTH_NAME" );
     if ( prop && prop->isString                                        &&
          *(prop->value.atom)                                           &&
          !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
-      strings[3] = (char*)( prop->value.atom );
+      strings[3] = (const char*)( prop->value.atom );
 
     prop = pcf_find_property( pcf, "ADD_STYLE_NAME" );
     if ( prop && prop->isString                                        &&
          *(prop->value.atom)                                           &&
          !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) )
-      strings[0] = (char*)( prop->value.atom );
+      strings[0] = (const char*)( prop->value.atom );
 
     for ( len = 0, nn = 0; nn < 4; nn++ )
     {
@@ -1353,7 +1361,7 @@ THE SOFTWARE.
 
     if ( len == 0 )
     {
-      strings[0] = (char*)"Regular";
+      strings[0] = "Regular";
       lengths[0] = ft_strlen( strings[0] );
       len        = lengths[0] + 1;
     }
@@ -1369,7 +1377,7 @@ THE SOFTWARE.
 
       for ( nn = 0; nn < 4; nn++ )
       {
-        char*  src = strings[nn];
+        const char*  src = strings[nn];
 
 
         len = lengths[nn];
diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c
index e103a3f6f28a5561596a3893c4d7c3cdbc57055e..9765f95c2fe70aa638495b8042c4f8e1e61b71f4 100644
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -378,7 +378,7 @@
       outline->flags &= ~FT_OUTLINE_OWNER;
       outline->flags |= FT_OUTLINE_REVERSE_FILL;
 
-      if ( size && pfrsize->metrics.y_ppem < 24 )
+      if ( pfrsize->metrics.y_ppem < 24 )
         outline->flags |= FT_OUTLINE_HIGH_PRECISION;
 
       /* compute the advance vector */
diff --git a/src/psaux/afmparse.c b/src/psaux/afmparse.c
index 49225a9f78e1dbb807ee1a8a9eefb5b2a86bf1fd..f78adbba3d8a8f2698114af506f1b08efd4d7e0c 100644
--- a/src/psaux/afmparse.c
+++ b/src/psaux/afmparse.c
@@ -953,7 +953,8 @@
         error = afm_parse_kern_data( parser );
         if ( error )
           goto Fail;
-        /* fall through since we only support kern data */
+        /* we only support kern data, so ... */
+        /* fall through                      */
 
       case AFM_TOKEN_ENDFONTMETRICS:
         return FT_Err_Ok;
diff --git a/src/psaux/psfixed.h b/src/psaux/psfixed.h
index fd3460f34afb9315192a39347293d4f0b1d1559e..7dff9ef1bd5b0fe059baafa08f7ab0fb8d3a9f33 100644
--- a/src/psaux/psfixed.h
+++ b/src/psaux/psfixed.h
@@ -72,8 +72,7 @@ FT_BEGIN_HEADER
 #define cf2_fixedFraction( x )                                           \
           ( (x) - cf2_fixedFloor( x ) )
 #define cf2_fracToFixed( x )                                             \
-          ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 )                       \
-                    :  ( (  (x) + 0x2000 ) >> 14 ) )
+          ( ( (x) + 0x2000 - ( (x) < 0 ) ) >> 14 )
 
 
   /* signed numeric types */
diff --git a/src/psaux/psfont.c b/src/psaux/psfont.c
index bb5faa38f5c0dd90cb6eb0e3debb7dc03b930f85..00e421081931bb77ee0dfeb9ded0cf943d10356e 100644
--- a/src/psaux/psfont.c
+++ b/src/psaux/psfont.c
@@ -274,9 +274,6 @@
 
     if ( !font->isT1 )
     {
-      FT_Service_CFFLoad  cffload = (FT_Service_CFFLoad)font->cffload;
-
-
       /* check for variation vectors */
       vstore        = cf2_getVStore( decoder );
       hasVariations = ( vstore->dataCount != 0 );
@@ -284,6 +281,9 @@
       if ( hasVariations )
       {
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+        FT_Service_CFFLoad  cffload = (FT_Service_CFFLoad)font->cffload;
+
+
         /* check whether Private DICT in this subfont needs to be reparsed */
         font->error = cf2_getNormalizedVector( decoder,
                                                &lenNormalizedV,
diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
index e2168a3324082de063c8265379f28f21dd1ddd33..8bfdb92332717e09d5d53cbc209cba57404b1a2d 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -174,10 +174,10 @@
    *   reallocation fails.
    */
   FT_LOCAL_DEF( FT_Error )
-  ps_table_add( PS_Table  table,
-                FT_Int    idx,
-                void*     object,
-                FT_UInt   length )
+  ps_table_add( PS_Table     table,
+                FT_Int       idx,
+                const void*  object,
+                FT_UInt      length )
   {
     if ( idx < 0 || idx >= table->max_elems )
     {
diff --git a/src/psaux/psobjs.h b/src/psaux/psobjs.h
index 9466a1d0754f3037d84c376f73fde9bf7479d20c..c44dc450ec6cc7124be22793d2b16fb4f7a53b23 100644
--- a/src/psaux/psobjs.h
+++ b/src/psaux/psobjs.h
@@ -53,10 +53,10 @@ FT_BEGIN_HEADER
                 FT_Memory  memory );
 
   FT_LOCAL( FT_Error )
-  ps_table_add( PS_Table  table,
-                FT_Int    idx,
-                void*     object,
-                FT_UInt   length );
+  ps_table_add( PS_Table     table,
+                FT_Int       idx,
+                const void*  object,
+                FT_UInt      length );
 
   FT_LOCAL( void )
   ps_table_done( PS_Table  table );
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index 798a72d02a129b669c5d875f573dd190c063c75c..023b6c1eff5a267019e460b156df874f6a7e5bb6 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -399,7 +399,7 @@
 
 
 #define RAS_ARGS       /* void */
-#define RAS_ARG        /* void */
+#define RAS_ARG        void
 
 #define RAS_VARS       /* void */
 #define RAS_VAR        /* void */
@@ -546,8 +546,7 @@
 
 #ifdef FT_STATIC_RASTER
 
-  static black_TWorker  cur_ras;
-#define ras  cur_ras
+  static black_TWorker  ras;
 
 #else /* !FT_STATIC_RASTER */
 
@@ -661,7 +660,6 @@
       return FAILURE;
     }
 
-    ras.cProfile->flags  = 0;
     ras.cProfile->start  = 0;
     ras.cProfile->height = 0;
     ras.cProfile->offset = ras.top;
@@ -914,16 +912,18 @@
 
 
     base[4].x = base[2].x;
-    b = base[1].x;
-    a = base[3].x = ( base[2].x + b ) / 2;
-    b = base[1].x = ( base[0].x + b ) / 2;
-    base[2].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    base[3].x = b >> 1;
+    base[2].x = ( a + b ) >> 2;
+    base[1].x = a >> 1;
 
     base[4].y = base[2].y;
-    b = base[1].y;
-    a = base[3].y = ( base[2].y + b ) / 2;
-    b = base[1].y = ( base[0].y + b ) / 2;
-    base[2].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    base[3].y = b >> 1;
+    base[2].y = ( a + b ) >> 2;
+    base[1].y = a >> 1;
 
     /* hand optimized.  gcc doesn't seem to be too good at common      */
     /* expression substitution and instruction scheduling ;-)          */
@@ -947,28 +947,32 @@
   static void
   Split_Cubic( TPoint*  base )
   {
-    Long  a, b, c, d;
+    Long  a, b, c;
 
 
     base[6].x = base[3].x;
-    c = base[1].x;
-    d = base[2].x;
-    base[1].x = a = ( base[0].x + c + 1 ) >> 1;
-    base[5].x = b = ( base[3].x + d + 1 ) >> 1;
-    c = ( c + d + 1 ) >> 1;
-    base[2].x = a = ( a + c + 1 ) >> 1;
-    base[4].x = b = ( b + c + 1 ) >> 1;
-    base[3].x = ( a + b + 1 ) >> 1;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    c = base[2].x + base[3].x;
+    base[5].x = c >> 1;
+    c += b;
+    base[4].x = c >> 2;
+    base[1].x = a >> 1;
+    a += b;
+    base[2].x = a >> 2;
+    base[3].x = ( a + c ) >> 3;
 
     base[6].y = base[3].y;
-    c = base[1].y;
-    d = base[2].y;
-    base[1].y = a = ( base[0].y + c + 1 ) >> 1;
-    base[5].y = b = ( base[3].y + d + 1 ) >> 1;
-    c = ( c + d + 1 ) >> 1;
-    base[2].y = a = ( a + c + 1 ) >> 1;
-    base[4].y = b = ( b + c + 1 ) >> 1;
-    base[3].y = ( a + b + 1 ) >> 1;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    c = base[2].y + base[3].y;
+    base[5].y = c >> 1;
+    c += b;
+    base[4].y = c >> 2;
+    base[1].y = a >> 1;
+    a += b;
+    base[2].y = a >> 2;
+    base[3].y = ( a + c ) >> 3;
   }
 
 
@@ -2784,7 +2788,7 @@
         P_Left  = draw_left;
         P_Right = draw_right;
 
-        while ( P_Left )
+        while ( P_Left && P_Right )
         {
           x1 = P_Left ->X;
           x2 = P_Right->X;
@@ -2885,7 +2889,7 @@
     P_Left  = draw_left;
     P_Right = draw_right;
 
-    while ( P_Left )
+    while ( P_Left && P_Right )
     {
       if ( P_Left->countL )
       {
@@ -3257,7 +3261,9 @@
     const FT_Outline*  outline    = (const FT_Outline*)params->source;
     const FT_Bitmap*   target_map = params->target;
 
+#ifndef FT_STATIC_RASTER
     black_TWorker  worker[1];
+#endif
 
     Long  buffer[FT_MAX_BLACK_POOL];
 
@@ -3299,8 +3305,8 @@
     ras.outline = *outline;
     ras.target  = *target_map;
 
-    worker->buff     = buffer;
-    worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
+    ras.buff     = buffer;
+    ras.sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
 
     return Render_Glyph( RAS_VAR );
   }
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index c467ff4d370aa59f257c4daf878e3a03e4fb5d22..2611685284427367aa5d7d0d2a3f3034ce9455f0 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -182,8 +182,8 @@
 
 
   static FT_UInt
-  sfnt_get_name_index( FT_Face     face,
-                       FT_String*  glyph_name )
+  sfnt_get_name_index( FT_Face           face,
+                       const FT_String*  glyph_name )
   {
     TT_Face  ttface = (TT_Face)face;
 
@@ -375,47 +375,61 @@
       {
       case 15:
         k4 ^= (FT_UInt32)tail[14] << 16;
+        /* fall through */
       case 14:
         k4 ^= (FT_UInt32)tail[13] << 8;
+        /* fall through */
       case 13:
         k4 ^= (FT_UInt32)tail[12];
         k4 *= c4;
         k4  = ROTL32( k4, 18 );
         k4 *= c1;
         h4 ^= k4;
+        /* fall through */
 
       case 12:
         k3 ^= (FT_UInt32)tail[11] << 24;
+        /* fall through */
       case 11:
         k3 ^= (FT_UInt32)tail[10] << 16;
+        /* fall through */
       case 10:
         k3 ^= (FT_UInt32)tail[9] << 8;
+        /* fall through */
       case 9:
         k3 ^= (FT_UInt32)tail[8];
         k3 *= c3;
         k3  = ROTL32( k3, 17 );
         k3 *= c4;
         h3 ^= k3;
+        /* fall through */
 
       case 8:
         k2 ^= (FT_UInt32)tail[7] << 24;
+        /* fall through */
       case 7:
         k2 ^= (FT_UInt32)tail[6] << 16;
+        /* fall through */
       case 6:
         k2 ^= (FT_UInt32)tail[5] << 8;
+        /* fall through */
       case 5:
         k2 ^= (FT_UInt32)tail[4];
         k2 *= c2;
         k2  = ROTL32( k2, 16 );
         k2 *= c3;
         h2 ^= k2;
+        /* fall through */
 
       case 4:
         k1 ^= (FT_UInt32)tail[3] << 24;
+        /* fall through */
       case 3:
         k1 ^= (FT_UInt32)tail[2] << 16;
+        /* fall through */
       case 2:
         k1 ^= (FT_UInt32)tail[1] << 8;
+        /* fall through */
       case 1:
         k1 ^= (FT_UInt32)tail[0];
         k1 *= c1;
diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c
index 5a503f30c54b6de418a4754bec91d63529f0f557..b4faf34a3affec31910ea2ebeea9537c9adaac5f 100644
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfnt.c
@@ -22,6 +22,7 @@
 #include "pngshim.c"
 #include "sfdriver.c"
 #include "sfobjs.c"
+#include "sfwoff.c"
 #include "ttbdf.c"
 #include "ttcmap.c"
 #include "ttcolr.c"
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 0b43d251b87cf5a093ecfe981935b6ef51f331b5..6edf3ae1ded66380794d1b0cba7fe956ec122e21 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -21,13 +21,13 @@
 #include "ttload.h"
 #include "ttcmap.h"
 #include "ttkern.h"
+#include "sfwoff.h"
 #include FT_INTERNAL_SFNT_H
 #include FT_INTERNAL_DEBUG_H
 #include FT_TRUETYPE_IDS_H
 #include FT_TRUETYPE_TAGS_H
 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
 #include FT_SFNT_NAMES_H
-#include FT_GZIP_H
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 #include FT_SERVICE_MULTIPLE_MASTERS_H
@@ -337,403 +337,6 @@
   }
 
 
-#define WRITE_USHORT( p, v )                \
-          do                                \
-          {                                 \
-            *(p)++ = (FT_Byte)( (v) >> 8 ); \
-            *(p)++ = (FT_Byte)( (v) >> 0 ); \
-                                            \
-          } while ( 0 )
-
-#define WRITE_ULONG( p, v )                  \
-          do                                 \
-          {                                  \
-            *(p)++ = (FT_Byte)( (v) >> 24 ); \
-            *(p)++ = (FT_Byte)( (v) >> 16 ); \
-            *(p)++ = (FT_Byte)( (v) >>  8 ); \
-            *(p)++ = (FT_Byte)( (v) >>  0 ); \
-                                             \
-          } while ( 0 )
-
-
-  static void
-  sfnt_stream_close( FT_Stream  stream )
-  {
-    FT_Memory  memory = stream->memory;
-
-
-    FT_FREE( stream->base );
-
-    stream->size  = 0;
-    stream->base  = NULL;
-    stream->close = NULL;
-  }
-
-
-  FT_CALLBACK_DEF( int )
-  compare_offsets( const void*  a,
-                   const void*  b )
-  {
-    WOFF_Table  table1 = *(WOFF_Table*)a;
-    WOFF_Table  table2 = *(WOFF_Table*)b;
-
-    FT_ULong  offset1 = table1->Offset;
-    FT_ULong  offset2 = table2->Offset;
-
-
-    if ( offset1 > offset2 )
-      return 1;
-    else if ( offset1 < offset2 )
-      return -1;
-    else
-      return 0;
-  }
-
-
-  /* Replace `face->root.stream' with a stream containing the extracted */
-  /* SFNT of a WOFF font.                                               */
-
-  static FT_Error
-  woff_open_font( FT_Stream  stream,
-                  TT_Face    face )
-  {
-    FT_Memory       memory = stream->memory;
-    FT_Error        error  = FT_Err_Ok;
-
-    WOFF_HeaderRec  woff;
-    WOFF_Table      tables  = NULL;
-    WOFF_Table*     indices = NULL;
-
-    FT_ULong        woff_offset;
-
-    FT_Byte*        sfnt        = NULL;
-    FT_Stream       sfnt_stream = NULL;
-
-    FT_Byte*        sfnt_header;
-    FT_ULong        sfnt_offset;
-
-    FT_Int          nn;
-    FT_ULong        old_tag = 0;
-
-    static const FT_Frame_Field  woff_header_fields[] =
-    {
-#undef  FT_STRUCTURE
-#define FT_STRUCTURE  WOFF_HeaderRec
-
-      FT_FRAME_START( 44 ),
-        FT_FRAME_ULONG ( signature ),
-        FT_FRAME_ULONG ( flavor ),
-        FT_FRAME_ULONG ( length ),
-        FT_FRAME_USHORT( num_tables ),
-        FT_FRAME_USHORT( reserved ),
-        FT_FRAME_ULONG ( totalSfntSize ),
-        FT_FRAME_USHORT( majorVersion ),
-        FT_FRAME_USHORT( minorVersion ),
-        FT_FRAME_ULONG ( metaOffset ),
-        FT_FRAME_ULONG ( metaLength ),
-        FT_FRAME_ULONG ( metaOrigLength ),
-        FT_FRAME_ULONG ( privOffset ),
-        FT_FRAME_ULONG ( privLength ),
-      FT_FRAME_END
-    };
-
-
-    FT_ASSERT( stream == face->root.stream );
-    FT_ASSERT( FT_STREAM_POS() == 0 );
-
-    if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) )
-      return error;
-
-    /* Make sure we don't recurse back here or hit TTC code. */
-    if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf )
-      return FT_THROW( Invalid_Table );
-
-    /* Miscellaneous checks. */
-    if ( woff.length != stream->size                              ||
-         woff.num_tables == 0                                     ||
-         44 + woff.num_tables * 20UL >= woff.length               ||
-         12 + woff.num_tables * 16UL >= woff.totalSfntSize        ||
-         ( woff.totalSfntSize & 3 ) != 0                          ||
-         ( woff.metaOffset == 0 && ( woff.metaLength != 0     ||
-                                     woff.metaOrigLength != 0 ) ) ||
-         ( woff.metaLength != 0 && woff.metaOrigLength == 0 )     ||
-         ( woff.privOffset == 0 && woff.privLength != 0 )         )
-    {
-      FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
-      return FT_THROW( Invalid_Table );
-    }
-
-    /* Don't trust `totalSfntSize' before thorough checks. */
-    if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
-         FT_NEW( sfnt_stream )                         )
-      goto Exit;
-
-    sfnt_header = sfnt;
-
-    /* Write sfnt header. */
-    {
-      FT_UInt  searchRange, entrySelector, rangeShift, x;
-
-
-      x             = woff.num_tables;
-      entrySelector = 0;
-      while ( x )
-      {
-        x            >>= 1;
-        entrySelector += 1;
-      }
-      entrySelector--;
-
-      searchRange = ( 1 << entrySelector ) * 16;
-      rangeShift  = woff.num_tables * 16 - searchRange;
-
-      WRITE_ULONG ( sfnt_header, woff.flavor );
-      WRITE_USHORT( sfnt_header, woff.num_tables );
-      WRITE_USHORT( sfnt_header, searchRange );
-      WRITE_USHORT( sfnt_header, entrySelector );
-      WRITE_USHORT( sfnt_header, rangeShift );
-    }
-
-    /* While the entries in the sfnt header must be sorted by the */
-    /* tag value, the tables themselves are not.  We thus have to */
-    /* sort them by offset and check that they don't overlap.     */
-
-    if ( FT_NEW_ARRAY( tables, woff.num_tables )  ||
-         FT_NEW_ARRAY( indices, woff.num_tables ) )
-      goto Exit;
-
-    FT_TRACE2(( "\n"
-                "  tag    offset    compLen  origLen  checksum\n"
-                "  -------------------------------------------\n" ));
-
-    if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
-      goto Exit;
-
-    for ( nn = 0; nn < woff.num_tables; nn++ )
-    {
-      WOFF_Table  table = tables + nn;
-
-      table->Tag        = FT_GET_TAG4();
-      table->Offset     = FT_GET_ULONG();
-      table->CompLength = FT_GET_ULONG();
-      table->OrigLength = FT_GET_ULONG();
-      table->CheckSum   = FT_GET_ULONG();
-
-      FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx  %08lx\n",
-                  (FT_Char)( table->Tag >> 24 ),
-                  (FT_Char)( table->Tag >> 16 ),
-                  (FT_Char)( table->Tag >> 8  ),
-                  (FT_Char)( table->Tag       ),
-                  table->Offset,
-                  table->CompLength,
-                  table->OrigLength,
-                  table->CheckSum ));
-
-      if ( table->Tag <= old_tag )
-      {
-        FT_FRAME_EXIT();
-
-        FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
-
-      old_tag     = table->Tag;
-      indices[nn] = table;
-    }
-
-    FT_FRAME_EXIT();
-
-    /* Sort by offset. */
-
-    ft_qsort( indices,
-              woff.num_tables,
-              sizeof ( WOFF_Table ),
-              compare_offsets );
-
-    /* Check offsets and lengths. */
-
-    woff_offset = 44 + woff.num_tables * 20L;
-    sfnt_offset = 12 + woff.num_tables * 16L;
-
-    for ( nn = 0; nn < woff.num_tables; nn++ )
-    {
-      WOFF_Table  table = indices[nn];
-
-
-      if ( table->Offset != woff_offset                         ||
-           table->CompLength > woff.length                      ||
-           table->Offset > woff.length - table->CompLength      ||
-           table->OrigLength > woff.totalSfntSize               ||
-           sfnt_offset > woff.totalSfntSize - table->OrigLength ||
-           table->CompLength > table->OrigLength                )
-      {
-        FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
-
-      table->OrigOffset = sfnt_offset;
-
-      /* The offsets must be multiples of 4. */
-      woff_offset += ( table->CompLength + 3 ) & ~3U;
-      sfnt_offset += ( table->OrigLength + 3 ) & ~3U;
-    }
-
-    /*
-     * Final checks!
-     *
-     * We don't decode and check the metadata block.
-     * We don't check table checksums either.
-     * But other than those, I think we implement all
-     * `MUST' checks from the spec.
-     */
-
-    if ( woff.metaOffset )
-    {
-      if ( woff.metaOffset != woff_offset                  ||
-           woff.metaOffset + woff.metaLength > woff.length )
-      {
-        FT_ERROR(( "woff_font_open:"
-                   " invalid `metadata' offset or length\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
-
-      /* We have padding only ... */
-      woff_offset += woff.metaLength;
-    }
-
-    if ( woff.privOffset )
-    {
-      /* ... if it isn't the last block. */
-      woff_offset = ( woff_offset + 3 ) & ~3U;
-
-      if ( woff.privOffset != woff_offset                  ||
-           woff.privOffset + woff.privLength > woff.length )
-      {
-        FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
-
-      /* No padding for the last block. */
-      woff_offset += woff.privLength;
-    }
-
-    if ( sfnt_offset != woff.totalSfntSize ||
-         woff_offset != woff.length        )
-    {
-      FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
-      error = FT_THROW( Invalid_Table );
-      goto Exit;
-    }
-
-    /* Now use `totalSfntSize'. */
-    if ( FT_REALLOC( sfnt,
-                     12 + woff.num_tables * 16UL,
-                     woff.totalSfntSize ) )
-      goto Exit;
-
-    sfnt_header = sfnt + 12;
-
-    /* Write the tables. */
-
-    for ( nn = 0; nn < woff.num_tables; nn++ )
-    {
-      WOFF_Table  table = tables + nn;
-
-
-      /* Write SFNT table entry. */
-      WRITE_ULONG( sfnt_header, table->Tag );
-      WRITE_ULONG( sfnt_header, table->CheckSum );
-      WRITE_ULONG( sfnt_header, table->OrigOffset );
-      WRITE_ULONG( sfnt_header, table->OrigLength );
-
-      /* Write table data. */
-      if ( FT_STREAM_SEEK( table->Offset )     ||
-           FT_FRAME_ENTER( table->CompLength ) )
-        goto Exit;
-
-      if ( table->CompLength == table->OrigLength )
-      {
-        /* Uncompressed data; just copy. */
-        ft_memcpy( sfnt + table->OrigOffset,
-                   stream->cursor,
-                   table->OrigLength );
-      }
-      else
-      {
-#ifdef FT_CONFIG_OPTION_USE_ZLIB
-
-        /* Uncompress with zlib. */
-        FT_ULong  output_len = table->OrigLength;
-
-
-        error = FT_Gzip_Uncompress( memory,
-                                    sfnt + table->OrigOffset, &output_len,
-                                    stream->cursor, table->CompLength );
-        if ( error )
-          goto Exit;
-        if ( output_len != table->OrigLength )
-        {
-          FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
-          error = FT_THROW( Invalid_Table );
-          goto Exit;
-        }
-
-#else /* !FT_CONFIG_OPTION_USE_ZLIB */
-
-        error = FT_THROW( Unimplemented_Feature );
-        goto Exit;
-
-#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
-      }
-
-      FT_FRAME_EXIT();
-
-      /* We don't check whether the padding bytes in the WOFF file are     */
-      /* actually '\0'.  For the output, however, we do set them properly. */
-      sfnt_offset = table->OrigOffset + table->OrigLength;
-      while ( sfnt_offset & 3 )
-      {
-        sfnt[sfnt_offset] = '\0';
-        sfnt_offset++;
-      }
-    }
-
-    /* Ok!  Finally ready.  Swap out stream and return. */
-    FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize );
-    sfnt_stream->memory = stream->memory;
-    sfnt_stream->close  = sfnt_stream_close;
-
-    FT_Stream_Free(
-      face->root.stream,
-      ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
-
-    face->root.stream = sfnt_stream;
-
-    face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
-
-  Exit:
-    FT_FREE( tables );
-    FT_FREE( indices );
-
-    if ( error )
-    {
-      FT_FREE( sfnt );
-      FT_Stream_Close( sfnt_stream );
-      FT_FREE( sfnt_stream );
-    }
-
-    return error;
-  }
-
-
-#undef WRITE_USHORT
-#undef WRITE_ULONG
-
-
   /* Fill in face->ttc_header.  If the font is not a TTC, it is */
   /* synthesized into a TTC with one offset table.              */
   static FT_Error
diff --git a/src/sfnt/sfobjs.h b/src/sfnt/sfobjs.h
index 17b0d50105e420f8be237903a2be9550cfa0e581..3fbf2dd6bd48e758c2d7146baaab638ff14e6fad 100644
--- a/src/sfnt/sfobjs.h
+++ b/src/sfnt/sfobjs.h
@@ -53,7 +53,7 @@ FT_BEGIN_HEADER
 
 FT_END_HEADER
 
-#endif /* SFDRIVER_H_ */
+#endif /* SFOBJS_H_ */
 
 
 /* END */
diff --git a/src/sfnt/sfwoff.c b/src/sfnt/sfwoff.c
new file mode 100644
index 0000000000000000000000000000000000000000..ca4821a20a4f1e3cb7ba5d82ea1df89e0d324319
--- /dev/null
+++ b/src/sfnt/sfwoff.c
@@ -0,0 +1,434 @@
+/****************************************************************************
+ *
+ * sfwoff.c
+ *
+ *   WOFF format management (base).
+ *
+ * Copyright (C) 1996-2019 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#include <ft2build.h>
+#include "sfwoff.h"
+#include FT_TRUETYPE_TAGS_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_GZIP_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  sfwoff
+
+
+#define WRITE_USHORT( p, v )                \
+          do                                \
+          {                                 \
+            *(p)++ = (FT_Byte)( (v) >> 8 ); \
+            *(p)++ = (FT_Byte)( (v) >> 0 ); \
+                                            \
+          } while ( 0 )
+
+#define WRITE_ULONG( p, v )                  \
+          do                                 \
+          {                                  \
+            *(p)++ = (FT_Byte)( (v) >> 24 ); \
+            *(p)++ = (FT_Byte)( (v) >> 16 ); \
+            *(p)++ = (FT_Byte)( (v) >>  8 ); \
+            *(p)++ = (FT_Byte)( (v) >>  0 ); \
+                                             \
+          } while ( 0 )
+
+
+  static void
+  sfnt_stream_close( FT_Stream  stream )
+  {
+    FT_Memory  memory = stream->memory;
+
+
+    FT_FREE( stream->base );
+
+    stream->size  = 0;
+    stream->base  = NULL;
+    stream->close = NULL;
+  }
+
+
+  FT_CALLBACK_DEF( int )
+  compare_offsets( const void*  a,
+                   const void*  b )
+  {
+    WOFF_Table  table1 = *(WOFF_Table*)a;
+    WOFF_Table  table2 = *(WOFF_Table*)b;
+
+    FT_ULong  offset1 = table1->Offset;
+    FT_ULong  offset2 = table2->Offset;
+
+
+    if ( offset1 > offset2 )
+      return 1;
+    else if ( offset1 < offset2 )
+      return -1;
+    else
+      return 0;
+  }
+
+
+  /* Replace `face->root.stream' with a stream containing the extracted */
+  /* SFNT of a WOFF font.                                               */
+
+  FT_LOCAL_DEF( FT_Error )
+  woff_open_font( FT_Stream  stream,
+                  TT_Face    face )
+  {
+    FT_Memory       memory = stream->memory;
+    FT_Error        error  = FT_Err_Ok;
+
+    WOFF_HeaderRec  woff;
+    WOFF_Table      tables  = NULL;
+    WOFF_Table*     indices = NULL;
+
+    FT_ULong        woff_offset;
+
+    FT_Byte*        sfnt        = NULL;
+    FT_Stream       sfnt_stream = NULL;
+
+    FT_Byte*        sfnt_header;
+    FT_ULong        sfnt_offset;
+
+    FT_Int          nn;
+    FT_ULong        old_tag = 0;
+
+    static const FT_Frame_Field  woff_header_fields[] =
+    {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  WOFF_HeaderRec
+
+      FT_FRAME_START( 44 ),
+        FT_FRAME_ULONG ( signature ),
+        FT_FRAME_ULONG ( flavor ),
+        FT_FRAME_ULONG ( length ),
+        FT_FRAME_USHORT( num_tables ),
+        FT_FRAME_USHORT( reserved ),
+        FT_FRAME_ULONG ( totalSfntSize ),
+        FT_FRAME_USHORT( majorVersion ),
+        FT_FRAME_USHORT( minorVersion ),
+        FT_FRAME_ULONG ( metaOffset ),
+        FT_FRAME_ULONG ( metaLength ),
+        FT_FRAME_ULONG ( metaOrigLength ),
+        FT_FRAME_ULONG ( privOffset ),
+        FT_FRAME_ULONG ( privLength ),
+      FT_FRAME_END
+    };
+
+
+    FT_ASSERT( stream == face->root.stream );
+    FT_ASSERT( FT_STREAM_POS() == 0 );
+
+    if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) )
+      return error;
+
+    /* Make sure we don't recurse back here or hit TTC code. */
+    if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf )
+      return FT_THROW( Invalid_Table );
+
+    /* Miscellaneous checks. */
+    if ( woff.length != stream->size                              ||
+         woff.num_tables == 0                                     ||
+         44 + woff.num_tables * 20UL >= woff.length               ||
+         12 + woff.num_tables * 16UL >= woff.totalSfntSize        ||
+         ( woff.totalSfntSize & 3 ) != 0                          ||
+         ( woff.metaOffset == 0 && ( woff.metaLength != 0     ||
+                                     woff.metaOrigLength != 0 ) ) ||
+         ( woff.metaLength != 0 && woff.metaOrigLength == 0 )     ||
+         ( woff.privOffset == 0 && woff.privLength != 0 )         )
+    {
+      FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
+      return FT_THROW( Invalid_Table );
+    }
+
+    /* Don't trust `totalSfntSize' before thorough checks. */
+    if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
+         FT_NEW( sfnt_stream )                         )
+      goto Exit;
+
+    sfnt_header = sfnt;
+
+    /* Write sfnt header. */
+    {
+      FT_UInt  searchRange, entrySelector, rangeShift, x;
+
+
+      x             = woff.num_tables;
+      entrySelector = 0;
+      while ( x )
+      {
+        x            >>= 1;
+        entrySelector += 1;
+      }
+      entrySelector--;
+
+      searchRange = ( 1 << entrySelector ) * 16;
+      rangeShift  = woff.num_tables * 16 - searchRange;
+
+      WRITE_ULONG ( sfnt_header, woff.flavor );
+      WRITE_USHORT( sfnt_header, woff.num_tables );
+      WRITE_USHORT( sfnt_header, searchRange );
+      WRITE_USHORT( sfnt_header, entrySelector );
+      WRITE_USHORT( sfnt_header, rangeShift );
+    }
+
+    /* While the entries in the sfnt header must be sorted by the */
+    /* tag value, the tables themselves are not.  We thus have to */
+    /* sort them by offset and check that they don't overlap.     */
+
+    if ( FT_NEW_ARRAY( tables, woff.num_tables )  ||
+         FT_NEW_ARRAY( indices, woff.num_tables ) )
+      goto Exit;
+
+    FT_TRACE2(( "\n"
+                "  tag    offset    compLen  origLen  checksum\n"
+                "  -------------------------------------------\n" ));
+
+    if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
+      goto Exit;
+
+    for ( nn = 0; nn < woff.num_tables; nn++ )
+    {
+      WOFF_Table  table = tables + nn;
+
+      table->Tag        = FT_GET_TAG4();
+      table->Offset     = FT_GET_ULONG();
+      table->CompLength = FT_GET_ULONG();
+      table->OrigLength = FT_GET_ULONG();
+      table->CheckSum   = FT_GET_ULONG();
+
+      FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx  %08lx\n",
+                  (FT_Char)( table->Tag >> 24 ),
+                  (FT_Char)( table->Tag >> 16 ),
+                  (FT_Char)( table->Tag >> 8  ),
+                  (FT_Char)( table->Tag       ),
+                  table->Offset,
+                  table->CompLength,
+                  table->OrigLength,
+                  table->CheckSum ));
+
+      if ( table->Tag <= old_tag )
+      {
+        FT_FRAME_EXIT();
+
+        FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      old_tag     = table->Tag;
+      indices[nn] = table;
+    }
+
+    FT_FRAME_EXIT();
+
+    /* Sort by offset. */
+
+    ft_qsort( indices,
+              woff.num_tables,
+              sizeof ( WOFF_Table ),
+              compare_offsets );
+
+    /* Check offsets and lengths. */
+
+    woff_offset = 44 + woff.num_tables * 20L;
+    sfnt_offset = 12 + woff.num_tables * 16L;
+
+    for ( nn = 0; nn < woff.num_tables; nn++ )
+    {
+      WOFF_Table  table = indices[nn];
+
+
+      if ( table->Offset != woff_offset                         ||
+           table->CompLength > woff.length                      ||
+           table->Offset > woff.length - table->CompLength      ||
+           table->OrigLength > woff.totalSfntSize               ||
+           sfnt_offset > woff.totalSfntSize - table->OrigLength ||
+           table->CompLength > table->OrigLength                )
+      {
+        FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      table->OrigOffset = sfnt_offset;
+
+      /* The offsets must be multiples of 4. */
+      woff_offset += ( table->CompLength + 3 ) & ~3U;
+      sfnt_offset += ( table->OrigLength + 3 ) & ~3U;
+    }
+
+    /*
+     * Final checks!
+     *
+     * We don't decode and check the metadata block.
+     * We don't check table checksums either.
+     * But other than those, I think we implement all
+     * `MUST' checks from the spec.
+     */
+
+    if ( woff.metaOffset )
+    {
+      if ( woff.metaOffset != woff_offset                  ||
+           woff.metaOffset + woff.metaLength > woff.length )
+      {
+        FT_ERROR(( "woff_font_open:"
+                   " invalid `metadata' offset or length\n" ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      /* We have padding only ... */
+      woff_offset += woff.metaLength;
+    }
+
+    if ( woff.privOffset )
+    {
+      /* ... if it isn't the last block. */
+      woff_offset = ( woff_offset + 3 ) & ~3U;
+
+      if ( woff.privOffset != woff_offset                  ||
+           woff.privOffset + woff.privLength > woff.length )
+      {
+        FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      /* No padding for the last block. */
+      woff_offset += woff.privLength;
+    }
+
+    if ( sfnt_offset != woff.totalSfntSize ||
+         woff_offset != woff.length        )
+    {
+      FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    /* Now use `totalSfntSize'. */
+    if ( FT_REALLOC( sfnt,
+                     12 + woff.num_tables * 16UL,
+                     woff.totalSfntSize ) )
+      goto Exit;
+
+    sfnt_header = sfnt + 12;
+
+    /* Write the tables. */
+
+    for ( nn = 0; nn < woff.num_tables; nn++ )
+    {
+      WOFF_Table  table = tables + nn;
+
+
+      /* Write SFNT table entry. */
+      WRITE_ULONG( sfnt_header, table->Tag );
+      WRITE_ULONG( sfnt_header, table->CheckSum );
+      WRITE_ULONG( sfnt_header, table->OrigOffset );
+      WRITE_ULONG( sfnt_header, table->OrigLength );
+
+      /* Write table data. */
+      if ( FT_STREAM_SEEK( table->Offset )     ||
+           FT_FRAME_ENTER( table->CompLength ) )
+        goto Exit;
+
+      if ( table->CompLength == table->OrigLength )
+      {
+        /* Uncompressed data; just copy. */
+        ft_memcpy( sfnt + table->OrigOffset,
+                   stream->cursor,
+                   table->OrigLength );
+      }
+      else
+      {
+#ifdef FT_CONFIG_OPTION_USE_ZLIB
+
+        /* Uncompress with zlib. */
+        FT_ULong  output_len = table->OrigLength;
+
+
+        error = FT_Gzip_Uncompress( memory,
+                                    sfnt + table->OrigOffset, &output_len,
+                                    stream->cursor, table->CompLength );
+        if ( error )
+          goto Exit;
+        if ( output_len != table->OrigLength )
+        {
+          FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
+          error = FT_THROW( Invalid_Table );
+          goto Exit;
+        }
+
+#else /* !FT_CONFIG_OPTION_USE_ZLIB */
+
+        error = FT_THROW( Unimplemented_Feature );
+        goto Exit;
+
+#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
+      }
+
+      FT_FRAME_EXIT();
+
+      /* We don't check whether the padding bytes in the WOFF file are     */
+      /* actually '\0'.  For the output, however, we do set them properly. */
+      sfnt_offset = table->OrigOffset + table->OrigLength;
+      while ( sfnt_offset & 3 )
+      {
+        sfnt[sfnt_offset] = '\0';
+        sfnt_offset++;
+      }
+    }
+
+    /* Ok!  Finally ready.  Swap out stream and return. */
+    FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize );
+    sfnt_stream->memory = stream->memory;
+    sfnt_stream->close  = sfnt_stream_close;
+
+    FT_Stream_Free(
+      face->root.stream,
+      ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
+
+    face->root.stream = sfnt_stream;
+
+    face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
+
+  Exit:
+    FT_FREE( tables );
+    FT_FREE( indices );
+
+    if ( error )
+    {
+      FT_FREE( sfnt );
+      FT_Stream_Close( sfnt_stream );
+      FT_FREE( sfnt_stream );
+    }
+
+    return error;
+  }
+
+
+#undef WRITE_USHORT
+#undef WRITE_ULONG
+
+
+/* END */
diff --git a/src/sfnt/sfwoff.h b/src/sfnt/sfwoff.h
new file mode 100644
index 0000000000000000000000000000000000000000..15495c32a2e5b93e9c2d1722cf5b51378f59c6e7
--- /dev/null
+++ b/src/sfnt/sfwoff.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ *
+ * sfwoff.h
+ *
+ *   WOFFF format management (specification).
+ *
+ * Copyright (C) 1996-2019 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#ifndef SFWOFF_H_
+#define SFWOFF_H_
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_SFNT_H
+#include FT_INTERNAL_OBJECTS_H
+
+
+FT_BEGIN_HEADER
+
+
+  FT_LOCAL( FT_Error )
+  woff_open_font( FT_Stream  stream,
+                  TT_Face    face );
+
+
+FT_END_HEADER
+
+#endif /* SFWOFF_H_ */
+
+
+/* END */
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index 8d9737310c729dc087a859f99f664e2e60c94374..683f3b18186622b965e38d37a7fd0b5691899b27 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -2368,10 +2368,7 @@
         /* if `gindex' is invalid, the remaining values */
         /* in this group are invalid, too               */
         if ( gindex >= (FT_UInt)face->num_glyphs )
-        {
-          gindex = 0;
           continue;
-        }
 
         cmap->cur_charcode = char_code;
         cmap->cur_gindex   = gindex;
@@ -3661,7 +3658,7 @@
   tt_get_glyph_name( TT_Face  face,
                      FT_UInt  idx )
   {
-    FT_String*  PSname;
+    FT_String*  PSname = NULL;
 
 
     tt_face_get_ps_name( face, idx, &PSname );
diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c
index 7a4d2be2cb81183ff2532cd821e7d9ecdd5ddd3e..b6725c962fefe8ec6cd151393579a1a45bd4b59a 100644
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -280,7 +280,7 @@
       else
       {
         table_pos += 4 * ( k - 1 );
-        if ( table_pos + 4 > table_end )
+        if ( table_pos + 2 > table_end )
           goto NoData;
 
         if ( FT_STREAM_SEEK( table_pos ) ||
@@ -292,7 +292,9 @@
           *abearing = 0;
         else
         {
-          if ( !FT_STREAM_SEEK( table_pos ) )
+          if ( FT_STREAM_SEEK( table_pos ) )
+            *abearing = 0;
+          else
             (void)FT_READ_SHORT( *abearing );
         }
       }
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 91293ac9463cf1636a41332e3ae1f1ed81d10f73..fd357a50fc7741f4421e26c94504ab6d0bcffaf8 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -45,7 +45,7 @@
    * This is a new anti-aliasing scan-converter for FreeType 2.  The
    * algorithm used here is _very_ different from the one in the standard
    * `ftraster' module.  Actually, `ftgrays' computes the _exact_
-   * coverage of the outline on each pixel cell.
+   * coverage of the outline on each pixel cell by straight segments.
    *
    * It is based on ideas that I initially found in Raph Levien's
    * excellent LibArt graphics library (see https://www.levien.com/libart
@@ -58,6 +58,14 @@
    * different way, and I don't use sorted vector paths.  Also, it doesn't
    * use floating point values.
    *
+   * Bézier segments are flattened by splitting them until their deviation
+   * from straight line becomes much smaller than a pixel.  Therefore, the
+   * pixel coverage by a Bézier curve is calculated approximately.  To
+   * estimate the deviation, we use the distance from the control point
+   * to the conic chord centre or the cubic chord trisection.  These
+   * distances vanish fast after each split.  In the conic case, they vanish
+   * predictably and the number of necessary splits can be calculated.
+   *
    * This renderer has the following advantages:
    *
    * - It doesn't need an intermediate bitmap.  Instead, one can supply a
@@ -67,7 +75,7 @@
    *   callback.
    *
    * - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on
-   *   each pixel cell.
+   *   each pixel cell by straight segments.
    *
    * - It performs a single pass on the outline (the `standard' FT2
    *   renderer makes two passes).
@@ -75,7 +83,7 @@
    * - It can easily be modified to render to _any_ number of gray levels
    *   cheaply.
    *
-   * - For small (< 20) pixel sizes, it is faster than the standard
+   * - For small (< 80) pixel sizes, it is faster than the standard
    *   renderer.
    *
    */
@@ -327,17 +335,9 @@ typedef ptrdiff_t  FT_PtrDist;
   /* must be at least 6 bits! */
 #define PIXEL_BITS  8
 
-#undef FLOOR
-#undef CEILING
-#undef TRUNC
-#undef SCALED
-
 #define ONE_PIXEL       ( 1 << PIXEL_BITS )
-#define TRUNC( x )      ( (TCoord)( (x) >> PIXEL_BITS ) )
-#define SUBPIXELS( x )  ( (TPos)(x) * ONE_PIXEL )
-#define FLOOR( x )      ( (x) & -ONE_PIXEL )
-#define CEILING( x )    ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
-#define ROUND( x )      ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
+#define TRUNC( x )      (TCoord)( (x) >> PIXEL_BITS )
+#define FRACT( x )      (TCoord)( (x) & ( ONE_PIXEL - 1 ) )
 
 #if PIXEL_BITS >= 6
 #define UPSCALE( x )    ( (x) * ( ONE_PIXEL >> 6 ) )
@@ -388,9 +388,9 @@ typedef ptrdiff_t  FT_PtrDist;
 #define FT_UDIVPREP( c, b )                                        \
   long  b ## _r = c ? (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) \
                     : 0
-#define FT_UDIV( a, b )                                        \
-  ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >>   \
-    ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) )
+#define FT_UDIV( a, b )                                                \
+  (TCoord)( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >>   \
+            ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) )
 
 
   /**************************************************************************
@@ -432,6 +432,9 @@ typedef ptrdiff_t  FT_PtrDist;
 #define FT_MAX_GRAY_POOL  ( 2048 / sizeof ( TCell ) )
 #endif
 
+  /* FT_Span buffer size for direct rendering only */
+#define FT_MAX_GRAY_SPANS  10
+
 
 #if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
   /* We disable the warning `structure was padded due to   */
@@ -465,6 +468,8 @@ typedef ptrdiff_t  FT_PtrDist;
 
     FT_Raster_Span_Func  render_span;
     void*                render_span_data;
+    FT_Span              spans[FT_MAX_GRAY_SPANS];
+    int                  num_spans;
 
   } gray_TWorker, *gray_PWorker;
 
@@ -516,7 +521,7 @@ typedef ptrdiff_t  FT_PtrDist;
 
   /**************************************************************************
    *
-   * Record the current cell in the table.
+   * Record the current cell in the linked list.
    */
   static void
   gray_record_cell( RAS_ARG )
@@ -526,10 +531,9 @@ typedef ptrdiff_t  FT_PtrDist;
 
 
     pcell = &ras.ycells[ras.ey - ras.min_ey];
-    for (;;)
+    while ( ( cell = *pcell ) )
     {
-      cell = *pcell;
-      if ( !cell || cell->x > x )
+      if ( cell->x > x )
         break;
 
       if ( cell->x == x )
@@ -577,16 +581,13 @@ typedef ptrdiff_t  FT_PtrDist;
     /* Note that if a cell is to the left of the clipping region, it is    */
     /* actually set to the (min_ex-1) horizontal position.                 */
 
-    if ( ex < ras.min_ex )
-      ex = ras.min_ex - 1;
-
     /* record the current one if it is valid and substantial */
     if ( !ras.invalid && ( ras.area || ras.cover ) )
       gray_record_cell( RAS_VAR );
 
     ras.area  = 0;
     ras.cover = 0;
-    ras.ex    = ex;
+    ras.ex    = FT_MAX( ex, ras.min_ex - 1 );
     ras.ey    = ey;
 
     ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey ||
@@ -622,8 +623,8 @@ typedef ptrdiff_t  FT_PtrDist;
       return;
     }
 
-    fx1   = (TCoord)( x1 - SUBPIXELS( ex1 ) );
-    fx2   = (TCoord)( x2 - SUBPIXELS( ex2 ) );
+    fx1   = FRACT( x1 );
+    fx2   = FRACT( x2 );
 
     /* everything is located in a single cell.  That is easy! */
     /*                                                        */
@@ -650,6 +651,9 @@ typedef ptrdiff_t  FT_PtrDist;
       dx    = -dx;
     }
 
+    /* the fractional part of y-delta is mod/dx. It is essential to */
+    /* keep track of its accumulation for accurate rendering.       */
+    /* XXX: y-delta and x-delta below should be related.            */
     FT_DIV_MOD( TCoord, p, dx, delta, mod );
 
     ras.area  += (TArea)( ( fx1 + first ) * delta );
@@ -715,8 +719,8 @@ typedef ptrdiff_t  FT_PtrDist;
          ( ey1 <  ras.min_ey && ey2 <  ras.min_ey ) )
       goto End;
 
-    fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
-    fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
+    fy1 = FRACT( ras.y );
+    fy2 = FRACT( to_y );
 
     /* everything is on a single scanline */
     if ( ey1 == ey2 )
@@ -732,7 +736,7 @@ typedef ptrdiff_t  FT_PtrDist;
     if ( dx == 0 )
     {
       TCoord  ex     = TRUNC( ras.x );
-      TCoord  two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );
+      TCoord  two_fx = FRACT( ras.x ) << 1;
       TArea   area;
 
 
@@ -787,6 +791,8 @@ typedef ptrdiff_t  FT_PtrDist;
       dy    = -dy;
     }
 
+    /* the fractional part of x-delta is mod/dy. It is essential to */
+    /* keep track of its accumulation for accurate rendering.       */
     FT_DIV_MOD( TCoord, p, dy, delta, mod );
 
     x = ras.x + delta;
@@ -843,8 +849,9 @@ typedef ptrdiff_t  FT_PtrDist;
   gray_render_line( RAS_ARG_ TPos  to_x,
                              TPos  to_y )
   {
-    TPos    dx, dy, fx1, fy1, fx2, fy2;
-    TCoord  ex1, ex2, ey1, ey2;
+    TPos    dx, dy;
+    TCoord  fx1, fy1, fx2, fy2;
+    TCoord  ex1, ey1, ex2, ey2;
 
 
     ey1 = TRUNC( ras.y );
@@ -858,8 +865,8 @@ typedef ptrdiff_t  FT_PtrDist;
     ex1 = TRUNC( ras.x );
     ex2 = TRUNC( to_x );
 
-    fx1 = ras.x - SUBPIXELS( ex1 );
-    fy1 = ras.y - SUBPIXELS( ey1 );
+    fx1 = FRACT( ras.x );
+    fy1 = FRACT( ras.y );
 
     dx = to_x - ras.x;
     dy = to_y - ras.y;
@@ -868,8 +875,8 @@ typedef ptrdiff_t  FT_PtrDist;
       ;
     else if ( dy == 0 ) /* ex1 != ex2 */  /* any horizontal line */
     {
-      ex1 = ex2;
-      gray_set_cell( RAS_VAR_ ex1, ey1 );
+      gray_set_cell( RAS_VAR_ ex2, ey2 );
+      goto End;
     }
     else if ( dx == 0 )
     {
@@ -896,7 +903,7 @@ typedef ptrdiff_t  FT_PtrDist;
     }
     else                                  /* any other line */
     {
-      TPos  prod = dx * fy1 - dy * fx1;
+      TPos  prod = dx * (TPos)fy1 - dy * (TPos)fx1;
       FT_UDIVPREP( ex1 != ex2, dx );
       FT_UDIVPREP( ey1 != ey2, dy );
 
@@ -910,7 +917,7 @@ typedef ptrdiff_t  FT_PtrDist;
                   prod - dx * ONE_PIXEL                  >  0 ) /* left */
         {
           fx2 = 0;
-          fy2 = (TPos)FT_UDIV( -prod, -dx );
+          fy2 = FT_UDIV( -prod, -dx );
           prod -= dy * ONE_PIXEL;
           ras.cover += ( fy2 - fy1 );
           ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
@@ -922,7 +929,7 @@ typedef ptrdiff_t  FT_PtrDist;
                   prod - dx * ONE_PIXEL + dy * ONE_PIXEL >  0 ) /* up */
         {
           prod -= dx * ONE_PIXEL;
-          fx2 = (TPos)FT_UDIV( -prod, dy );
+          fx2 = FT_UDIV( -prod, dy );
           fy2 = ONE_PIXEL;
           ras.cover += ( fy2 - fy1 );
           ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
@@ -935,7 +942,7 @@ typedef ptrdiff_t  FT_PtrDist;
         {
           prod += dy * ONE_PIXEL;
           fx2 = ONE_PIXEL;
-          fy2 = (TPos)FT_UDIV( prod, dx );
+          fy2 = FT_UDIV( prod, dx );
           ras.cover += ( fy2 - fy1 );
           ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
           fx1 = 0;
@@ -945,7 +952,7 @@ typedef ptrdiff_t  FT_PtrDist;
         else /* ( prod                  + dy * ONE_PIXEL <  0 &&
                   prod                                   >  0 )    down */
         {
-          fx2 = (TPos)FT_UDIV( prod, -dy );
+          fx2 = FT_UDIV( prod, -dy );
           fy2 = 0;
           prod += dx * ONE_PIXEL;
           ras.cover += ( fy2 - fy1 );
@@ -959,8 +966,8 @@ typedef ptrdiff_t  FT_PtrDist;
       } while ( ex1 != ex2 || ey1 != ey2 );
     }
 
-    fx2 = to_x - SUBPIXELS( ex2 );
-    fy2 = to_y - SUBPIXELS( ey2 );
+    fx2 = FRACT( to_x );
+    fy2 = FRACT( to_y );
 
     ras.cover += ( fy2 - fy1 );
     ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
@@ -979,16 +986,18 @@ typedef ptrdiff_t  FT_PtrDist;
 
 
     base[4].x = base[2].x;
-    b = base[1].x;
-    a = base[3].x = ( base[2].x + b ) / 2;
-    b = base[1].x = ( base[0].x + b ) / 2;
-    base[2].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    base[3].x = b >> 1;
+    base[2].x = ( a + b ) >> 2;
+    base[1].x = a >> 1;
 
     base[4].y = base[2].y;
-    b = base[1].y;
-    a = base[3].y = ( base[2].y + b ) / 2;
-    b = base[1].y = ( base[0].y + b ) / 2;
-    base[2].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    base[3].y = b >> 1;
+    base[2].y = ( a + b ) >> 2;
+    base[1].y = a >> 1;
   }
 
 
@@ -1042,12 +1051,11 @@ typedef ptrdiff_t  FT_PtrDist;
     /* many times as there are trailing zeros in the counter.         */
     do
     {
-      split = 1;
-      while ( ( draw & split ) == 0 )
+      split = draw & ( -draw );  /* isolate the rightmost 1-bit */
+      while ( ( split >>= 1 ) )
       {
         gray_split_conic( arc );
         arc += 2;
-        split <<= 1;
       }
 
       gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
@@ -1060,28 +1068,32 @@ typedef ptrdiff_t  FT_PtrDist;
   static void
   gray_split_cubic( FT_Vector*  base )
   {
-    TPos  a, b, c, d;
+    TPos  a, b, c;
 
 
     base[6].x = base[3].x;
-    c = base[1].x;
-    d = base[2].x;
-    base[1].x = a = ( base[0].x + c ) / 2;
-    base[5].x = b = ( base[3].x + d ) / 2;
-    c = ( c + d ) / 2;
-    base[2].x = a = ( a + c ) / 2;
-    base[4].x = b = ( b + c ) / 2;
-    base[3].x = ( a + b ) / 2;
+    a = base[0].x + base[1].x;
+    b = base[1].x + base[2].x;
+    c = base[2].x + base[3].x;
+    base[5].x = c >> 1;
+    c += b;
+    base[4].x = c >> 2;
+    base[1].x = a >> 1;
+    a += b;
+    base[2].x = a >> 2;
+    base[3].x = ( a + c ) >> 3;
 
     base[6].y = base[3].y;
-    c = base[1].y;
-    d = base[2].y;
-    base[1].y = a = ( base[0].y + c ) / 2;
-    base[5].y = b = ( base[3].y + d ) / 2;
-    c = ( c + d ) / 2;
-    base[2].y = a = ( a + c ) / 2;
-    base[4].y = b = ( b + c ) / 2;
-    base[3].y = ( a + b ) / 2;
+    a = base[0].y + base[1].y;
+    b = base[1].y + base[2].y;
+    c = base[2].y + base[3].y;
+    base[5].y = c >> 1;
+    c += b;
+    base[4].y = c >> 2;
+    base[1].y = a >> 1;
+    a += b;
+    base[2].y = a >> 2;
+    base[3].y = ( a + c ) >> 3;
   }
 
 
@@ -1092,9 +1104,6 @@ typedef ptrdiff_t  FT_PtrDist;
   {
     FT_Vector   bez_stack[16 * 3 + 1];  /* enough to accommodate bisections */
     FT_Vector*  arc = bez_stack;
-    TPos        dx, dy, dx_, dy_;
-    TPos        dx1, dy1, dx2, dy2;
-    TPos        L, s, s_limit;
 
 
     arc[0].x = UPSCALE( to->x );
@@ -1123,45 +1132,13 @@ typedef ptrdiff_t  FT_PtrDist;
 
     for (;;)
     {
-      /* Decide whether to split or draw. See `Rapid Termination          */
-      /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */
-      /* F. Hain, at                                                      */
-      /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
-
-      /* dx and dy are x and y components of the P0-P3 chord vector. */
-      dx = dx_ = arc[3].x - arc[0].x;
-      dy = dy_ = arc[3].y - arc[0].y;
-
-      L = FT_HYPOT( dx_, dy_ );
-
-      /* Avoid possible arithmetic overflow below by splitting. */
-      if ( L > 32767 )
-        goto Split;
-
-      /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
-      s_limit = L * (TPos)( ONE_PIXEL / 6 );
-
-      /* s is L * the perpendicular distance from P1 to the line P0-P3. */
-      dx1 = arc[1].x - arc[0].x;
-      dy1 = arc[1].y - arc[0].y;
-      s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx1 ), MUL_LONG( dx, dy1 ) ) );
-
-      if ( s > s_limit )
-        goto Split;
-
-      /* s is L * the perpendicular distance from P2 to the line P0-P3. */
-      dx2 = arc[2].x - arc[0].x;
-      dy2 = arc[2].y - arc[0].y;
-      s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx2 ), MUL_LONG( dx, dy2 ) ) );
-
-      if ( s > s_limit )
-        goto Split;
-
-      /* Split super curvy segments where the off points are so far
-         from the chord that the angles P0-P1-P3 or P0-P2-P3 become
-         acute as detected by appropriate dot products. */
-      if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
-           dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
+      /* with each split, control points quickly converge towards  */
+      /* chord trisection points and the vanishing distances below */
+      /* indicate when the segment is flat enough to draw          */
+      if ( FT_ABS( 2 * arc[0].x - 3 * arc[1].x + arc[3].x ) > ONE_PIXEL / 2 ||
+           FT_ABS( 2 * arc[0].y - 3 * arc[1].y + arc[3].y ) > ONE_PIXEL / 2 ||
+           FT_ABS( arc[0].x - 3 * arc[2].x + 2 * arc[3].x ) > ONE_PIXEL / 2 ||
+           FT_ABS( arc[0].y - 3 * arc[2].y + 2 * arc[3].y ) > ONE_PIXEL / 2 )
         goto Split;
 
       gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
@@ -1236,8 +1213,6 @@ typedef ptrdiff_t  FT_PtrDist;
   {
     /* scale the coverage from 0..(ONE_PIXEL*ONE_PIXEL*2) to 0..256  */
     coverage >>= PIXEL_BITS * 2 + 1 - 8;
-    if ( coverage < 0 )
-      coverage = -coverage - 1;
 
     /* compute the line's coverage depending on the outline fill rule */
     if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )
@@ -1247,23 +1222,30 @@ typedef ptrdiff_t  FT_PtrDist;
       if ( coverage >= 256 )
         coverage = 511 - coverage;
     }
-    else
+    else  /* default non-zero winding rule */
     {
-      /* normal non-zero winding rule */
+      if ( coverage < 0 )
+        coverage = ~coverage;  /* the same as -coverage - 1 */
+
       if ( coverage >= 256 )
         coverage = 255;
     }
 
-    if ( ras.render_span )  /* for FT_RASTER_FLAG_DIRECT only */
+    if ( ras.num_spans >= 0 )  /* for FT_RASTER_FLAG_DIRECT only */
     {
-      FT_Span  span;
+      FT_Span*  span = ras.spans + ras.num_spans++;
 
 
-      span.x        = (short)x;
-      span.len      = (unsigned short)acount;
-      span.coverage = (unsigned char)coverage;
+      span->x        = (short)x;
+      span->len      = (unsigned short)acount;
+      span->coverage = (unsigned char)coverage;
 
-      ras.render_span( y, 1, &span, ras.render_span_data );
+      if ( ras.num_spans == FT_MAX_GRAY_SPANS )
+      {
+        /* flush the span buffer and reset the count */
+        ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data );
+        ras.num_spans = 0;
+      }
     }
     else
     {
@@ -1277,14 +1259,29 @@ typedef ptrdiff_t  FT_PtrDist;
        */
       switch ( acount )
       {
-      case 7: *q++ = c;
-      case 6: *q++ = c;
-      case 5: *q++ = c;
-      case 4: *q++ = c;
-      case 3: *q++ = c;
-      case 2: *q++ = c;
-      case 1: *q   = c;
-      case 0: break;
+      case 7:
+        *q++ = c;
+        /* fall through */
+      case 6:
+        *q++ = c;
+        /* fall through */
+      case 5:
+        *q++ = c;
+        /* fall through */
+      case 4:
+        *q++ = c;
+        /* fall through */
+      case 3:
+        *q++ = c;
+        /* fall through */
+      case 2:
+        *q++ = c;
+        /* fall through */
+      case 1:
+        *q = c;
+        /* fall through */
+      case 0:
+        break;
       default:
         FT_MEM_SET( q, c, acount );
       }
@@ -1322,6 +1319,13 @@ typedef ptrdiff_t  FT_PtrDist;
 
       if ( cover != 0 )
         gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x );
+
+      if ( ras.num_spans > 0 )  /* for FT_RASTER_FLAG_DIRECT only */
+      {
+        /* flush the span buffer and reset the count */
+        ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data );
+        ras.num_spans = 0;
+      }
     }
   }
 
@@ -1371,7 +1375,7 @@ typedef ptrdiff_t  FT_PtrDist;
                         void*                    user )
   {
 #undef SCALED
-#define SCALED( x )  ( ( (x) << shift ) - delta )
+#define SCALED( x )  ( (x) * ( 1L << shift ) - delta )
 
     FT_Vector   v_last;
     FT_Vector   v_control;
@@ -1631,7 +1635,7 @@ typedef ptrdiff_t  FT_PtrDist;
   gray_convert_glyph_inner( RAS_ARG,
                             int  continued )
   {
-    volatile int  error = 0;
+    int  error;
 
 
     if ( ft_setjmp( ras.jump_buffer ) == 0 )
@@ -1755,7 +1759,6 @@ typedef ptrdiff_t  FT_PtrDist;
   {
     const FT_Outline*  outline    = (const FT_Outline*)params->source;
     const FT_Bitmap*   target_map = params->target;
-    FT_BBox            clip;
 
 #ifndef FT_STATIC_RASTER
     gray_TWorker  worker[1];
@@ -1792,6 +1795,12 @@ typedef ptrdiff_t  FT_PtrDist;
 
       ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
       ras.render_span_data = params->user;
+      ras.num_spans        = 0;
+
+      ras.min_ex = params->clip_box.xMin;
+      ras.min_ey = params->clip_box.yMin;
+      ras.max_ex = params->clip_box.xMax;
+      ras.max_ey = params->clip_box.yMax;
     }
     else
     {
@@ -1816,27 +1825,15 @@ typedef ptrdiff_t  FT_PtrDist;
 
       ras.render_span      = (FT_Raster_Span_Func)NULL;
       ras.render_span_data = NULL;
-    }
+      ras.num_spans        = -1;  /* invalid */
 
-    /* compute clipping box */
-    if ( params->flags & FT_RASTER_FLAG_DIRECT &&
-         params->flags & FT_RASTER_FLAG_CLIP   )
-      clip = params->clip_box;
-    else
-    {
-      /* compute clip box from target pixmap */
-      clip.xMin = 0;
-      clip.yMin = 0;
-      clip.xMax = (FT_Pos)target_map->width;
-      clip.yMax = (FT_Pos)target_map->rows;
+      ras.min_ex = 0;
+      ras.min_ey = 0;
+      ras.max_ex = (FT_Pos)target_map->width;
+      ras.max_ey = (FT_Pos)target_map->rows;
     }
 
-    /* clip to target bitmap, exit if nothing to do */
-    ras.min_ex = clip.xMin;
-    ras.min_ey = clip.yMin;
-    ras.max_ex = clip.xMax;
-    ras.max_ey = clip.yMax;
-
+    /* exit if nothing to do */
     if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey )
       return 0;
 
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index c8b6bb75186b1134fb0cc36763a7c6865a42c707..cd034d2b4089cd58aad0d2a3f4efec6d3ef91074 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -243,7 +243,7 @@
       }
 
       if ( lcd_filter_func )
-        lcd_filter_func( bitmap, mode, lcd_weights );
+        lcd_filter_func( bitmap, lcd_weights );
     }
 
 #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index cbee27aa69210ae8c74a3f90a44dd84a09470364..a04684086b9e007f3be1ef01527b574243ec9a1a 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -82,6 +82,15 @@
 #define UNSCALED_COMPONENT_OFFSET  0x1000
 
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#define IS_DEFAULT_INSTANCE( _face )             \
+          ( !( FT_IS_NAMED_INSTANCE( _face ) ||  \
+               FT_IS_VARIATION( _face )      ) )
+#else
+#define IS_DEFAULT_INSTANCE( _face )  1
+#endif
+
+
   /**************************************************************************
    *
    * Return the horizontal metrics in font units for a given glyph.
@@ -927,6 +936,11 @@
     FT_Outline*     outline;
     FT_Int          n_points;
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    FT_Memory   memory    = loader->face->root.memory;
+    FT_Vector*  unrounded = NULL;
+#endif
+
 
     outline  = &gloader->current.outline;
     n_points = outline->n_points;
@@ -947,26 +961,32 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
-    if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
-         FT_IS_VARIATION( FT_FACE( loader->face ) )      )
+    if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
     {
+      if ( FT_NEW_ARRAY( unrounded, n_points ) )
+        goto Exit;
+
       /* Deltas apply to the unscaled data. */
       error = TT_Vary_Apply_Glyph_Deltas( loader->face,
                                           loader->glyph_index,
                                           outline,
+                                          unrounded,
                                           (FT_UInt)n_points );
 
       /* recalculate linear horizontal and vertical advances */
       /* if we don't have HVAR and VVAR, respectively        */
+
+      /* XXX: change all FreeType modules to store `linear' and `vadvance' */
+      /*      in 26.6 format before the `base' module scales them to 16.16 */
       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
-        loader->linear = outline->points[n_points - 3].x -
-                         outline->points[n_points - 4].x;
+        loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x -
+                                       unrounded[n_points - 4].x ) / 64;
       if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
-        loader->vadvance = outline->points[n_points - 1].x -
-                           outline->points[n_points - 2].x;
+        loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].x -
+                                         unrounded[n_points - 2].x ) / 64;
 
       if ( error )
-        return error;
+        goto Exit;
     }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1021,10 +1041,23 @@
           /* compensate for any scaling by de/emboldening; */
           /* the amount was determined via experimentation */
           if ( x_scale_factor != 1000 && ppem > 11 )
+          {
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+            FT_Vector*  orig_points = outline->points;
+
+
+            if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
+              outline->points = unrounded;
+#endif
             FT_Outline_EmboldenXY( outline,
                                    FT_MulFix( 1280 * ppem,
                                               1000 - x_scale_factor ),
                                    0 );
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+            if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
+              outline->points = orig_points;
+#endif
+          }
           do_scale = TRUE;
         }
       }
@@ -1045,10 +1078,26 @@
 
       if ( do_scale )
       {
-        for ( ; vec < limit; vec++ )
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+        if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
         {
-          vec->x = FT_MulFix( vec->x, x_scale );
-          vec->y = FT_MulFix( vec->y, y_scale );
+          FT_Vector*  u = unrounded;
+
+
+          for ( ; vec < limit; vec++, u++ )
+          {
+            vec->x = ( FT_MulFix( u->x, x_scale ) + 32 ) >> 6;
+            vec->y = ( FT_MulFix( u->y, y_scale ) + 32 ) >> 6;
+          }
+        }
+        else
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+        {
+          for ( ; vec < limit; vec++ )
+          {
+            vec->x = FT_MulFix( vec->x, x_scale );
+            vec->y = FT_MulFix( vec->y, y_scale );
+          }
         }
       }
 
@@ -1080,6 +1129,11 @@
       error = TT_Hint_Glyph( loader, 0 );
     }
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+  Exit:
+    FT_FREE( unrounded );
+#endif
+
     return error;
   }
 
@@ -1681,6 +1735,9 @@
         short       contours[4] = { 0, 1, 2, 3 };
         FT_Outline  outline;
 
+        /* unrounded values */
+        FT_Vector  unrounded[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
+
 
         points[0].x = loader->pp1.x;
         points[0].y = loader->pp1.y;
@@ -1702,6 +1759,7 @@
         error = TT_Vary_Apply_Glyph_Deltas( loader->face,
                                             glyph_index,
                                             &outline,
+                                            unrounded,
                                             (FT_UInt)outline.n_points );
         if ( error )
           goto Exit;
@@ -1719,9 +1777,11 @@
         /* recalculate linear horizontal and vertical advances */
         /* if we don't have HVAR and VVAR, respectively        */
         if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
-          loader->linear = loader->pp2.x - loader->pp1.x;
+          loader->linear = FT_PIX_ROUND( unrounded[1].x -
+                                         unrounded[0].x ) / 64;
         if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
-          loader->vadvance = loader->pp4.x - loader->pp3.x;
+          loader->vadvance = FT_PIX_ROUND( unrounded[3].x -
+                                           unrounded[2].x ) / 64;
       }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1861,9 +1921,10 @@
         FT_SubGlyph  subglyph;
 
         FT_Outline  outline;
-        FT_Vector*  points   = NULL;
-        char*       tags     = NULL;
-        short*      contours = NULL;
+        FT_Vector*  points    = NULL;
+        char*       tags      = NULL;
+        short*      contours  = NULL;
+        FT_Vector*  unrounded = NULL;
 
 
         limit = (short)gloader->current.num_subglyphs;
@@ -1877,9 +1938,10 @@
         outline.tags     = NULL;
         outline.contours = NULL;
 
-        if ( FT_NEW_ARRAY( points, outline.n_points )   ||
-             FT_NEW_ARRAY( tags, outline.n_points )     ||
-             FT_NEW_ARRAY( contours, outline.n_points ) )
+        if ( FT_NEW_ARRAY( points, outline.n_points )    ||
+             FT_NEW_ARRAY( tags, outline.n_points )      ||
+             FT_NEW_ARRAY( contours, outline.n_points )  ||
+             FT_NEW_ARRAY( unrounded, outline.n_points ) )
           goto Exit1;
 
         subglyph = gloader->current.subglyphs;
@@ -1928,6 +1990,7 @@
                              face,
                              glyph_index,
                              &outline,
+                             unrounded,
                              (FT_UInt)outline.n_points ) ) )
           goto Exit1;
 
@@ -1955,14 +2018,19 @@
         /* recalculate linear horizontal and vertical advances */
         /* if we don't have HVAR and VVAR, respectively        */
         if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
-          loader->linear = loader->pp2.x - loader->pp1.x;
+          loader->linear =
+            FT_PIX_ROUND( unrounded[outline.n_points - 3].x -
+                          unrounded[outline.n_points - 4].x ) / 64;
         if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
-          loader->vadvance = loader->pp4.x - loader->pp3.x;
+          loader->vadvance =
+            FT_PIX_ROUND( unrounded[outline.n_points - 1].x -
+                          unrounded[outline.n_points - 2].x ) / 64;
 
       Exit1:
         FT_FREE( outline.points );
         FT_FREE( outline.tags );
         FT_FREE( outline.contours );
+        FT_FREE( unrounded );
 
         if ( error )
           goto Exit;
@@ -2088,6 +2156,7 @@
         loader->ins_pos = ins_pos;
         if ( IS_HINTED( loader->load_flags ) &&
 #ifdef TT_USE_BYTECODE_INTERPRETER
+             subglyph                        &&
              subglyph->flags & WE_HAVE_INSTR &&
 #endif
              num_points > start_point )
@@ -2611,11 +2680,6 @@
 
       if ( reexecute )
       {
-        FT_UInt  i;
-
-
-        for ( i = 0; i < size->cvt_size; i++ )
-          size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
         error = tt_size_run_prep( size, pedantic );
         if ( error )
           return error;
@@ -2718,13 +2782,6 @@
     FT_Error      error;
     TT_LoaderRec  loader;
 
-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-#define IS_DEFAULT_INSTANCE  ( !( FT_IS_NAMED_INSTANCE( glyph->face ) ||  \
-                                  FT_IS_VARIATION( glyph->face )      ) )
-#else
-#define IS_DEFAULT_INSTANCE  1
-#endif
-
 
     FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
 
@@ -2733,7 +2790,7 @@
     /* try to load embedded bitmap (if any) */
     if ( size->strike_index != 0xFFFFFFFFUL      &&
          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
-         IS_DEFAULT_INSTANCE                     )
+         IS_DEFAULT_INSTANCE( glyph->face )      )
     {
       FT_Fixed  x_scale = size->root.metrics.x_scale;
       FT_Fixed  y_scale = size->root.metrics.y_scale;
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index 020918f53368eb43d14768077d610b5001e3dec2..78d87dc097f31f64c7e7b0c3bbf49095ca3466f6 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -68,12 +68,16 @@
 
 
   /* some macros we need */
-#define FT_fdot14ToFixed( x )                \
-        ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
-#define FT_intToFixed( i )                    \
-        ( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
-#define FT_fixedToInt( x )                                   \
-        ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) )
+#define FT_fdot14ToFixed( x )                  \
+          ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
+#define FT_intToFixed( i )                      \
+          ( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
+#define FT_fdot6ToFixed( i )                    \
+          ( (FT_Fixed)( (FT_ULong)(i) << 10 ) )
+#define FT_fixedToInt( x )                          \
+          ( (FT_Short)( ( (x) + 0x8000U ) >> 16 ) )
+#define FT_fixedToFdot6( x )                    \
+          ( (FT_Pos)( ( (x) + 0x200 ) >> 10 ) )
 
 
   /**************************************************************************
@@ -397,9 +401,10 @@
 
       for ( j = 0; j < segment->pairCount; j++ )
       {
-        /* convert to Fixed */
-        segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4;
-        segment->correspondence[j].toCoord   = FT_GET_SHORT() * 4;
+        segment->correspondence[j].fromCoord =
+          FT_fdot14ToFixed( FT_GET_SHORT() );
+        segment->correspondence[j].toCoord =
+          FT_fdot14ToFixed( FT_GET_SHORT() );
 
         FT_TRACE5(( "    mapping %.5f to %.5f\n",
                     segment->correspondence[j].fromCoord / 65536.0,
@@ -1616,7 +1621,7 @@
         for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ )
         {
           blend->tuplecoords[i * gvar_head.axisCount + j] =
-            FT_GET_SHORT() * 4;                 /* convert to FT_Fixed */
+            FT_fdot14ToFixed( FT_GET_SHORT() );
           FT_TRACE5(( "%.5f ",
             blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
         }
@@ -3054,7 +3059,7 @@
     if ( instance_index > num_instances )
       goto Exit;
 
-    if ( instance_index > 0 && mmvar->namedstyle )
+    if ( instance_index > 0 )
     {
       FT_Memory     memory = face->root.memory;
       SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
@@ -3080,7 +3085,12 @@
                                  mmvar->num_axis,
                                  named_style->coords );
       if ( error )
+      {
+        /* internal error code -1 means `no change' */
+        if ( error == -1 )
+          error = FT_Err_Ok;
         goto Exit;
+      }
     }
     else
       error = TT_Set_Var_Design( face, 0, NULL );
@@ -3103,6 +3113,21 @@
   /*************************************************************************/
 
 
+  static FT_Error
+  tt_cvt_ready_iterator( FT_ListNode  node,
+                         void*        user )
+  {
+    TT_Size  size = (TT_Size)node->data;
+
+    FT_UNUSED( user );
+
+
+    size->cvt_ready = -1;
+
+    return FT_Err_Ok;
+  }
+
+
   /**************************************************************************
    *
    * @Function:
@@ -3133,6 +3158,8 @@
     FT_Error   error;
     FT_Memory  memory = stream->memory;
 
+    FT_Face  root = &face->root;
+
     FT_ULong  table_start;
     FT_ULong  table_len;
 
@@ -3261,8 +3288,7 @@
       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
       {
         for ( j = 0; j < blend->num_axis; j++ )
-          tuple_coords[j] = FT_GET_SHORT() * 4;  /* convert from        */
-                                                 /* short frac to fixed */
+          tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
       }
       else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
       {
@@ -3293,9 +3319,9 @@
       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
       {
         for ( j = 0; j < blend->num_axis; j++ )
-          im_start_coords[j] = FT_GET_SHORT() * 4;
+          im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
         for ( j = 0; j < blend->num_axis; j++ )
-          im_end_coords[j] = FT_GET_SHORT() * 4;
+          im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
       }
 
       apply = ft_var_apply_tuple( blend,
@@ -3360,9 +3386,9 @@
           {
             FT_TRACE7(( "      %d: %f -> %f\n",
                         j,
-                        ( FT_intToFixed( face->cvt[j] ) +
+                        ( FT_fdot6ToFixed( face->cvt[j] ) +
                           old_cvt_delta ) / 65536.0,
-                        ( FT_intToFixed( face->cvt[j] ) +
+                        ( FT_fdot6ToFixed( face->cvt[j] ) +
                           cvt_deltas[j] ) / 65536.0 ));
             count++;
           }
@@ -3402,9 +3428,9 @@
           {
             FT_TRACE7(( "      %d: %f -> %f\n",
                         pindex,
-                        ( FT_intToFixed( face->cvt[pindex] ) +
+                        ( FT_fdot6ToFixed( face->cvt[pindex] ) +
                           old_cvt_delta ) / 65536.0,
-                        ( FT_intToFixed( face->cvt[pindex] ) +
+                        ( FT_fdot6ToFixed( face->cvt[pindex] ) +
                           cvt_deltas[pindex] ) / 65536.0 ));
             count++;
           }
@@ -3429,7 +3455,7 @@
     FT_TRACE5(( "\n" ));
 
     for ( i = 0; i < face->cvt_size; i++ )
-      face->cvt[i] += FT_fixedToInt( cvt_deltas[i] );
+      face->cvt[i] += FT_fixedToFdot6( cvt_deltas[i] );
 
   FExit:
     FT_FRAME_EXIT();
@@ -3442,6 +3468,12 @@
     FT_FREE( im_end_coords );
     FT_FREE( cvt_deltas );
 
+    /* iterate over all FT_Size objects and set `cvt_ready' to -1 */
+    /* to trigger rescaling of all CVT values                     */
+    FT_List_Iterate( &root->sizes_list,
+                     tt_cvt_ready_iterator,
+                     NULL );
+
     return error;
   }
 
@@ -3669,6 +3701,11 @@
    *   outline ::
    *     The outline to change.
    *
+   * @Output:
+   *   unrounded ::
+   *     An array with `n_points' elements that is filled with unrounded
+   *     point coordinates (in 26.6 format).
+   *
    * @Return:
    *   FreeType error code.  0 means success.
    */
@@ -3676,6 +3713,7 @@
   TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
                               FT_UInt      glyph_index,
                               FT_Outline*  outline,
+                              FT_Vector*   unrounded,
                               FT_UInt      n_points )
   {
     FT_Error   error;
@@ -3717,6 +3755,12 @@
     if ( !face->doblend || !blend )
       return FT_THROW( Invalid_Argument );
 
+    for ( i = 0; i < n_points; i++ )
+    {
+      unrounded[i].x = INT_TO_F26DOT6( outline->points[i].x );
+      unrounded[i].y = INT_TO_F26DOT6( outline->points[i].y );
+    }
+
     if ( glyph_index >= blend->gv_glyphcnt      ||
          blend->glyphoffsets[glyph_index] ==
            blend->glyphoffsets[glyph_index + 1] )
@@ -3807,8 +3851,7 @@
       if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD )
       {
         for ( j = 0; j < blend->num_axis; j++ )
-          tuple_coords[j] = FT_GET_SHORT() * 4;   /* convert from        */
-                                                  /* short frac to fixed */
+          tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
       }
       else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount )
       {
@@ -3828,9 +3871,9 @@
       if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE )
       {
         for ( j = 0; j < blend->num_axis; j++ )
-          im_start_coords[j] = FT_GET_SHORT() * 4;
+          im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
         for ( j = 0; j < blend->num_axis; j++ )
-          im_end_coords[j] = FT_GET_SHORT() * 4;
+          im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
       }
 
       apply = ft_var_apply_tuple( blend,
@@ -4064,6 +4107,9 @@
 
     for ( i = 0; i < n_points; i++ )
     {
+      unrounded[i].x += FT_fixedToFdot6( point_deltas_x[i] );
+      unrounded[i].y += FT_fixedToFdot6( point_deltas_y[i] );
+
       outline->points[i].x += FT_fixedToInt( point_deltas_x[i] );
       outline->points[i].y += FT_fixedToInt( point_deltas_y[i] );
     }
diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h
index 7e8d9768a76a2a9482247342475ace5d9cdbe730..07c99b6403b628550f8752825c80332cb4cfbba6 100644
--- a/src/truetype/ttgxvar.h
+++ b/src/truetype/ttgxvar.h
@@ -416,6 +416,7 @@ FT_BEGIN_HEADER
   TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
                               FT_UInt      glyph_index,
                               FT_Outline*  outline,
+                              FT_Vector*   unrounded,
                               FT_UInt      n_points );
 
   FT_LOCAL( FT_Error )
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 403f3753c7b5b46db1f55a17d0f8aeab20d935b0..70434e1729169f0ef52ef2b99f32bcf04924aa86 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -654,23 +654,25 @@
     /* opcodes are gathered in groups of 16 */
     /* please keep the spaces as they are   */
 
-    /*  SVTCA  y  */  PACK( 0, 0 ),
-    /*  SVTCA  x  */  PACK( 0, 0 ),
-    /*  SPvTCA y  */  PACK( 0, 0 ),
-    /*  SPvTCA x  */  PACK( 0, 0 ),
-    /*  SFvTCA y  */  PACK( 0, 0 ),
-    /*  SFvTCA x  */  PACK( 0, 0 ),
-    /*  SPvTL //  */  PACK( 2, 0 ),
-    /*  SPvTL +   */  PACK( 2, 0 ),
-    /*  SFvTL //  */  PACK( 2, 0 ),
-    /*  SFvTL +   */  PACK( 2, 0 ),
-    /*  SPvFS     */  PACK( 2, 0 ),
-    /*  SFvFS     */  PACK( 2, 0 ),
-    /*  GPv       */  PACK( 0, 2 ),
-    /*  GFv       */  PACK( 0, 2 ),
-    /*  SFvTPv    */  PACK( 0, 0 ),
+    /* 0x00 */
+    /*  SVTCA[0]  */  PACK( 0, 0 ),
+    /*  SVTCA[1]  */  PACK( 0, 0 ),
+    /*  SPVTCA[0] */  PACK( 0, 0 ),
+    /*  SPVTCA[1] */  PACK( 0, 0 ),
+    /*  SFVTCA[0] */  PACK( 0, 0 ),
+    /*  SFVTCA[1] */  PACK( 0, 0 ),
+    /*  SPVTL[0]  */  PACK( 2, 0 ),
+    /*  SPVTL[1]  */  PACK( 2, 0 ),
+    /*  SFVTL[0]  */  PACK( 2, 0 ),
+    /*  SFVTL[1]  */  PACK( 2, 0 ),
+    /*  SPVFS     */  PACK( 2, 0 ),
+    /*  SFVFS     */  PACK( 2, 0 ),
+    /*  GPV       */  PACK( 0, 2 ),
+    /*  GFV       */  PACK( 0, 2 ),
+    /*  SFVTPV    */  PACK( 0, 0 ),
     /*  ISECT     */  PACK( 5, 0 ),
 
+    /* 0x10 */
     /*  SRP0      */  PACK( 1, 0 ),
     /*  SRP1      */  PACK( 1, 0 ),
     /*  SRP2      */  PACK( 1, 0 ),
@@ -684,10 +686,11 @@
     /*  SMD       */  PACK( 1, 0 ),
     /*  ELSE      */  PACK( 0, 0 ),
     /*  JMPR      */  PACK( 1, 0 ),
-    /*  SCvTCi    */  PACK( 1, 0 ),
-    /*  SSwCi     */  PACK( 1, 0 ),
+    /*  SCVTCI    */  PACK( 1, 0 ),
+    /*  SSWCI     */  PACK( 1, 0 ),
     /*  SSW       */  PACK( 1, 0 ),
 
+    /* 0x20 */
     /*  DUP       */  PACK( 1, 2 ),
     /*  POP       */  PACK( 1, 0 ),
     /*  CLEAR     */  PACK( 0, 0 ),
@@ -695,7 +698,7 @@
     /*  DEPTH     */  PACK( 0, 1 ),
     /*  CINDEX    */  PACK( 1, 1 ),
     /*  MINDEX    */  PACK( 1, 0 ),
-    /*  AlignPTS  */  PACK( 2, 0 ),
+    /*  ALIGNPTS  */  PACK( 2, 0 ),
     /*  INS_$28   */  PACK( 0, 0 ),
     /*  UTP       */  PACK( 1, 0 ),
     /*  LOOPCALL  */  PACK( 2, 0 ),
@@ -705,6 +708,7 @@
     /*  MDAP[0]   */  PACK( 1, 0 ),
     /*  MDAP[1]   */  PACK( 1, 0 ),
 
+    /* 0x30 */
     /*  IUP[0]    */  PACK( 0, 0 ),
     /*  IUP[1]    */  PACK( 0, 0 ),
     /*  SHP[0]    */  PACK( 0, 0 ), /* loops */
@@ -717,17 +721,18 @@
     /*  IP        */  PACK( 0, 0 ), /* loops */
     /*  MSIRP[0]  */  PACK( 2, 0 ),
     /*  MSIRP[1]  */  PACK( 2, 0 ),
-    /*  AlignRP   */  PACK( 0, 0 ), /* loops */
+    /*  ALIGNRP   */  PACK( 0, 0 ), /* loops */
     /*  RTDG      */  PACK( 0, 0 ),
     /*  MIAP[0]   */  PACK( 2, 0 ),
     /*  MIAP[1]   */  PACK( 2, 0 ),
 
-    /*  NPushB    */  PACK( 0, 0 ),
-    /*  NPushW    */  PACK( 0, 0 ),
+    /* 0x40 */
+    /*  NPUSHB    */  PACK( 0, 0 ),
+    /*  NPUSHW    */  PACK( 0, 0 ),
     /*  WS        */  PACK( 2, 0 ),
     /*  RS        */  PACK( 1, 1 ),
-    /*  WCvtP     */  PACK( 2, 0 ),
-    /*  RCvt      */  PACK( 1, 1 ),
+    /*  WCVTP     */  PACK( 2, 0 ),
+    /*  RCVT      */  PACK( 1, 1 ),
     /*  GC[0]     */  PACK( 1, 1 ),
     /*  GC[1]     */  PACK( 1, 1 ),
     /*  SCFS      */  PACK( 2, 0 ),
@@ -735,10 +740,11 @@
     /*  MD[1]     */  PACK( 2, 1 ),
     /*  MPPEM     */  PACK( 0, 1 ),
     /*  MPS       */  PACK( 0, 1 ),
-    /*  FlipON    */  PACK( 0, 0 ),
-    /*  FlipOFF   */  PACK( 0, 0 ),
+    /*  FLIPON    */  PACK( 0, 0 ),
+    /*  FLIPOFF   */  PACK( 0, 0 ),
     /*  DEBUG     */  PACK( 1, 0 ),
 
+    /* 0x50 */
     /*  LT        */  PACK( 2, 1 ),
     /*  LTEQ      */  PACK( 2, 1 ),
     /*  GT        */  PACK( 2, 1 ),
@@ -752,10 +758,11 @@
     /*  AND       */  PACK( 2, 1 ),
     /*  OR        */  PACK( 2, 1 ),
     /*  NOT       */  PACK( 1, 1 ),
-    /*  DeltaP1   */  PACK( 1, 0 ),
+    /*  DELTAP1   */  PACK( 1, 0 ),
     /*  SDB       */  PACK( 1, 0 ),
     /*  SDS       */  PACK( 1, 0 ),
 
+    /* 0x60 */
     /*  ADD       */  PACK( 2, 1 ),
     /*  SUB       */  PACK( 2, 1 ),
     /*  DIV       */  PACK( 2, 1 ),
@@ -773,14 +780,15 @@
     /*  NROUND[2] */  PACK( 1, 1 ),
     /*  NROUND[3] */  PACK( 1, 1 ),
 
-    /*  WCvtF     */  PACK( 2, 0 ),
-    /*  DeltaP2   */  PACK( 1, 0 ),
-    /*  DeltaP3   */  PACK( 1, 0 ),
-    /*  DeltaCn[0] */ PACK( 1, 0 ),
-    /*  DeltaCn[1] */ PACK( 1, 0 ),
-    /*  DeltaCn[2] */ PACK( 1, 0 ),
+    /* 0x70 */
+    /*  WCVTF     */  PACK( 2, 0 ),
+    /*  DELTAP2   */  PACK( 1, 0 ),
+    /*  DELTAP3   */  PACK( 1, 0 ),
+    /*  DELTAC1   */  PACK( 1, 0 ),
+    /*  DELTAC2   */  PACK( 1, 0 ),
+    /*  DELTAC3   */  PACK( 1, 0 ),
     /*  SROUND    */  PACK( 1, 0 ),
-    /*  S45Round  */  PACK( 1, 0 ),
+    /*  S45ROUND  */  PACK( 1, 0 ),
     /*  JROT      */  PACK( 2, 0 ),
     /*  JROF      */  PACK( 2, 0 ),
     /*  ROFF      */  PACK( 0, 0 ),
@@ -790,23 +798,25 @@
     /*  SANGW     */  PACK( 1, 0 ),
     /*  AA        */  PACK( 1, 0 ),
 
-    /*  FlipPT    */  PACK( 0, 0 ), /* loops */
-    /*  FlipRgON  */  PACK( 2, 0 ),
-    /*  FlipRgOFF */  PACK( 2, 0 ),
+    /* 0x80 */
+    /*  FLIPPT    */  PACK( 0, 0 ), /* loops */
+    /*  FLIPRGON  */  PACK( 2, 0 ),
+    /*  FLIPRGOFF */  PACK( 2, 0 ),
     /*  INS_$83   */  PACK( 0, 0 ),
     /*  INS_$84   */  PACK( 0, 0 ),
-    /*  ScanCTRL  */  PACK( 1, 0 ),
-    /*  SDPvTL[0] */  PACK( 2, 0 ),
-    /*  SDPvTL[1] */  PACK( 2, 0 ),
-    /*  GetINFO   */  PACK( 1, 1 ),
+    /*  SCANCTRL  */  PACK( 1, 0 ),
+    /*  SDPVTL[0] */  PACK( 2, 0 ),
+    /*  SDPVTL[1] */  PACK( 2, 0 ),
+    /*  GETINFO   */  PACK( 1, 1 ),
     /*  IDEF      */  PACK( 1, 0 ),
     /*  ROLL      */  PACK( 3, 3 ),
     /*  MAX       */  PACK( 2, 1 ),
     /*  MIN       */  PACK( 2, 1 ),
-    /*  ScanTYPE  */  PACK( 1, 0 ),
-    /*  InstCTRL  */  PACK( 2, 0 ),
+    /*  SCANTYPE  */  PACK( 1, 0 ),
+    /*  INSTCTRL  */  PACK( 2, 0 ),
     /*  INS_$8F   */  PACK( 0, 0 ),
 
+    /* 0x90 */
     /*  INS_$90  */   PACK( 0, 0 ),
     /*  GETVAR   */   PACK( 0, 0 ), /* will be handled specially */
     /*  GETDATA  */   PACK( 0, 1 ),
@@ -824,6 +834,7 @@
     /*  INS_$9E  */   PACK( 0, 0 ),
     /*  INS_$9F  */   PACK( 0, 0 ),
 
+    /* 0xA0 */
     /*  INS_$A0  */   PACK( 0, 0 ),
     /*  INS_$A1  */   PACK( 0, 0 ),
     /*  INS_$A2  */   PACK( 0, 0 ),
@@ -841,23 +852,25 @@
     /*  INS_$AE  */   PACK( 0, 0 ),
     /*  INS_$AF  */   PACK( 0, 0 ),
 
-    /*  PushB[0]  */  PACK( 0, 1 ),
-    /*  PushB[1]  */  PACK( 0, 2 ),
-    /*  PushB[2]  */  PACK( 0, 3 ),
-    /*  PushB[3]  */  PACK( 0, 4 ),
-    /*  PushB[4]  */  PACK( 0, 5 ),
-    /*  PushB[5]  */  PACK( 0, 6 ),
-    /*  PushB[6]  */  PACK( 0, 7 ),
-    /*  PushB[7]  */  PACK( 0, 8 ),
-    /*  PushW[0]  */  PACK( 0, 1 ),
-    /*  PushW[1]  */  PACK( 0, 2 ),
-    /*  PushW[2]  */  PACK( 0, 3 ),
-    /*  PushW[3]  */  PACK( 0, 4 ),
-    /*  PushW[4]  */  PACK( 0, 5 ),
-    /*  PushW[5]  */  PACK( 0, 6 ),
-    /*  PushW[6]  */  PACK( 0, 7 ),
-    /*  PushW[7]  */  PACK( 0, 8 ),
-
+    /* 0xB0 */
+    /*  PUSHB[0]  */  PACK( 0, 1 ),
+    /*  PUSHB[1]  */  PACK( 0, 2 ),
+    /*  PUSHB[2]  */  PACK( 0, 3 ),
+    /*  PUSHB[3]  */  PACK( 0, 4 ),
+    /*  PUSHB[4]  */  PACK( 0, 5 ),
+    /*  PUSHB[5]  */  PACK( 0, 6 ),
+    /*  PUSHB[6]  */  PACK( 0, 7 ),
+    /*  PUSHB[7]  */  PACK( 0, 8 ),
+    /*  PUSHW[0]  */  PACK( 0, 1 ),
+    /*  PUSHW[1]  */  PACK( 0, 2 ),
+    /*  PUSHW[2]  */  PACK( 0, 3 ),
+    /*  PUSHW[3]  */  PACK( 0, 4 ),
+    /*  PUSHW[4]  */  PACK( 0, 5 ),
+    /*  PUSHW[5]  */  PACK( 0, 6 ),
+    /*  PUSHW[6]  */  PACK( 0, 7 ),
+    /*  PUSHW[7]  */  PACK( 0, 8 ),
+
+    /* 0xC0 */
     /*  MDRP[00]  */  PACK( 1, 0 ),
     /*  MDRP[01]  */  PACK( 1, 0 ),
     /*  MDRP[02]  */  PACK( 1, 0 ),
@@ -875,6 +888,7 @@
     /*  MDRP[14]  */  PACK( 1, 0 ),
     /*  MDRP[15]  */  PACK( 1, 0 ),
 
+    /* 0xD0 */
     /*  MDRP[16]  */  PACK( 1, 0 ),
     /*  MDRP[17]  */  PACK( 1, 0 ),
     /*  MDRP[18]  */  PACK( 1, 0 ),
@@ -892,6 +906,7 @@
     /*  MDRP[30]  */  PACK( 1, 0 ),
     /*  MDRP[31]  */  PACK( 1, 0 ),
 
+    /* 0xE0 */
     /*  MIRP[00]  */  PACK( 2, 0 ),
     /*  MIRP[01]  */  PACK( 2, 0 ),
     /*  MIRP[02]  */  PACK( 2, 0 ),
@@ -909,6 +924,7 @@
     /*  MIRP[14]  */  PACK( 2, 0 ),
     /*  MIRP[15]  */  PACK( 2, 0 ),
 
+    /* 0xF0 */
     /*  MIRP[16]  */  PACK( 2, 0 ),
     /*  MIRP[17]  */  PACK( 2, 0 ),
     /*  MIRP[18]  */  PACK( 2, 0 ),
@@ -937,23 +953,25 @@
   static
   const char*  const opcode_name[256] =
   {
-    "7 SVTCA y",
-    "7 SVTCA x",
-    "8 SPvTCA y",
-    "8 SPvTCA x",
-    "8 SFvTCA y",
-    "8 SFvTCA x",
-    "8 SPvTL ||",
-    "7 SPvTL +",
-    "8 SFvTL ||",
-    "7 SFvTL +",
-    "5 SPvFS",
-    "5 SFvFS",
-    "3 GPv",
-    "3 GFv",
-    "6 SFvTPv",
+    /* 0x00 */
+    "8 SVTCA[y]",
+    "8 SVTCA[x]",
+    "9 SPVTCA[y]",
+    "9 SPVTCA[x]",
+    "9 SFVTCA[y]",
+    "9 SFVTCA[x]",
+    "9 SPVTL[||]",
+    "8 SPVTL[+]",
+    "9 SFVTL[||]",
+    "8 SFVTL[+]",
+    "5 SPVFS",
+    "5 SFVFS",
+    "3 GPV",
+    "3 GFV",
+    "6 SFVTPV",
     "5 ISECT",
 
+    /* 0x10 */
     "4 SRP0",
     "4 SRP1",
     "4 SRP2",
@@ -967,10 +985,11 @@
     "3 SMD",
     "4 ELSE",
     "4 JMPR",
-    "6 SCvTCi",
-    "5 SSwCi",
+    "6 SCVTCI",
+    "5 SSWCI",
     "3 SSW",
 
+    /* 0x20 */
     "3 DUP",
     "3 POP",
     "5 CLEAR",
@@ -978,50 +997,53 @@
     "5 DEPTH",
     "6 CINDEX",
     "6 MINDEX",
-    "8 AlignPTS",
+    "8 ALIGNPTS",
     "7 INS_$28",
     "3 UTP",
     "8 LOOPCALL",
     "4 CALL",
     "4 FDEF",
     "4 ENDF",
-    "7 MDAP[0]",
-    "7 MDAP[1]",
-
-    "6 IUP[0]",
-    "6 IUP[1]",
-    "6 SHP[0]",
-    "6 SHP[1]",
-    "6 SHC[0]",
-    "6 SHC[1]",
-    "6 SHZ[0]",
-    "6 SHZ[1]",
+    "6 MDAP[]",
+    "9 MDAP[rnd]",
+
+    /* 0x30 */
+    "6 IUP[y]",
+    "6 IUP[x]",
+    "8 SHP[rp2]",
+    "8 SHP[rp1]",
+    "8 SHC[rp2]",
+    "8 SHC[rp1]",
+    "8 SHZ[rp2]",
+    "8 SHZ[rp1]",
     "5 SHPIX",
     "2 IP",
-    "8 MSIRP[0]",
-    "8 MSIRP[1]",
-    "7 AlignRP",
+    "7 MSIRP[]",
+    "A MSIRP[rp0]",
+    "7 ALIGNRP",
     "4 RTDG",
-    "7 MIAP[0]",
-    "7 MIAP[1]",
+    "6 MIAP[]",
+    "9 MIAP[rnd]",
 
-    "6 NPushB",
-    "6 NPushW",
+    /* 0x40 */
+    "6 NPUSHB",
+    "6 NPUSHW",
     "2 WS",
     "2 RS",
-    "5 WCvtP",
-    "4 RCvt",
-    "5 GC[0]",
-    "5 GC[1]",
+    "5 WCVTP",
+    "4 RCVT",
+    "8 GC[curr]",
+    "8 GC[orig]",
     "4 SCFS",
-    "5 MD[0]",
-    "5 MD[1]",
+    "8 MD[curr]",
+    "8 MD[orig]",
     "5 MPPEM",
     "3 MPS",
-    "6 FlipON",
-    "7 FlipOFF",
+    "6 FLIPON",
+    "7 FLIPOFF",
     "5 DEBUG",
 
+    /* 0x50 */
     "2 LT",
     "4 LTEQ",
     "2 GT",
@@ -1035,10 +1057,11 @@
     "3 AND",
     "2 OR",
     "3 NOT",
-    "7 DeltaP1",
+    "7 DELTAP1",
     "3 SDB",
     "3 SDS",
 
+    /* 0x60 */
     "3 ADD",
     "3 SUB",
     "3 DIV",
@@ -1047,23 +1070,24 @@
     "3 NEG",
     "5 FLOOR",
     "7 CEILING",
-    "8 ROUND[0]",
-    "8 ROUND[1]",
-    "8 ROUND[2]",
-    "8 ROUND[3]",
-    "9 NROUND[0]",
-    "9 NROUND[1]",
-    "9 NROUND[2]",
-    "9 NROUND[3]",
-
-    "5 WCvtF",
-    "7 DeltaP2",
-    "7 DeltaP3",
-    "A DeltaCn[0]",
-    "A DeltaCn[1]",
-    "A DeltaCn[2]",
+    "8 ROUND[G]",
+    "8 ROUND[B]",
+    "8 ROUND[W]",
+    "7 ROUND[]",
+    "9 NROUND[G]",
+    "9 NROUND[B]",
+    "9 NROUND[W]",
+    "8 NROUND[]",
+
+    /* 0x70 */
+    "5 WCVTF",
+    "7 DELTAP2",
+    "7 DELTAP3",
+    "7 DELTAC1",
+    "7 DELTAC2",
+    "7 DELTAC3",
     "6 SROUND",
-    "8 S45Round",
+    "8 S45ROUND",
     "4 JROT",
     "4 JROF",
     "4 ROFF",
@@ -1073,26 +1097,28 @@
     "5 SANGW",
     "2 AA",
 
-    "6 FlipPT",
-    "8 FlipRgON",
-    "9 FlipRgOFF",
+    /* 0x80 */
+    "6 FLIPPT",
+    "8 FLIPRGON",
+    "9 FLIPRGOFF",
     "7 INS_$83",
     "7 INS_$84",
-    "8 ScanCTRL",
-    "9 SDPvTL[0]",
-    "9 SDPvTL[1]",
-    "7 GetINFO",
+    "8 SCANCTRL",
+    "A SDPVTL[||]",
+    "9 SDPVTL[+]",
+    "7 GETINFO",
     "4 IDEF",
     "4 ROLL",
     "3 MAX",
     "3 MIN",
-    "8 ScanTYPE",
-    "8 InstCTRL",
+    "8 SCANTYPE",
+    "8 INSTCTRL",
     "7 INS_$8F",
 
+    /* 0x90 */
     "7 INS_$90",
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    "6 GETVAR",
+    "C GETVARIATION",
     "7 GETDATA",
 #else
     "7 INS_$91",
@@ -1112,6 +1138,7 @@
     "7 INS_$9E",
     "7 INS_$9F",
 
+    /* 0xA0 */
     "7 INS_$A0",
     "7 INS_$A1",
     "7 INS_$A2",
@@ -1129,90 +1156,95 @@
     "7 INS_$AE",
     "7 INS_$AF",
 
-    "8 PushB[0]",
-    "8 PushB[1]",
-    "8 PushB[2]",
-    "8 PushB[3]",
-    "8 PushB[4]",
-    "8 PushB[5]",
-    "8 PushB[6]",
-    "8 PushB[7]",
-    "8 PushW[0]",
-    "8 PushW[1]",
-    "8 PushW[2]",
-    "8 PushW[3]",
-    "8 PushW[4]",
-    "8 PushW[5]",
-    "8 PushW[6]",
-    "8 PushW[7]",
-
+    /* 0xB0 */
+    "8 PUSHB[0]",
+    "8 PUSHB[1]",
+    "8 PUSHB[2]",
+    "8 PUSHB[3]",
+    "8 PUSHB[4]",
+    "8 PUSHB[5]",
+    "8 PUSHB[6]",
+    "8 PUSHB[7]",
+    "8 PUSHW[0]",
+    "8 PUSHW[1]",
+    "8 PUSHW[2]",
+    "8 PUSHW[3]",
+    "8 PUSHW[4]",
+    "8 PUSHW[5]",
+    "8 PUSHW[6]",
+    "8 PUSHW[7]",
+
+    /* 0xC0 */
     "7 MDRP[G]",
     "7 MDRP[B]",
     "7 MDRP[W]",
-    "7 MDRP[?]",
+    "6 MDRP[]",
     "8 MDRP[rG]",
     "8 MDRP[rB]",
     "8 MDRP[rW]",
-    "8 MDRP[r?]",
+    "7 MDRP[r]",
     "8 MDRP[mG]",
     "8 MDRP[mB]",
     "8 MDRP[mW]",
-    "8 MDRP[m?]",
+    "7 MDRP[m]",
     "9 MDRP[mrG]",
     "9 MDRP[mrB]",
     "9 MDRP[mrW]",
-    "9 MDRP[mr?]",
+    "8 MDRP[mr]",
 
+    /* 0xD0 */
     "8 MDRP[pG]",
     "8 MDRP[pB]",
     "8 MDRP[pW]",
-    "8 MDRP[p?]",
+    "7 MDRP[p]",
     "9 MDRP[prG]",
     "9 MDRP[prB]",
     "9 MDRP[prW]",
-    "9 MDRP[pr?]",
+    "8 MDRP[pr]",
     "9 MDRP[pmG]",
     "9 MDRP[pmB]",
     "9 MDRP[pmW]",
-    "9 MDRP[pm?]",
+    "8 MDRP[pm]",
     "A MDRP[pmrG]",
     "A MDRP[pmrB]",
     "A MDRP[pmrW]",
-    "A MDRP[pmr?]",
+    "9 MDRP[pmr]",
 
+    /* 0xE0 */
     "7 MIRP[G]",
     "7 MIRP[B]",
     "7 MIRP[W]",
-    "7 MIRP[?]",
+    "6 MIRP[]",
     "8 MIRP[rG]",
     "8 MIRP[rB]",
     "8 MIRP[rW]",
-    "8 MIRP[r?]",
+    "7 MIRP[r]",
     "8 MIRP[mG]",
     "8 MIRP[mB]",
     "8 MIRP[mW]",
-    "8 MIRP[m?]",
+    "7 MIRP[m]",
     "9 MIRP[mrG]",
     "9 MIRP[mrB]",
     "9 MIRP[mrW]",
-    "9 MIRP[mr?]",
+    "8 MIRP[mr]",
 
+    /* 0xF0 */
     "8 MIRP[pG]",
     "8 MIRP[pB]",
     "8 MIRP[pW]",
-    "8 MIRP[p?]",
+    "7 MIRP[p]",
     "9 MIRP[prG]",
     "9 MIRP[prB]",
     "9 MIRP[prW]",
-    "9 MIRP[pr?]",
+    "8 MIRP[pr]",
     "9 MIRP[pmG]",
     "9 MIRP[pmB]",
     "9 MIRP[pmW]",
-    "9 MIRP[pm?]",
+    "8 MIRP[pm]",
     "A MIRP[pmrG]",
     "A MIRP[pmrB]",
     "A MIRP[pmrW]",
-    "A MIRP[pmr?]"
+    "9 MIRP[pmr]"
   };
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
@@ -1662,6 +1694,32 @@
   }
 
 
+  /*
+   *
+   * Apple's TrueType specification at
+   *
+   *   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM02/Chap2.html#order
+   *
+   * gives the following order of operations in instructions that move
+   * points.
+   *
+   *   - check single width cut-in (MIRP, MDRP)
+   *
+   *   - check control value cut-in (MIRP, MIAP)
+   *
+   *   - apply engine compensation (MIRP, MDRP)
+   *
+   *   - round distance (MIRP, MDRP) or value (MIAP, MDAP)
+   *
+   *   - check minimum distance (MIRP,MDRP)
+   *
+   *   - move point (MIRP, MDRP, MIAP, MSIRP, MDAP)
+   *
+   * For rounding instructions, engine compensation happens before rounding.
+   *
+   */
+
+
   /**************************************************************************
    *
    * @Function:
@@ -1886,7 +1944,6 @@
     zone->org[point].y = ADD_LONG( zone->org[point].y, distance );
   }
 
-
   /**************************************************************************
    *
    * @Function:
@@ -1904,12 +1961,6 @@
    *
    * @Return:
    *   The compensated distance.
-   *
-   * @Note:
-   *   The TrueType specification says very few about the relationship
-   *   between rounding and engine compensation.  However, it seems from
-   *   the description of super round that we should add the compensation
-   *   before rounding.
    */
   static FT_F26Dot6
   Round_None( TT_ExecContext  exc,
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index f3a432cedd6fae73943449de724ecd0954eeb5c6..e4775a51ed3afe71ca51e7397ca2fa2c03576274 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -148,7 +148,7 @@
   /* This list shall be expanded as we find more of them.       */
 
   static FT_Bool
-  tt_check_trickyness_family( FT_String*  name )
+  tt_check_trickyness_family( const FT_String*  name )
   {
 
 #define TRICK_NAMES_MAX_CHARACTERS  19
@@ -937,7 +937,22 @@
     TT_Face         face = (TT_Face)size->root.face;
     TT_ExecContext  exec;
     FT_Error        error;
+    FT_UInt         i;
 
+    /* unscaled CVT values are already stored in 26.6 format */
+    FT_Fixed  scale = size->ttmetrics.scale >> 6;
+
+
+    /* Scale the cvt values to the new ppem.            */
+    /* By default, we use the y ppem value for scaling. */
+    FT_TRACE6(( "CVT values:\n" ));
+    for ( i = 0; i < size->cvt_size; i++ )
+    {
+      size->cvt[i] = FT_MulFix( face->cvt[i], scale );
+      FT_TRACE6(( "  %3d: %f (%f)\n",
+                  i, face->cvt[i] / 64.0, size->cvt[i] / 64.0 ));
+    }
+    FT_TRACE6(( "\n" ));
 
     exec = size->context;
 
@@ -1094,11 +1109,17 @@
       tt_metrics->rotated   = FALSE;
       tt_metrics->stretched = FALSE;
 
-      /* set default engine compensation */
-      tt_metrics->compensations[0] = 0;   /* gray     */
-      tt_metrics->compensations[1] = 0;   /* black    */
-      tt_metrics->compensations[2] = 0;   /* white    */
-      tt_metrics->compensations[3] = 0;   /* reserved */
+      /* Set default engine compensation.  Value 3 is not described */
+      /* in the OpenType specification (as of Mai 2019), but Greg   */
+      /* says that MS handles it the same as `gray'.                */
+      /*                                                            */
+      /* The Apple specification says that the compensation for     */
+      /* `gray' is always zero.  FreeType doesn't do any            */
+      /* compensation at all.                                       */
+      tt_metrics->compensations[0] = 0;   /* gray             */
+      tt_metrics->compensations[1] = 0;   /* black            */
+      tt_metrics->compensations[2] = 0;   /* white            */
+      tt_metrics->compensations[3] = 0;   /* the same as gray */
     }
 
     /* allocate function defs, instruction defs, cvt, and storage area */
@@ -1171,20 +1192,8 @@
     if ( size->cvt_ready < 0 )
     {
       FT_UInt  i;
-      TT_Face  face = (TT_Face)size->root.face;
 
 
-      /* Scale the cvt values to the new ppem.            */
-      /* By default, we use the y ppem value for scaling. */
-      FT_TRACE6(( "CVT values:\n" ));
-      for ( i = 0; i < size->cvt_size; i++ )
-      {
-        size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
-        FT_TRACE6(( "  %3d: %d (%f)\n",
-                    i, face->cvt[i], size->cvt[i] / 64.0 ));
-      }
-      FT_TRACE6(( "\n" ));
-
       /* all twilight points are originally zero */
       for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
       {
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index e7718bf9b794c66e12256ec9abfe9d43c64dd2cf..bc954c2dba8426d2fc5121d0745dda0b10745955 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -352,12 +352,12 @@
       goto Exit;
 
     {
-      FT_Short*  cur   = face->cvt;
-      FT_Short*  limit = cur + face->cvt_size;
+      FT_Int32*  cur   = face->cvt;
+      FT_Int32*  limit = cur + face->cvt_size;
 
 
       for ( ; cur < limit; cur++ )
-        *cur = FT_GET_SHORT();
+        *cur = FT_GET_SHORT() * 64;
     }
 
     FT_FRAME_EXIT();
diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c
index 8625db5b0159ffb8b1223133899cf741fd5517d3..557733da3b11c48841863a9ca614e433d37b0a80 100644
--- a/src/type1/t1driver.c
+++ b/src/type1/t1driver.c
@@ -70,8 +70,8 @@
 
 
   static FT_UInt
-  t1_get_name_index( T1_Face     face,
-                     FT_String*  glyph_name )
+  t1_get_name_index( T1_Face           face,
+                     const FT_String*  glyph_name )
   {
     FT_Int  i;
 
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index 3896af70ba1e979e10458807d31ad706b19fb9df..5cffdfaac471cd647ea61d30d1a4f41f020f4248 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -1507,12 +1507,7 @@
 
       /* We need to `zero' out encoding_table.elements */
       for ( n = 0; n < array_size; n++ )
-      {
-        char*  notdef = (char *)".notdef";
-
-
-        (void)T1_Add_Table( char_table, n, notdef, 8 );
-      }
+        (void)T1_Add_Table( char_table, n, ".notdef", 8 );
 
       /* Now we need to read records of the form                */
       /*                                                        */
@@ -2147,7 +2142,6 @@
 
       /* 0 333 hsbw endchar */
       FT_Byte  notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E };
-      char*    notdef_name    = (char *)".notdef";
 
 
       error = T1_Add_Table( swap_table, 0,
@@ -2162,7 +2156,7 @@
       if ( error )
         goto Fail;
 
-      error = T1_Add_Table( name_table, 0, notdef_name, 8 );
+      error = T1_Add_Table( name_table, 0, ".notdef", 8 );
       if ( error )
         goto Fail;
 
@@ -2633,8 +2627,7 @@
     /* we must now build type1.encoding when we have a custom array */
     if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
     {
-      FT_Int    charcode, idx, min_char, max_char;
-      FT_Byte*  glyph_name;
+      FT_Int  charcode, idx, min_char, max_char;
 
 
       /* OK, we do the following: for each element in the encoding  */
@@ -2648,27 +2641,27 @@
       charcode = 0;
       for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
       {
-        FT_Byte*  char_name;
+        const FT_String*  char_name =
+              (const FT_String*)loader.encoding_table.elements[charcode];
 
 
         type1->encoding.char_index[charcode] = 0;
-        type1->encoding.char_name [charcode] = (char *)".notdef";
+        type1->encoding.char_name [charcode] = ".notdef";
 
-        char_name = loader.encoding_table.elements[charcode];
         if ( char_name )
           for ( idx = 0; idx < type1->num_glyphs; idx++ )
           {
-            glyph_name = (FT_Byte*)type1->glyph_names[idx];
-            if ( ft_strcmp( (const char*)char_name,
-                            (const char*)glyph_name ) == 0 )
+            const FT_String*  glyph_name = type1->glyph_names[idx];
+
+
+            if ( ft_strcmp( char_name, glyph_name ) == 0 )
             {
               type1->encoding.char_index[charcode] = (FT_UShort)idx;
-              type1->encoding.char_name [charcode] = (char*)glyph_name;
+              type1->encoding.char_name [charcode] = glyph_name;
 
               /* Change min/max encoded char only if glyph name is */
               /* not /.notdef                                      */
-              if ( ft_strcmp( (const char*)".notdef",
-                              (const char*)glyph_name ) != 0 )
+              if ( ft_strcmp( ".notdef", glyph_name ) != 0 )
               {
                 if ( charcode < min_char )
                   min_char = charcode;
diff --git a/src/type42/t42drivr.c b/src/type42/t42drivr.c
index 6d4e7a09554ceb1bb78f8bd5ed86598a245d5597..09ad632e978c2995c903be11048a3e8fecd46cee 100644
--- a/src/type42/t42drivr.c
+++ b/src/type42/t42drivr.c
@@ -69,8 +69,8 @@
 
 
   static FT_UInt
-  t42_get_name_index( T42_Face    face,
-                      FT_String*  glyph_name )
+  t42_get_name_index( T42_Face          face,
+                      const FT_String*  glyph_name )
   {
     FT_Int  i;
 
diff --git a/src/type42/t42objs.c b/src/type42/t42objs.c
index 234c0a3e9756b0ee291833c892d58ef7082f264a..d31bace4512157b2f701ca6bd09bea934d118527 100644
--- a/src/type42/t42objs.c
+++ b/src/type42/t42objs.c
@@ -98,8 +98,7 @@
     /* we must now build type1.encoding when we have a custom array */
     if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
     {
-      FT_Int    charcode, idx, min_char, max_char;
-      FT_Byte*  glyph_name;
+      FT_Int  charcode, idx, min_char, max_char;
 
 
       /* OK, we do the following: for each element in the encoding   */
@@ -114,27 +113,27 @@
       charcode = 0;
       for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
       {
-        FT_Byte*  char_name;
+        const FT_String*  char_name =
+              (const FT_String*)loader.encoding_table.elements[charcode];
 
 
         type1->encoding.char_index[charcode] = 0;
-        type1->encoding.char_name [charcode] = (char *)".notdef";
+        type1->encoding.char_name [charcode] = ".notdef";
 
-        char_name = loader.encoding_table.elements[charcode];
         if ( char_name )
           for ( idx = 0; idx < type1->num_glyphs; idx++ )
           {
-            glyph_name = (FT_Byte*)type1->glyph_names[idx];
-            if ( ft_strcmp( (const char*)char_name,
-                            (const char*)glyph_name ) == 0 )
+            const FT_String*  glyph_name = type1->glyph_names[idx];
+
+
+            if ( ft_strcmp( char_name, glyph_name ) == 0 )
             {
               type1->encoding.char_index[charcode] = (FT_UShort)idx;
-              type1->encoding.char_name [charcode] = (char*)glyph_name;
+              type1->encoding.char_name [charcode] = glyph_name;
 
               /* Change min/max encoded char only if glyph name is */
               /* not /.notdef                                      */
-              if ( ft_strcmp( (const char*)".notdef",
-                              (const char*)glyph_name ) != 0 )
+              if ( ft_strcmp( ".notdef", glyph_name ) != 0 )
               {
                 if ( charcode < min_char )
                   min_char = charcode;
diff --git a/src/type42/t42parse.c b/src/type42/t42parse.c
index b653a133a550f619f21a958ef9dcef0b75fceefd..c47a77786dea3a4d4d7ff70361418d9182b55071 100644
--- a/src/type42/t42parse.c
+++ b/src/type42/t42parse.c
@@ -226,7 +226,8 @@
     if ( !parser->in_memory )
       FT_FREE( parser->base_dict );
 
-    parser->root.funcs.done( &parser->root );
+    if ( parser->root.funcs.done )
+      parser->root.funcs.done( &parser->root );
   }
 
 
@@ -373,12 +374,7 @@
 
       /* We need to `zero' out encoding_table.elements */
       for ( n = 0; n < count; n++ )
-      {
-        char*  notdef = (char *)".notdef";
-
-
-        (void)T1_Add_Table( char_table, n, notdef, 8 );
-      }
+        (void)T1_Add_Table( char_table, n, ".notdef", 8 );
 
       /* Now we need to read records of the form                */
       /*                                                        */
@@ -1021,8 +1017,7 @@
     }
 
     /* if /.notdef does not occupy index 0, do our magic. */
-    if ( ft_strcmp( (const char*)".notdef",
-                    (const char*)name_table->elements[0] ) )
+    if ( ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) )
     {
       /* Swap glyph in index 0 with /.notdef glyph.  First, add index 0  */
       /* name and code entries to swap_table.  Then place notdef_index   */