Update FreeType to e432ebf2 (2.7.1 + patches)

A major new feature since 2.7 is Opentype 1.8 (variable font) and
1.8.1 (CFF2 - variable font) support.

BUG: 34742506
Test: build freetype and install on a device.
Change-Id: I480fbd09bfa0ad25fe38a22ee0f584059587dc72
diff --git a/README.android b/README.android
index b634371..3f599a0 100644
--- a/README.android
+++ b/README.android
@@ -19,17 +19,3 @@
 The following option is enabled to support color fonts.
 
   FT_CONFIG_OPTION_USE_PNG
-
-The following commits are cherry-picked from the upstream repository.
-
-  1c6fd994376c182f07cd59558a2f9bdd082b9509
-  Author: Werner Lemberg <wl@gnu.org>
-  [sfnt] Improve FT_LOAD_BITMAP_METRICS_ONLY for `sbix' format.
-
-  565db95b5cc87f8875576afb4282f443a5a10a8e
-  Author: Werner Lemberg <wl@gnu.org>
-  [sfnt] Speed up `sbix' lookup.
-
-  37e193e9357bdccbfb8a4437ddfdc06efd9e140c
-  Author: Werner Lemberg <wl@gnu.org>
-  Introduce a way of quickly retrieving (embedded) bitmap metrics.
diff --git a/README.version b/README.version
index 6d57025..34d1641 100644
--- a/README.version
+++ b/README.version
@@ -1,3 +1,3 @@
-URL: http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=c38be52b
-Version: c38be52bf8de3b1699d74932b849bf150265819e (2.7 + update)
+URL: http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=e432ebf
+Version: e432ebf2e2c96e75f674af41f062d8b210de8491
 BugComponent: 75970
diff --git a/include/freetype/config/ftconfig.h b/include/freetype/config/ftconfig.h
index 157a704..9d7f883 100644
--- a/include/freetype/config/ftconfig.h
+++ b/include/freetype/config/ftconfig.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    ANSI-specific configuration file (specification only).               */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -143,6 +143,14 @@
 #endif
 
 
+  /* Fix compiler warning with sgi compiler */
+#if defined( __sgi ) && !defined( __GNUC__ )
+#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
+#pragma set woff 3505
+#endif
+#endif
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Section>                                                             */
@@ -338,10 +346,11 @@
 
 
   /* typeof condition taken from gnulib's `intprops.h' header file */
-#if ( __GNUC__ >= 2                         || \
-      defined( __IBM__TYPEOF__ )            || \
-      ( __SUNPRO_C >= 0x5110 && !__STDC__ ) )
-#define FT_TYPEOF( type )  (__typeof__ (type))
+#if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 )                       || \
+      ( defined( __IBMC__ ) && __IBMC__ >= 1210 &&                      \
+        defined( __IBM__TYPEOF__ ) )                                 || \
+      ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) )
+#define FT_TYPEOF( type )  ( __typeof__ ( type ) )
 #else
 #define FT_TYPEOF( type )  /* empty */
 #endif
diff --git a/include/freetype/config/ftheader.h b/include/freetype/config/ftheader.h
index 68e1483..d491af5 100644
--- a/include/freetype/config/ftheader.h
+++ b/include/freetype/config/ftheader.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Build macros of the FreeType 2 library.                              */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -357,6 +357,19 @@
   /*************************************************************************
    *
    * @macro:
+   *   FT_PCF_DRIVER_H
+   *
+   * @description:
+   *   A macro used in #include statements to name the file containing
+   *   structures and macros related to the PCF driver module.
+   *
+   */
+#define FT_PCF_DRIVER_H  <freetype/ftpcfdrv.h>
+
+
+  /*************************************************************************
+   *
+   * @macro:
    *   FT_TYPE1_TABLES_H
    *
    * @description:
diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h
index 94ccf7f..5bd638b 100644
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    User-selectable configuration macros (specification only).           */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -82,8 +82,8 @@
   /* to control the various font drivers and modules.  The controllable    */
   /* properties are listed in the section `Controlling FreeType Modules'   */
   /* in the reference's table of contents; currently there are properties  */
-  /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'), and  */
-  /* TrueType (file `ftttdrv.h').                                          */
+  /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'),      */
+  /* TrueType (file `ftttdrv.h'), and PCF (file `ftpcfdrv.h').             */
   /*                                                                       */
   /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */
   /* multiple lines for better readability).                               */
@@ -102,7 +102,7 @@
   /*                       cff:no-stem-darkening=1 \                       */
   /*                       autofitter:warping=1                            */
   /*                                                                       */
-/* #define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES */
+  /* #define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES                       */
 
 
   /*************************************************************************/
@@ -400,7 +400,7 @@
   /* supply font data incrementally as the document is parsed, such        */
   /* as the Ghostscript interpreter for the PostScript language.           */
   /*                                                                       */
-/* #define FT_CONFIG_OPTION_INCREMENTAL */
+  /* #define FT_CONFIG_OPTION_INCREMENTAL                                  */
 
 
   /*************************************************************************/
@@ -640,17 +640,21 @@
   /* [1] for a technical overview on what this means.  See `ttinterp.h'    */
   /* for more details on the LEAN option.                                  */
   /*                                                                       */
-  /* There are three options.                                              */
+  /* There are three possible values.                                      */
   /*                                                                       */
-  /* 1. This option is associated with the `Infinality' moniker.           */
-  /*    Contributed by an individual nicknamed Infinality with the goal of */
+  /* Value 1:                                                              */
+  /*    This value is associated with the `Infinality' moniker,            */
+  /*    contributed by an individual nicknamed Infinality with the goal of */
   /*    making TrueType fonts render better than on Windows.  A high       */
   /*    amount of configurability and flexibility, down to rules for       */
   /*    single glyphs in fonts, but also very slow.  Its experimental and  */
   /*    slow nature and the original developer losing interest meant that  */
   /*    this option was never enabled in default builds.                   */
   /*                                                                       */
-  /* 2. The new default mode for the TrueType driver.  The Infinality code */
+  /*    The corresponding interpreter version is v38.                      */
+  /*                                                                       */
+  /* Value 2:                                                              */
+  /*    The new default mode for the TrueType driver.  The Infinality code */
   /*    base was stripped to the bare minimum and all configurability      */
   /*    removed in the name of speed and simplicity.  The configurability  */
   /*    was mainly aimed at legacy fonts like Arial, Times New Roman, or   */
@@ -660,14 +664,19 @@
   /*    that modern and web fonts render well while legacy fonts render    */
   /*    okay.                                                              */
   /*                                                                       */
-  /* 3. Compile both.                                                      */
+  /*    The corresponding interpreter version is v40.                      */
+  /*                                                                       */
+  /* Value 3:                                                              */
+  /*    Compile both, making both v38 and v40 available (the latter is the */
+  /*    default).                                                          */
   /*                                                                       */
   /* By undefining these, you get rendering behavior like on Windows       */
   /* without ClearType, i.e., Windows XP without ClearType enabled and     */
   /* Win9x (interpreter version v35).  Or not, depending on how much       */
   /* hinting blood and testing tears the font designer put into a given    */
   /* font.  If you define one or both subpixel hinting options, you can    */
-  /* switch between between v35 and the ones you define.                   */
+  /* switch between between v35 and the ones you define (using             */
+  /* `FT_Property_Set').                                                   */
   /*                                                                       */
   /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be      */
   /* defined.                                                              */
@@ -835,6 +844,33 @@
   /*************************************************************************/
   /*************************************************************************/
   /****                                                                 ****/
+  /****         P C F   D R I V E R    C O N F I G U R A T I O N        ****/
+  /****                                                                 ****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* There are many PCF fonts just called `Fixed' which look completely    */
+  /* different, and which have nothing to do with each other.  When        */
+  /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */
+  /* random, the style changes often if one changes the size and one       */
+  /* cannot select some fonts at all.  This option makes the PCF module    */
+  /* prepend the foundry name (plus a space) to the family name.           */
+  /*                                                                       */
+  /* We also check whether we have `wide' characters; all put together, we */
+  /* get family names like `Sony Fixed' or `Misc Fixed Wide'.              */
+  /*                                                                       */
+  /* If this option is activated, it can be controlled with the            */
+  /* `no-long-family-names' property of the pcf driver module.             */
+  /*                                                                       */
+/* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /****                                                                 ****/
   /****    A U T O F I T   M O D U L E    C O N F I G U R A T I O N     ****/
   /****                                                                 ****/
   /*************************************************************************/
diff --git a/include/freetype/config/ftstdlib.h b/include/freetype/config/ftstdlib.h
index 6eefa9f..05a4845 100644
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -5,7 +5,7 @@
 /*    ANSI-specific library and header configuration file (specification   */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index b19188e..568a588 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType high-level API and common types (specification only).       */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -265,8 +265,8 @@
   /*    FT_Glyph_Metrics                                                   */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model the metrics of a single glyph.  The      */
-  /*    values are expressed in 26.6 fractional pixel format; if the flag  */
+  /*    A structure to model the metrics of a single glyph.  The values    */
+  /*    are expressed in 26.6 fractional pixel format; if the flag         */
   /*    @FT_LOAD_NO_SCALE has been used while loading the glyph, values    */
   /*    are expressed in font units instead.                               */
   /*                                                                       */
@@ -305,6 +305,11 @@
   /*    `horiAdvance' or `vertAdvance'; you have to manually adjust these  */
   /*    values to account for the added width and height.                  */
   /*                                                                       */
+  /*    FreeType doesn't use the `VORG' table data for CFF fonts because   */
+  /*    it doesn't have an interface to quickly retrieve the glyph height. */
+  /*    The y~coordinate of the vertical origin can be simply computed as  */
+  /*    `vertBearingY + height' after loading a glyph.                     */
+  /*                                                                       */
   typedef struct  FT_Glyph_Metrics_
   {
     FT_Pos  width;
@@ -349,10 +354,10 @@
   /*                                                                       */
   /* <Note>                                                                */
   /*    Windows FNT:                                                       */
-  /*      The nominal size given in a FNT font is not reliable.  Thus when */
-  /*      the driver finds it incorrect, it sets `size' to some calculated */
-  /*      values and sets `x_ppem' and `y_ppem' to the pixel width and     */
-  /*      height given in the font, respectively.                          */
+  /*      The nominal size given in a FNT font is not reliable.  If the    */
+  /*      driver finds it incorrect, it sets `size' to some calculated     */
+  /*      values, and `x_ppem' and `y_ppem' to the pixel width and height  */
+  /*      given in the font, respectively.                                 */
   /*                                                                       */
   /*    TrueType embedded bitmaps:                                         */
   /*      `size', `width', and `height' values are not contained in the    */
@@ -421,9 +426,9 @@
   /*    FT_Module                                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A handle to a given FreeType module object.  Each module can be a  */
+  /*    A handle to a given FreeType module object.  A module can be a     */
   /*    font driver, a renderer, or anything else that provides services   */
-  /*    to the formers.                                                    */
+  /*    to the former.                                                     */
   /*                                                                       */
   typedef struct FT_ModuleRec_*  FT_Module;
 
@@ -434,8 +439,8 @@
   /*    FT_Driver                                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A handle to a given FreeType font driver object.  Each font driver */
-  /*    is a special module capable of creating faces from font files.     */
+  /*    A handle to a given FreeType font driver object.  A font driver    */
+  /*    is a module capable of creating faces from font files.             */
   /*                                                                       */
   typedef struct FT_DriverRec_*  FT_Driver;
 
@@ -446,10 +451,10 @@
   /*    FT_Renderer                                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A handle to a given FreeType renderer.  A renderer is a special    */
-  /*    module in charge of converting a glyph image to a bitmap, when     */
-  /*    necessary.  Each renderer supports a given glyph image format, and */
-  /*    one or more target surface depths.                                 */
+  /*    A handle to a given FreeType renderer.  A renderer is a module in  */
+  /*    charge of converting a glyph's outline image to a bitmap.  It      */
+  /*    supports a single glyph image format, and one or more target       */
+  /*    surface depths.                                                    */
   /*                                                                       */
   typedef struct FT_RendererRec_*  FT_Renderer;
 
@@ -467,15 +472,15 @@
   /*    FT_Face                                                            */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A handle to a given typographic face object.  A face object models */
-  /*    a given typeface, in a given style.                                */
+  /*    A handle to a typographic face object.  A face object models a     */
+  /*    given typeface, in a given style.                                  */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    Each face object also owns a single @FT_GlyphSlot object, as well  */
+  /*    A face object also owns a single @FT_GlyphSlot object, as well     */
   /*    as one or more @FT_Size objects.                                   */
   /*                                                                       */
   /*    Use @FT_New_Face or @FT_Open_Face to create a new face object from */
-  /*    a given filepathname or a custom input stream.                     */
+  /*    a given filepath or a custom input stream.                         */
   /*                                                                       */
   /*    Use @FT_Done_Face to destroy it (along with its slot and sizes).   */
   /*                                                                       */
@@ -500,11 +505,11 @@
   /*    FT_Size                                                            */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A handle to an object used to model a face scaled to a given       */
+  /*    A handle to an object that models a face scaled to a given         */
   /*    character size.                                                    */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    Each @FT_Face has an _active_ @FT_Size object that is used by      */
+  /*    An @FT_Face has one _active_ @FT_Size object that is used by       */
   /*    functions like @FT_Load_Glyph to determine the scaling             */
   /*    transformation that in turn is used to load and hint glyphs and    */
   /*    metrics.                                                           */
@@ -531,9 +536,8 @@
   /*    FT_GlyphSlot                                                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A handle to a given `glyph slot'.  A slot is a container where it  */
-  /*    is possible to load any of the glyphs contained in its parent      */
-  /*    face.                                                              */
+  /*    A handle to a given `glyph slot'.  A slot is a container that can  */
+  /*    hold any of the glyphs contained in its parent face.               */
   /*                                                                       */
   /*    In other words, each time you call @FT_Load_Glyph or               */
   /*    @FT_Load_Char, the slot's content is erased by the new glyph data, */
@@ -552,13 +556,14 @@
   /*    FT_CharMap                                                         */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A handle to a given character map.  A charmap is used to translate */
-  /*    character codes in a given encoding into glyph indexes for its     */
-  /*    parent's face.  Some font formats may provide several charmaps per */
-  /*    font.                                                              */
+  /*    A handle to a character map (usually abbreviated to `charmap').  A */
+  /*    charmap is used to translate character codes in a given encoding   */
+  /*    into glyph indexes for its parent's face.  Some font formats may   */
+  /*    provide several charmaps per font.                                 */
   /*                                                                       */
   /*    Each face object owns zero or more charmaps, but only one of them  */
-  /*    can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char.   */
+  /*    can be `active', providing the data used by @FT_Get_Char_Index or  */
+  /*    @FT_Load_Char.                                                     */
   /*                                                                       */
   /*    The list of available charmaps in a face is available through the  */
   /*    `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec.   */
@@ -615,8 +620,8 @@
   /*    FT_Encoding                                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    An enumeration used to specify character sets supported by         */
-  /*    charmaps.  Used in the @FT_Select_Charmap API function.            */
+  /*    An enumeration to specify character sets supported by charmaps.    */
+  /*    Used in the @FT_Select_Charmap API function.                       */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Despite the name, this enumeration lists specific character        */
@@ -630,18 +635,17 @@
   /*      The encoding value~0 is reserved.                                */
   /*                                                                       */
   /*    FT_ENCODING_UNICODE ::                                             */
-  /*      Corresponds to the Unicode character set.  This value covers     */
-  /*      all versions of the Unicode repertoire, including ASCII and      */
-  /*      Latin-1.  Most fonts include a Unicode charmap, but not all      */
-  /*      of them.                                                         */
+  /*      The Unicode character set.  This value covers all versions of    */
+  /*      the Unicode repertoire, including ASCII and Latin-1.  Most fonts */
+  /*      include a Unicode charmap, but not all of them.                  */
   /*                                                                       */
   /*      For example, if you want to access Unicode value U+1F028 (and    */
   /*      the font contains it), use value 0x1F028 as the input value for  */
   /*      @FT_Get_Char_Index.                                              */
   /*                                                                       */
   /*    FT_ENCODING_MS_SYMBOL ::                                           */
-  /*      Corresponds to the Microsoft Symbol encoding, used to encode     */
-  /*      mathematical symbols and wingdings.  For more information, see   */
+  /*      Microsoft Symbol encoding, used to encode mathematical symbols   */
+  /*      and wingdings.  For more information, see                        */
   /*      `http://www.microsoft.com/typography/otspec/recom.htm',          */
   /*      `http://www.kostis.net/charsets/symbol.htm', and                 */
   /*      `http://www.kostis.net/charsets/wingding.htm'.                   */
@@ -650,22 +654,24 @@
   /*      Area) in the range U+F020-U+F0FF.                                */
   /*                                                                       */
   /*    FT_ENCODING_SJIS ::                                                */
-  /*      Corresponds to Japanese SJIS encoding.  More info at             */
-  /*      `http://en.wikipedia.org/wiki/Shift_JIS'.                        */
-  /*      See note on multi-byte encodings below.                          */
+  /*      Shift JIS encoding for Japanese.  More info at                   */
+  /*      `http://en.wikipedia.org/wiki/Shift_JIS'.  See note on           */
+  /*      multi-byte encodings below.                                      */
   /*                                                                       */
-  /*    FT_ENCODING_GB2312 ::                                              */
-  /*      Corresponds to an encoding system for Simplified Chinese as      */
-  /*      used in mainland China.                                          */
+  /*    FT_ENCODING_PRC ::                                                 */
+  /*      Corresponds to encoding systems mainly for Simplified Chinese as */
+  /*      used in People's Republic of China (PRC).  The encoding layout   */
+  /*      is based on GB~2312 and its supersets GBK and GB~18030.          */
   /*                                                                       */
   /*    FT_ENCODING_BIG5 ::                                                */
   /*      Corresponds to an encoding system for Traditional Chinese as     */
   /*      used in Taiwan and Hong Kong.                                    */
   /*                                                                       */
   /*    FT_ENCODING_WANSUNG ::                                             */
-  /*      Corresponds to the Korean encoding system known as Wansung.      */
+  /*      Corresponds to the Korean encoding system known as Extended      */
+  /*      Wansung (MS Windows code page 949).                              */
   /*      For more information see                                         */
-  /*      `https://msdn.microsoft.com/en-US/goglobal/cc305154'.            */
+  /*      `http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit949.txt'. */
   /*                                                                       */
   /*    FT_ENCODING_JOHAB ::                                               */
   /*      The Korean standard character set (KS~C 5601-1992), which        */
@@ -677,33 +683,31 @@
   /*      PostScript font.  It is limited to 256 character codes.          */
   /*                                                                       */
   /*    FT_ENCODING_ADOBE_STANDARD ::                                      */
-  /*      Corresponds to the Adobe Standard encoding, as found in Type~1,  */
-  /*      CFF, and OpenType/CFF fonts.  It is limited to 256 character     */
-  /*      codes.                                                           */
+  /*      Adobe Standard encoding, as found in Type~1, CFF, and            */
+  /*      OpenType/CFF fonts.  It is limited to 256 character codes.       */
   /*                                                                       */
   /*    FT_ENCODING_ADOBE_EXPERT ::                                        */
-  /*      Corresponds to the Adobe Expert encoding, as found in Type~1,    */
-  /*      CFF, and OpenType/CFF fonts.  It is limited to 256 character     */
-  /*      codes.                                                           */
+  /*      Adobe Expert encoding, as found in Type~1, CFF, and OpenType/CFF */
+  /*      fonts.  It is limited to 256 character codes.                    */
   /*                                                                       */
   /*    FT_ENCODING_ADOBE_CUSTOM ::                                        */
   /*      Corresponds to a custom encoding, as found in Type~1, CFF, and   */
   /*      OpenType/CFF fonts.  It is limited to 256 character codes.       */
   /*                                                                       */
   /*    FT_ENCODING_APPLE_ROMAN ::                                         */
-  /*      Corresponds to the 8-bit Apple roman encoding.  Many TrueType    */
-  /*      and OpenType fonts contain a charmap for this encoding, since    */
-  /*      older versions of Mac OS are able to use it.                     */
+  /*      Apple roman encoding.  Many TrueType and OpenType fonts contain  */
+  /*      a charmap for this 8-bit encoding, since older versions of Mac   */
+  /*      OS are able to use it.                                           */
   /*                                                                       */
   /*    FT_ENCODING_OLD_LATIN_2 ::                                         */
-  /*      This value is deprecated and was never used nor reported by      */
+  /*      This value is deprecated and was neither used nor reported by    */
   /*      FreeType.  Don't use or test for it.                             */
   /*                                                                       */
   /*    FT_ENCODING_MS_SJIS ::                                             */
   /*      Same as FT_ENCODING_SJIS.  Deprecated.                           */
   /*                                                                       */
   /*    FT_ENCODING_MS_GB2312 ::                                           */
-  /*      Same as FT_ENCODING_GB2312.  Deprecated.                         */
+  /*      Same as FT_ENCODING_PRC.  Deprecated.                            */
   /*                                                                       */
   /*    FT_ENCODING_MS_BIG5 ::                                             */
   /*      Same as FT_ENCODING_BIG5.  Deprecated.                           */
@@ -716,7 +720,7 @@
   /*                                                                       */
   /* <Note>                                                                */
   /*    By default, FreeType automatically synthesizes a Unicode charmap   */
-  /*    for PostScript fonts, using their glyph names dictionaries.        */
+  /*    for PostScript fonts, using their glyph name dictionaries.         */
   /*    However, it also reports the encodings defined explicitly in the   */
   /*    font file, for the cases when they are needed, with the Adobe      */
   /*    values as well.                                                    */
@@ -736,7 +740,7 @@
   /*    Russian).                                                          */
   /*                                                                       */
   /*    FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */
-  /*    and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to  */
+  /*    and `encoding_id' is not `TT_MAC_ID_ROMAN' (otherwise it is set to */
   /*    FT_ENCODING_APPLE_ROMAN).                                          */
   /*                                                                       */
   /*    If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function       */
@@ -748,9 +752,9 @@
   /*    to get an idea how to do that.  Basically, if the language ID      */
   /*    is~0, don't use it, otherwise subtract 1 from the language ID.     */
   /*    Then examine `encoding_id'.  If, for example, `encoding_id' is     */
-  /*    @TT_MAC_ID_ROMAN and the language ID (minus~1) is                  */
+  /*    `TT_MAC_ID_ROMAN' and the language ID (minus~1) is                 */
   /*    `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman.        */
-  /*    @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi       */
+  /*    `TT_MAC_ID_ARABIC' with `TT_MAC_LANGID_FARSI' means the Farsi      */
   /*    variant the Arabic encoding.                                       */
   /*                                                                       */
   typedef enum  FT_Encoding_
@@ -761,14 +765,15 @@
     FT_ENC_TAG( FT_ENCODING_UNICODE,   'u', 'n', 'i', 'c' ),
 
     FT_ENC_TAG( FT_ENCODING_SJIS,    's', 'j', 'i', 's' ),
-    FT_ENC_TAG( FT_ENCODING_GB2312,  'g', 'b', ' ', ' ' ),
+    FT_ENC_TAG( FT_ENCODING_PRC,     'g', 'b', ' ', ' ' ),
     FT_ENC_TAG( FT_ENCODING_BIG5,    'b', 'i', 'g', '5' ),
     FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ),
     FT_ENC_TAG( FT_ENCODING_JOHAB,   'j', 'o', 'h', 'a' ),
 
     /* for backwards compatibility */
+    FT_ENCODING_GB2312     = FT_ENCODING_PRC,
     FT_ENCODING_MS_SJIS    = FT_ENCODING_SJIS,
-    FT_ENCODING_MS_GB2312  = FT_ENCODING_GB2312,
+    FT_ENCODING_MS_GB2312  = FT_ENCODING_PRC,
     FT_ENCODING_MS_BIG5    = FT_ENCODING_BIG5,
     FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG,
     FT_ENCODING_MS_JOHAB   = FT_ENCODING_JOHAB,
@@ -793,7 +798,7 @@
 #define ft_encoding_latin_1         FT_ENCODING_ADOBE_LATIN_1
 #define ft_encoding_latin_2         FT_ENCODING_OLD_LATIN_2
 #define ft_encoding_sjis            FT_ENCODING_SJIS
-#define ft_encoding_gb2312          FT_ENCODING_GB2312
+#define ft_encoding_gb2312          FT_ENCODING_PRC
 #define ft_encoding_big5            FT_ENCODING_BIG5
 #define ft_encoding_wansung         FT_ENCODING_WANSUNG
 #define ft_encoding_johab           FT_ENCODING_JOHAB
@@ -820,11 +825,11 @@
   /*                                                                       */
   /*    platform_id :: An ID number describing the platform for the        */
   /*                   following encoding ID.  This comes directly from    */
-  /*                   the TrueType specification and should be emulated   */
+  /*                   the TrueType specification gets emulated            */
   /*                   for other formats.                                  */
   /*                                                                       */
   /*    encoding_id :: A platform specific encoding number.  This also     */
-  /*                   comes from the TrueType specification and should be */
+  /*                   comes from the TrueType specification and gets      */
   /*                   emulated similarly.                                 */
   /*                                                                       */
   typedef struct  FT_CharMapRec_
@@ -852,8 +857,8 @@
   /*    FT_Face_Internal                                                   */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    An opaque handle to an `FT_Face_InternalRec' structure, used to    */
-  /*    model private data of a given @FT_Face object.                     */
+  /*    An opaque handle to an `FT_Face_InternalRec' structure that models */
+  /*    the private data of a given @FT_Face object.                       */
   /*                                                                       */
   /*    This structure might change between releases of FreeType~2 and is  */
   /*    not generally available to client applications.                    */
@@ -873,7 +878,7 @@
   /* <Fields>                                                              */
   /*    num_faces           :: The number of faces in the font file.  Some */
   /*                           font formats can have multiple faces in     */
-  /*                           a font file.                                */
+  /*                           a single font file.                         */
   /*                                                                       */
   /*    face_index          :: This field holds two different values.      */
   /*                           Bits 0-15 are the index of the face in the  */
@@ -881,14 +886,15 @@
   /*                           are set to~0 if there is only one face in   */
   /*                           the font file.                              */
   /*                                                                       */
-  /*                           Bits 16-30 are relevant to GX variation     */
-  /*                           fonts only, holding the named instance      */
-  /*                           index for the current face index (starting  */
-  /*                           with value~1; value~0 indicates font access */
-  /*                           without GX variation data).  For non-GX     */
-  /*                           fonts, bits 16-30 are ignored.  If we have  */
-  /*                           the third named instance of face~4, say,    */
-  /*                           `face_index' is set to 0x00030004.          */
+  /*                           Bits 16-30 are relevant to GX and OpenType  */
+  /*                           variation fonts only, holding the named     */
+  /*                           instance index for the current face index   */
+  /*                           (starting with value~1; value~0 indicates   */
+  /*                           font access without variation data).  For   */
+  /*                           non-variation fonts, bits 16-30 are         */
+  /*                           ignored.  If we have the third named        */
+  /*                           instance of face~4, say, `face_index' is    */
+  /*                           set to 0x00030004.                          */
   /*                                                                       */
   /*                           Bit 31 is always zero (this is,             */
   /*                           `face_index' is always a positive value).   */
@@ -902,17 +908,18 @@
   /*                           @FT_STYLE_FLAG_XXX for the details.  Bits   */
   /*                           16-30 hold the number of named instances    */
   /*                           available for the current face if we have a */
-  /*                           GX variation (sub)font.  Bit 31 is always   */
-  /*                           zero (this is, `style_flags' is always a    */
-  /*                           positive value).                            */
+  /*                           GX or OpenType variation (sub)font.  Bit 31 */
+  /*                           is always zero (this is, `style_flags' is   */
+  /*                           always a positive value).                   */
   /*                                                                       */
   /*    num_glyphs          :: The number of glyphs in the face.  If the   */
   /*                           face is scalable and has sbits (see         */
   /*                           `num_fixed_sizes'), it is set to the number */
   /*                           of outline glyphs.                          */
   /*                                                                       */
-  /*                           For CID-keyed fonts, this value gives the   */
-  /*                           highest CID used in the font.               */
+  /*                           For CID-keyed fonts (not in an SFNT         */
+  /*                           wrapper) this value gives the highest CID   */
+  /*                           used in the font.                           */
   /*                                                                       */
   /*    family_name         :: The face's family name.  This is an ASCII   */
   /*                           string, usually in English, that describes  */
@@ -990,8 +997,8 @@
   /*                           expressed in font units.  For font formats  */
   /*                           not having this information, it is set to   */
   /*                           `bbox.yMin'.  Note that this field is       */
-  /*                           usually negative.  Only relevant for        */
-  /*                           scalable formats.                           */
+  /*                           negative for values below the baseline.     */
+  /*                           Only relevant for scalable formats.         */
   /*                                                                       */
   /*    height              :: This value is the vertical distance         */
   /*                           between two consecutive baselines,          */
@@ -1034,6 +1041,12 @@
   /*    Fields may be changed after a call to @FT_Attach_File or           */
   /*    @FT_Attach_Stream.                                                 */
   /*                                                                       */
+  /*    For an OpenType variation font, the values of the following fields */
+  /*    can change after a call to @FT_Set_Var_Design_Coordinates (and     */
+  /*    friends) if the font contains an `MVAR' table: `ascender',         */
+  /*    `descender', `height', `underline_position', and                   */
+  /*    `underline_thickness'.                                             */
+  /*                                                                       */
   typedef struct  FT_FaceRec_
   {
     FT_Long           num_faces;
@@ -1105,49 +1118,51 @@
   /*                                                                       */
   /* <Values>                                                              */
   /*    FT_FACE_FLAG_SCALABLE ::                                           */
-  /*      Indicates that the face contains outline glyphs.  This doesn't   */
-  /*      prevent bitmap strikes, i.e., a face can have both this and      */
+  /*      The face contains outline glyphs.  Note that a face can contain  */
+  /*      bitmap strikes also, i.e., a face can have both this flag and    */
   /*      @FT_FACE_FLAG_FIXED_SIZES set.                                   */
   /*                                                                       */
   /*    FT_FACE_FLAG_FIXED_SIZES ::                                        */
-  /*      Indicates that the face contains bitmap strikes.  See also the   */
+  /*      The face contains bitmap strikes.  See also the                  */
   /*      `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec.   */
   /*                                                                       */
   /*    FT_FACE_FLAG_FIXED_WIDTH ::                                        */
-  /*      Indicates that the face contains fixed-width characters (like    */
-  /*      Courier, Lucido, MonoType, etc.).                                */
+  /*      The face contains fixed-width characters (like Courier, Lucida,  */
+  /*      MonoType, etc.).                                                 */
   /*                                                                       */
   /*    FT_FACE_FLAG_SFNT ::                                               */
-  /*      Indicates that the face uses the `sfnt' storage scheme.  For     */
-  /*      now, this means TrueType and OpenType.                           */
+  /*      The face uses the SFNT storage scheme.  For now, this means      */
+  /*      TrueType and OpenType.                                           */
   /*                                                                       */
   /*    FT_FACE_FLAG_HORIZONTAL ::                                         */
-  /*      Indicates that the face contains horizontal glyph metrics.  This */
-  /*      should be set for all common formats.                            */
+  /*      The face contains horizontal glyph metrics.  This should be set  */
+  /*      for all common formats.                                          */
   /*                                                                       */
   /*    FT_FACE_FLAG_VERTICAL ::                                           */
-  /*      Indicates that the face contains vertical glyph metrics.  This   */
-  /*      is only available in some formats, not all of them.              */
+  /*      The face contains vertical glyph metrics.  This is only          */
+  /*      available in some formats, not all of them.                      */
   /*                                                                       */
   /*    FT_FACE_FLAG_KERNING ::                                            */
-  /*      Indicates that the face contains kerning information.  If set,   */
-  /*      the kerning distance can be retrieved through the function       */
-  /*      @FT_Get_Kerning.  Otherwise the function always return the       */
-  /*      vector (0,0).  Note that FreeType doesn't handle kerning data    */
-  /*      from the `GPOS' table (as present in some OpenType fonts).       */
+  /*      The face contains kerning information.  If set, the kerning      */
+  /*      distance can be retrieved using the function @FT_Get_Kerning.    */
+  /*      Otherwise the function always return the vector (0,0).  Note     */
+  /*      that FreeType doesn't handle kerning data from the SFNT `GPOS'   */
+  /*      table (as present in many OpenType fonts).                       */
   /*                                                                       */
   /*    FT_FACE_FLAG_FAST_GLYPHS ::                                        */
   /*      THIS FLAG IS DEPRECATED.  DO NOT USE OR TEST IT.                 */
   /*                                                                       */
   /*    FT_FACE_FLAG_MULTIPLE_MASTERS ::                                   */
-  /*      Indicates that the font contains multiple masters and is capable */
-  /*      of interpolating between them.  See the multiple-masters         */
-  /*      specific API for details.                                        */
+  /*      The face contains multiple masters and is capable of             */
+  /*      interpolating between them.  Supported formats are Adobe MM,     */
+  /*      TrueType GX, and OpenType variation fonts.                       */
+  /*                                                                       */
+  /*      See the multiple-masters specific API for details.               */
   /*                                                                       */
   /*    FT_FACE_FLAG_GLYPH_NAMES ::                                        */
-  /*      Indicates that the font contains glyph names that can be         */
-  /*      retrieved through @FT_Get_Glyph_Name.  Note that some TrueType   */
-  /*      fonts contain broken glyph name tables.  Use the function        */
+  /*      The face contains glyph names, which can be retrieved using      */
+  /*      @FT_Get_Glyph_Name.  Note that some TrueType fonts contain       */
+  /*      broken glyph name tables.  Use the function                      */
   /*      @FT_Has_PS_Glyph_Names when needed.                              */
   /*                                                                       */
   /*    FT_FACE_FLAG_EXTERNAL_STREAM ::                                    */
@@ -1156,31 +1171,31 @@
   /*      when @FT_Done_Face is called.  Don't read or test this flag.     */
   /*                                                                       */
   /*    FT_FACE_FLAG_HINTER ::                                             */
-  /*      Set if the font driver has a hinting machine of its own.  For    */
-  /*      example, with TrueType fonts, it makes sense to use data from    */
-  /*      the SFNT `gasp' table only if the native TrueType hinting engine */
-  /*      (with the bytecode interpreter) is available and active.         */
+  /*      The font driver has a hinting machine of its own.  For example,  */
+  /*      with TrueType fonts, it makes sense to use data from the SFNT    */
+  /*      `gasp' table only if the native TrueType hinting engine (with    */
+  /*      the bytecode interpreter) is available and active.               */
   /*                                                                       */
   /*    FT_FACE_FLAG_CID_KEYED ::                                          */
-  /*      Set if the font is CID-keyed.  In that case, the font is not     */
-  /*      accessed by glyph indices but by CID values.  For subsetted      */
-  /*      CID-keyed fonts this has the consequence that not all index      */
-  /*      values are a valid argument to FT_Load_Glyph.  Only the CID      */
-  /*      values for which corresponding glyphs in the subsetted font      */
-  /*      exist make FT_Load_Glyph return successfully; in all other cases */
-  /*      you get an `FT_Err_Invalid_Argument' error.                      */
+  /*      The face is CID-keyed.  In that case, the face is not accessed   */
+  /*      by glyph indices but by CID values.  For subsetted CID-keyed     */
+  /*      fonts this has the consequence that not all index values are a   */
+  /*      valid argument to @FT_Load_Glyph.  Only the CID values for which */
+  /*      corresponding glyphs in the subsetted font exist make            */
+  /*      `FT_Load_Glyph' return successfully; in all other cases you get  */
+  /*      an `FT_Err_Invalid_Argument' error.                              */
   /*                                                                       */
-  /*      Note that CID-keyed fonts that are in an SFNT wrapper don't      */
-  /*      have this flag set since the glyphs are accessed in the normal   */
-  /*      way (using contiguous indices); the `CID-ness' isn't visible to  */
-  /*      the application.                                                 */
+  /*      Note that CID-keyed fonts that are in an SFNT wrapper (this is,  */
+  /*      all OpenType/CFF fonts) don't have this flag set since the       */
+  /*      glyphs are accessed in the normal way (using contiguous          */
+  /*      indices); the `CID-ness' isn't visible to the application.       */
   /*                                                                       */
   /*    FT_FACE_FLAG_TRICKY ::                                             */
-  /*      Set if the font is `tricky', this is, it always needs the        */
-  /*      font format's native hinting engine to get a reasonable result.  */
-  /*      A typical example is the Chinese font `mingli.ttf' that uses     */
-  /*      TrueType bytecode instructions to move and scale all of its      */
-  /*      subglyphs.                                                       */
+  /*      The face is `tricky', this is, it always needs the font format's */
+  /*      native hinting engine to get a reasonable result.  A typical     */
+  /*      example is the old Chinese font `mingli.ttf' (but not            */
+  /*      `mingliu.ttc') that uses TrueType bytecode instructions to move  */
+  /*      and scale all of its subglyphs.                                  */
   /*                                                                       */
   /*      It is not possible to auto-hint such fonts using                 */
   /*      @FT_LOAD_FORCE_AUTOHINT; it will also ignore                     */
@@ -1192,8 +1207,8 @@
   /*      tricky fonts; they are hard-coded in file `ttobjs.c'.            */
   /*                                                                       */
   /*    FT_FACE_FLAG_COLOR ::                                              */
-  /*      Set if the font has color glyph tables.  To access color glyphs  */
-  /*      use @FT_LOAD_COLOR.                                              */
+  /*      The face has color glyph tables.  To access color glyphs use     */
+  /*      @FT_LOAD_COLOR.                                                  */
   /*                                                                       */
 #define FT_FACE_FLAG_SCALABLE          ( 1L <<  0 )
 #define FT_FACE_FLAG_FIXED_SIZES       ( 1L <<  1 )
@@ -1265,7 +1280,7 @@
    * @description:
    *   A macro that returns true whenever a face object contains a scalable
    *   font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF,
-   *   and PFR font formats.
+   *   and PFR font formats).
    *
    */
 #define FT_IS_SCALABLE( face ) \
@@ -1369,7 +1384,7 @@
    *
    * @description:
    *   A macro that returns true whenever a face object is a named instance
-   *   of a GX variation font.
+   *   of a GX or OpenType variation font.
    *
    */
 #define FT_IS_NAMED_INSTANCE( face ) \
@@ -1428,15 +1443,15 @@
   /*    FT_STYLE_FLAG_XXX                                                  */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A list of bit flags used to indicate the style of a given face.    */
-  /*    These are used in the `style_flags' field of @FT_FaceRec.          */
+  /*    A list of bit flags to indicate the style of a given face.  These  */
+  /*    are used in the `style_flags' field of @FT_FaceRec.                */
   /*                                                                       */
   /* <Values>                                                              */
   /*    FT_STYLE_FLAG_ITALIC ::                                            */
-  /*      Indicates that a given face style is italic or oblique.          */
+  /*      The face style is italic or oblique.                             */
   /*                                                                       */
   /*    FT_STYLE_FLAG_BOLD ::                                              */
-  /*      Indicates that a given face is bold.                             */
+  /*      The face is bold.                                                */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The style information as provided by FreeType is very basic.  More */
@@ -1477,12 +1492,12 @@
   /*                    hence the term `ppem' (pixels per EM).  It is also */
   /*                    referred to as `nominal height'.                   */
   /*                                                                       */
-  /*    x_scale      :: A 16.16 fractional scaling value used to convert   */
+  /*    x_scale      :: A 16.16 fractional scaling value to convert        */
   /*                    horizontal metrics from font units to 26.6         */
   /*                    fractional pixels.  Only relevant for scalable     */
   /*                    font formats.                                      */
   /*                                                                       */
-  /*    y_scale      :: A 16.16 fractional scaling value used to convert   */
+  /*    y_scale      :: A 16.16 fractional scaling value to convert        */
   /*                    vertical metrics from font units to 26.6           */
   /*                    fractional pixels.  Only relevant for scalable     */
   /*                    font formats.                                      */
@@ -1513,7 +1528,7 @@
   /*    glyphs.  As this would be a definite performance hit, it is up to  */
   /*    client applications to perform such computations.                  */
   /*                                                                       */
-  /*    The FT_Size_Metrics structure is valid for bitmap fonts also.      */
+  /*    The `FT_Size_Metrics' structure is valid for bitmap fonts also.    */
   /*                                                                       */
   typedef struct  FT_Size_Metrics_
   {
@@ -1653,8 +1668,8 @@
   /*                         contained in the glyph slot.  Typically       */
   /*                         @FT_GLYPH_FORMAT_BITMAP,                      */
   /*                         @FT_GLYPH_FORMAT_OUTLINE, or                  */
-  /*                         @FT_GLYPH_FORMAT_COMPOSITE, but others are    */
-  /*                         possible.                                     */
+  /*                         @FT_GLYPH_FORMAT_COMPOSITE, but other values  */
+  /*                         are possible.                                 */
   /*                                                                       */
   /*    bitmap            :: This field is used as a bitmap descriptor     */
   /*                         when the slot format is                       */
@@ -1669,16 +1684,15 @@
   /*                         glyph slot contains a bitmap.                 */
   /*                                                                       */
   /*    bitmap_top        :: The bitmap's top bearing expressed in integer */
-  /*                         pixels.  Remember that this is the distance   */
-  /*                         from the baseline to the top-most glyph       */
-  /*                         scanline, upwards y~coordinates being         */
-  /*                         *positive*.                                   */
+  /*                         pixels.  This is the distance from the        */
+  /*                         baseline to the top-most glyph scanline,      */
+  /*                         upwards y~coordinates being *positive*.       */
   /*                                                                       */
   /*    outline           :: The outline descriptor for the current glyph  */
   /*                         image if its format is                        */
   /*                         @FT_GLYPH_FORMAT_OUTLINE.  Once a glyph is    */
   /*                         loaded, `outline' can be transformed,         */
-  /*                         distorted, embolded, etc.  However, it must   */
+  /*                         distorted, emboldened, etc.  However, it must */
   /*                         not be freed.                                 */
   /*                                                                       */
   /*    num_subglyphs     :: The number of subglyphs in a composite glyph. */
@@ -1694,15 +1708,13 @@
   /*    control_data      :: Certain font drivers can also return the      */
   /*                         control data for a given glyph image (e.g.    */
   /*                         TrueType bytecode, Type~1 charstrings, etc.). */
-  /*                         This field is a pointer to such data.         */
+  /*                         This field is a pointer to such data; it is   */
+  /*                         currently internal to FreeType.               */
   /*                                                                       */
   /*    control_len       :: This is the length in bytes of the control    */
-  /*                         data.                                         */
+  /*                         data.  Currently internal to FreeType.        */
   /*                                                                       */
-  /*    other             :: Really wicked formats can use this pointer to */
-  /*                         present their own glyph image to client       */
-  /*                         applications.  Note that the application      */
-  /*                         needs to know about the image format.         */
+  /*    other             :: Reserved.                                     */
   /*                                                                       */
   /*    lsb_delta         :: The difference between hinted and unhinted    */
   /*                         left side bearing while auto-hinting is       */
@@ -1719,7 +1731,7 @@
   /*    formats).                                                          */
   /*                                                                       */
   /*    This image can later be converted into a bitmap by calling         */
-  /*    @FT_Render_Glyph.  This function finds the current renderer for    */
+  /*    @FT_Render_Glyph.  This function searches the current renderer for */
   /*    the native image's format, then invokes it.                        */
   /*                                                                       */
   /*    The renderer is in charge of transforming the native image through */
@@ -1731,7 +1743,6 @@
   /*    position (e.g., coordinates (0,0) on the baseline).  Of course,    */
   /*    `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP.         */
   /*                                                                       */
-  /* <Note>                                                                */
   /*    Here is a small pseudo code fragment that shows how to use         */
   /*    `lsb_delta' and `rsb_delta':                                       */
   /*                                                                       */
@@ -1741,8 +1752,8 @@
   /*                                                                       */
   /*                                                                       */
   /*      for all glyphs do                                                */
-  /*        <compute kern between current and previous glyph and add it to */
-  /*         `origin_x'>                                                   */
+  /*        <compute kern between current and previous glyph               */
+  /*         and add it to `origin_x'>                                     */
   /*                                                                       */
   /*        <load glyph with `FT_Load_Glyph'>                              */
   /*                                                                       */
@@ -1759,6 +1770,12 @@
   /*      endfor                                                           */
   /*    }                                                                  */
   /*                                                                       */
+  /*    If you use strong auto-hinting, you *must* apply these delta       */
+  /*    values!  Otherwise you will experience far too large inter-glyph   */
+  /*    spacing at small rendering sizes in most cases.  Note that it      */
+  /*    doesn't harm to use the above code for other hinting modes also,   */
+  /*    since the delta values are zero then.                              */
+  /*                                                                       */
   typedef struct  FT_GlyphSlotRec_
   {
     FT_Library        library;
@@ -1823,7 +1840,8 @@
   /* <Note>                                                                */
   /*    In case you want to provide your own memory allocating routines,   */
   /*    use @FT_New_Library instead, followed by a call to                 */
-  /*    @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module).  */
+  /*    @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module)   */
+  /*    and @FT_Set_Default_Properties.                                    */
   /*                                                                       */
   /*    See the documentation of @FT_Library and @FT_Face for              */
   /*    multi-threading issues.                                            */
@@ -1831,6 +1849,11 @@
   /*    If you need reference-counting (cf. @FT_Reference_Library), use    */
   /*    @FT_New_Library and @FT_Done_Library.                              */
   /*                                                                       */
+  /*    If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is   */
+  /*    set, this function reads the `FREETYPE_PROPERTIES' environment     */
+  /*    variable to control driver properties.  See sections @auto_hinter, */
+  /*    @cff_driver, @pcf_driver, and @tt_driver for more.                 */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Init_FreeType( FT_Library  *alibrary );
 
@@ -1901,7 +1924,7 @@
   /*    FT_Parameter                                                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A simple structure used to pass more or less generic parameters to */
+  /*    A simple structure to pass more or less generic parameters to      */
   /*    @FT_Open_Face.                                                     */
   /*                                                                       */
   /* <Fields>                                                              */
@@ -1927,9 +1950,9 @@
   /*    FT_Open_Args                                                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to indicate how to open a new font file or        */
-  /*    stream.  A pointer to such a structure can be used as a parameter  */
-  /*    for the functions @FT_Open_Face and @FT_Attach_Stream.             */
+  /*    A structure to indicate how to open a new font file or stream.  A  */
+  /*    pointer to such a structure can be used as a parameter for the     */
+  /*    functions @FT_Open_Face and @FT_Attach_Stream.                     */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    flags       :: A set of bit flags indicating how to use the        */
@@ -1944,9 +1967,10 @@
   /*    stream      :: A handle to a source stream object.                 */
   /*                                                                       */
   /*    driver      :: This field is exclusively used by @FT_Open_Face;    */
-  /*                   it simply specifies the font driver to use to open  */
-  /*                   the face.  If set to~0, FreeType tries to load the  */
-  /*                   face with each one of the drivers in its list.      */
+  /*                   it simply specifies the font driver to use for      */
+  /*                   opening the face.  If set to NULL, FreeType tries   */
+  /*                   to load the face with each one of the drivers in    */
+  /*                   its list.                                           */
   /*                                                                       */
   /*    num_params  :: The number of extra parameters.                     */
   /*                                                                       */
@@ -1999,7 +2023,7 @@
   /*    FT_New_Face                                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This function calls @FT_Open_Face to open a font by its pathname.  */
+  /*    Call @FT_Open_Face to open a font by its pathname.                 */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    library    :: A handle to the library resource.                    */
@@ -2034,8 +2058,8 @@
   /*    FT_New_Memory_Face                                                 */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This function calls @FT_Open_Face to open a font that has been     */
-  /*    loaded into memory.                                                */
+  /*    Call @FT_Open_Face to open a font that has been loaded into        */
+  /*    memory.                                                            */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    library    :: A handle to the library resource.                    */
@@ -2087,20 +2111,21 @@
   /*                  with value~0).  Set it to~0 if there is only one     */
   /*                  face in the font file.                               */
   /*                                                                       */
-  /*                  Bits 16-30 are relevant to GX variation fonts only,  */
-  /*                  specifying the named instance index for the current  */
-  /*                  face index (starting with value~1; value~0 makes     */
-  /*                  FreeType ignore named instances).  For non-GX fonts, */
-  /*                  bits 16-30 are ignored.  Assuming that you want to   */
-  /*                  access the third named instance in face~4,           */
-  /*                  `face_index' should be set to 0x00030004.  If you    */
-  /*                  want to access face~4 without GX variation handling, */
-  /*                  simply set `face_index' to value~4.                  */
+  /*                  Bits 16-30 are relevant to GX and OpenType variation */
+  /*                  fonts only, specifying the named instance index for  */
+  /*                  the current face index (starting with value~1;       */
+  /*                  value~0 makes FreeType ignore named instances).  For */
+  /*                  non-variation fonts, bits 16-30 are ignored.         */
+  /*                  Assuming that you want to access the third named     */
+  /*                  instance in face~4, `face_index' should be set to    */
+  /*                  0x00030004.  If you want to access face~4 without    */
+  /*                  variation handling, simply set `face_index' to       */
+  /*                  value~4.                                             */
   /*                                                                       */
-  /*                  FT_Open_Face and its siblings can be used to quickly */
-  /*                  check whether the font format of a given font        */
-  /*                  resource is supported by FreeType.  In general, if   */
-  /*                  the `face_index' argument is negative, the           */
+  /*                  `FT_Open_Face' and its siblings can be used to       */
+  /*                  quickly check whether the font format of a given     */
+  /*                  font resource is supported by FreeType.  In general, */
+  /*                  if the `face_index' argument is negative, the        */
   /*                  function's return value is~0 if the font format is   */
   /*                  recognized, or non-zero otherwise.  The function     */
   /*                  allocates a more or less empty face handle in        */
@@ -2109,10 +2134,10 @@
   /*                  `face->num_faces' and `face->style_flags'.  For any  */
   /*                  negative value of `face_index', `face->num_faces'    */
   /*                  gives the number of faces within the font file.  For */
-  /*                  the negative value `-(N+1)' (with `N' a 16-bit       */
-  /*                  value), bits 16-30 in `face->style_flags' give the   */
-  /*                  number of named instances in face `N' if we have a   */
-  /*                  GX variation font (or zero otherwise).  After        */
+  /*                  the negative value `-(N+1)' (with `N' a non-negative */
+  /*                  16-bit value), bits 16-30 in `face->style_flags'     */
+  /*                  give the number of named instances in face `N' if we */
+  /*                  have a variation font (or zero otherwise).  After    */
   /*                  examination, the returned @FT_Face structure should  */
   /*                  be deallocated with a call to @FT_Done_Face.         */
   /*                                                                       */
@@ -2219,7 +2244,7 @@
   /*    FT_Attach_File                                                     */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This function calls @FT_Attach_Stream to attach a file.            */
+  /*    Call @FT_Attach_Stream to attach a file.                           */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face         :: The target face object.                            */
@@ -2263,7 +2288,7 @@
   /*                                                                       */
   /*    Client applications are expected to know what they are doing       */
   /*    when invoking this function.  Most drivers simply do not implement */
-  /*    file attachments.                                                  */
+  /*    file or stream attachments.                                        */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Attach_Stream( FT_Face        face,
@@ -2326,7 +2351,10 @@
   /*    FT_Select_Size                                                     */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Select a bitmap strike.                                            */
+  /*    Select a bitmap strike.  To be more precise, this function sets    */
+  /*    the scaling factors of the active @FT_Size object in a face so     */
+  /*    that bitmaps from this particular strike are taken by              */
+  /*    @FT_Load_Glyph and friends.                                        */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face         :: A handle to a target face object.                  */
@@ -2338,6 +2366,20 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    For bitmaps embedded in outline fonts it is common that only a     */
+  /*    subset of the available glyphs at a given ppem value is available. */
+  /*    FreeType silently uses outlines if there is no bitmap for a given  */
+  /*    glyph index.                                                       */
+  /*                                                                       */
+  /*    For GX and OpenType variation fonts, a bitmap strike makes sense   */
+  /*    only if the default instance is active (this is, no glyph          */
+  /*    variation takes place); otherwise, FreeType simply ignores bitmap  */
+  /*    strikes.  The same is true for all named instances that are        */
+  /*    different from the default instance.                               */
+  /*                                                                       */
+  /*    Don't use this function if you are using the FreeType cache API.   */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Select_Size( FT_Face  face,
                   FT_Int   strike_index );
@@ -2367,7 +2409,7 @@
   /*                                                                       */
   /*    FT_SIZE_REQUEST_TYPE_REAL_DIM ::                                   */
   /*      The real dimension.  The sum of the `ascender' and (minus of)    */
-  /*      the `descender' fields of @FT_FaceRec are used to determine both */
+  /*      the `descender' fields of @FT_FaceRec is used to determine both  */
   /*      scaling values.                                                  */
   /*                                                                       */
   /*    FT_SIZE_REQUEST_TYPE_BBOX ::                                       */
@@ -2413,7 +2455,7 @@
   /*    FT_Size_RequestRec                                                 */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a size request.                          */
+  /*    A structure to model a size request.                               */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    type           :: See @FT_Size_Request_Type.                       */
@@ -2426,14 +2468,16 @@
   /*                                                                       */
   /*    horiResolution :: The horizontal resolution (dpi, i.e., pixels per */
   /*                      inch).  If set to zero, `width' is treated as a  */
-  /*                      26.6 fractional *pixel* value.                   */
+  /*                      26.6 fractional *pixel* value, which gets        */
+  /*                      internally rounded to an integer.                */
   /*                                                                       */
   /*    vertResolution :: The vertical resolution (dpi, i.e., pixels per   */
   /*                      inch).  If set to zero, `height' is treated as a */
-  /*                      26.6 fractional *pixel* value.                   */
+  /*                      26.6 fractional *pixel* value, which gets        */
+  /*                      internally rounded to an integer.                */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    If `width' is zero, then the horizontal scaling value is set equal */
+  /*    If `width' is zero, the horizontal scaling value is set equal      */
   /*    to the vertical scaling value, and vice versa.                     */
   /*                                                                       */
   /*    If `type' is FT_SIZE_REQUEST_TYPE_SCALES, `width' and `height' are */
@@ -2490,7 +2534,7 @@
   /*    size is dependent entirely on how the size is defined in the       */
   /*    source face.  The font designer chooses the final size of each     */
   /*    glyph relative to this size.  For more information refer to        */
-  /*    `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'      */
+  /*    `https://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'.    */
   /*                                                                       */
   /*    Don't use this function if you are using the FreeType cache API.   */
   /*                                                                       */
@@ -2505,8 +2549,7 @@
   /*    FT_Set_Char_Size                                                   */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This function calls @FT_Request_Size to request the nominal size   */
-  /*    (in points).                                                       */
+  /*    Call @FT_Request_Size to request the nominal size (in points).     */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face            :: A handle to a target face object.               */
@@ -2524,6 +2567,10 @@
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
+  /*    While this function allows fractional points as input values, the  */
+  /*    resulting ppem value for the given resolution is always rounded to */
+  /*    the nearest integer.                                               */
+  /*                                                                       */
   /*    If either the character width or height is zero, it is set equal   */
   /*    to the other value.                                                */
   /*                                                                       */
@@ -2549,8 +2596,7 @@
   /*    FT_Set_Pixel_Sizes                                                 */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This function calls @FT_Request_Size to request the nominal size   */
-  /*    (in pixels).                                                       */
+  /*    Call @FT_Request_Size to request the nominal size (in pixels).     */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face         :: A handle to the target face object.                */
@@ -2564,8 +2610,8 @@
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    You should not rely on the resulting glyphs matching, or being     */
-  /*    constrained, to this pixel size.  Refer to @FT_Request_Size to     */
+  /*    You should not rely on the resulting glyphs matching or being      */
+  /*    constrained to this pixel size.  Refer to @FT_Request_Size to      */
   /*    understand how requested sizes relate to actual sizes.             */
   /*                                                                       */
   /*    Don't use this function if you are using the FreeType cache API.   */
@@ -2582,8 +2628,7 @@
   /*    FT_Load_Glyph                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A function used to load a single glyph into the glyph slot of a    */
-  /*    face object.                                                       */
+  /*    Load a glyph into the glyph slot of a face object.                 */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face        :: A handle to the target face object where the glyph  */
@@ -2628,8 +2673,8 @@
   /*    FT_Load_Char                                                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A function used to load a single glyph into the glyph slot of a    */
-  /*    face object, according to its character code.                      */
+  /*    Load a glyph into the glyph slot of a face object, accessed by its */
+  /*    character code.                                                    */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face        :: A handle to a target face object where the glyph    */
@@ -2651,6 +2696,10 @@
   /* <Note>                                                                */
   /*    This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph.  */
   /*                                                                       */
+  /*    Many fonts contain glyphs that can't be loaded by this function    */
+  /*    since its glyph indices are not listed in any of the font's        */
+  /*    charmaps.                                                          */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Load_Char( FT_Face   face,
                 FT_ULong  char_code,
@@ -2663,8 +2712,8 @@
    *   FT_LOAD_XXX
    *
    * @description:
-   *   A list of bit field constants used with @FT_Load_Glyph to indicate
-   *   what kind of operations to perform during glyph loading.
+   *   A list of bit field constants for @FT_Load_Glyph to indicate what
+   *   kind of operations to perform during glyph loading.
    *
    * @values:
    *   FT_LOAD_DEFAULT ::
@@ -2676,13 +2725,13 @@
    *        The bitmap data can be accessed from the glyph slot (see note
    *        below).
    *
-   *     2. If no embedded bitmap is searched or found, FreeType looks for a
-   *        scalable outline.  If one is found, it is loaded from the font
-   *        file, scaled to device pixels, then `hinted' to the pixel grid
-   *        in order to optimize it.  The outline data can be accessed from
-   *        the glyph slot (see note below).
+   *     2. If no embedded bitmap is searched for or found, FreeType looks
+   *        for a scalable outline.  If one is found, it is loaded from
+   *        the font file, scaled to device pixels, then `hinted' to the
+   *        pixel grid in order to optimize it.  The outline data can be
+   *        accessed from the glyph slot (see note below).
    *
-   *     Note that by default, the glyph loader doesn't render outlines into
+   *     Note that by default the glyph loader doesn't render outlines into
    *     bitmaps.  The following flags are used to modify this default
    *     behaviour to more specific and useful cases.
    *
@@ -2729,13 +2778,13 @@
    *     various font formats.
    *
    *   FT_LOAD_FORCE_AUTOHINT ::
-   *     Indicates that the auto-hinter is preferred over the font's native
-   *     hinter.  See also the note below.
+   *     Prefer the auto-hinter over the font's native hinter.  See also
+   *     the note below.
    *
    *   FT_LOAD_PEDANTIC ::
-   *     Indicates that the font driver should perform pedantic verifications
-   *     during glyph loading.  This is mostly used to detect broken glyphs
-   *     in fonts.  By default, FreeType tries to handle broken fonts also.
+   *     Make the font driver perform pedantic verifications during glyph
+   *     loading.  This is mostly used to detect broken glyphs in fonts.
+   *     By default, FreeType tries to handle broken fonts also.
    *
    *     In particular, errors from the TrueType bytecode engine are not
    *     passed to the application if this flag is not set; this might
@@ -2743,17 +2792,16 @@
    *     bytecode is buggy.
    *
    *   FT_LOAD_NO_RECURSE ::
-   *     Indicate that the font driver should not load composite glyphs
-   *     recursively.  Instead, it should set the `num_subglyph' and
-   *     `subglyphs' values of the glyph slot accordingly, and set
-   *     `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE.  The description of
-   *     subglyphs can then be accessed with @FT_Get_SubGlyph_Info.
+   *     Don't load composite glyphs recursively.  Instead, the font
+   *     driver should set the `num_subglyph' and `subglyphs' values of
+   *     the glyph slot accordingly, and set `glyph->format' to
+   *     @FT_GLYPH_FORMAT_COMPOSITE.  The description of subglyphs can
+   *     then be accessed with @FT_Get_SubGlyph_Info.
    *
    *     This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM.
    *
    *   FT_LOAD_IGNORE_TRANSFORM ::
-   *     Indicates that the transform matrix set by @FT_Set_Transform should
-   *     be ignored.
+   *     Ignore the transform matrix set by @FT_Set_Transform.
    *
    *   FT_LOAD_MONOCHROME ::
    *     This flag is used with @FT_LOAD_RENDER to indicate that you want to
@@ -2765,36 +2813,34 @@
    *     monochrome-optimized hinting algorithm is used.
    *
    *   FT_LOAD_LINEAR_DESIGN ::
-   *     Indicates that the `linearHoriAdvance' and `linearVertAdvance'
-   *     fields of @FT_GlyphSlotRec should be kept in font units.  See
-   *     @FT_GlyphSlotRec for details.
+   *     Keep  `linearHoriAdvance' and `linearVertAdvance' fields of
+   *     @FT_GlyphSlotRec in font units.  See @FT_GlyphSlotRec for
+   *     details.
    *
    *   FT_LOAD_NO_AUTOHINT ::
-   *     Disable auto-hinter.  See also the note below.
+   *     Disable the auto-hinter.  See also the note below.
    *
    *   FT_LOAD_COLOR ::
-   *     This flag is used to request loading of color embedded-bitmap
-   *     images.  The resulting color bitmaps, if available, will have the
-   *     @FT_PIXEL_MODE_BGRA format.  When the flag is not used and color
-   *     bitmaps are found, they will be converted to 256-level gray
-   *     bitmaps transparently.  Those bitmaps will be in the
+   *     Load embedded color bitmap images.  The resulting color bitmaps,
+   *     if available, will have the @FT_PIXEL_MODE_BGRA format.  If the
+   *     flag is not set and color bitmaps are found, they are converted
+   *     to 256-level gray bitmaps transparently, using the
    *     @FT_PIXEL_MODE_GRAY format.
    *
    *   FT_LOAD_COMPUTE_METRICS ::
-   *     This flag sets computing glyph metrics without the use of bundled
-   *     metrics tables (for example, the `hdmx' table in TrueType fonts).
-   *     Well-behaving fonts have optimized bundled metrics and these should
-   *     be used.  This flag is mainly used by font validating or font
+   *     Compute glyph metrics from the glyph data, without the use of
+   *     bundled metrics tables (for example, the `hdmx' table in TrueType
+   *     fonts).  This flag is mainly used by font validating or font
    *     editing applications, which need to ignore, verify, or edit those
    *     tables.
    *
    *     Currently, this flag is only implemented for TrueType fonts.
    *
    *   FT_LOAD_BITMAP_METRICS_ONLY ::
-   *     This flag is used to request loading of the metrics and bitmap
-   *     image information of a (possibly embedded) bitmap glyph without
-   *     allocating or copying the bitmap image data itself.  No effect if
-   *     the target glyph is not a bitmap image.
+   *     Request loading of the metrics and bitmap image information of a
+   *     (possibly embedded) bitmap glyph without allocating or copying
+   *     the bitmap image data itself.  No effect if the target glyph is
+   *     not a bitmap image.
    *
    *     This flag unsets @FT_LOAD_RENDER.
    *
@@ -2841,14 +2887,14 @@
 #define FT_LOAD_MONOCHROME                   ( 1L << 12 )
 #define FT_LOAD_LINEAR_DESIGN                ( 1L << 13 )
 #define FT_LOAD_NO_AUTOHINT                  ( 1L << 15 )
-  /* Bits 16..19 are used by `FT_LOAD_TARGET_' */
+  /* Bits 16-19 are used by `FT_LOAD_TARGET_' */
 #define FT_LOAD_COLOR                        ( 1L << 20 )
 #define FT_LOAD_COMPUTE_METRICS              ( 1L << 21 )
 #define FT_LOAD_BITMAP_METRICS_ONLY          ( 1L << 22 )
 
   /* */
 
-  /* used internally only by certain font drivers! */
+  /* used internally only by certain font drivers */
 #define FT_LOAD_ADVANCE_ONLY                 ( 1L << 8 )
 #define FT_LOAD_SBITS_ONLY                   ( 1L << 14 )
 
@@ -2859,19 +2905,20 @@
    *   FT_LOAD_TARGET_XXX
    *
    * @description:
-   *   A list of values that are used to select a specific hinting algorithm
-   *   to use by the hinter.  You should OR one of these values to your
-   *   `load_flags' when calling @FT_Load_Glyph.
+   *   A list of values to select a specific hinting algorithm for the
+   *   hinter.  You should OR one of these values to your `load_flags'
+   *   when calling @FT_Load_Glyph.
    *
-   *   Note that font's native hinters may ignore the hinting algorithm you
-   *   have specified (e.g., the TrueType bytecode interpreter).  You can set
-   *   @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used.
+   *   Note that a font's native hinters may ignore the hinting algorithm
+   *   you have specified (e.g., the TrueType bytecode interpreter).  You
+   *   can set @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is
+   *   used.
    *
    * @values:
    *   FT_LOAD_TARGET_NORMAL ::
-   *     This corresponds to the default hinting algorithm, optimized for
-   *     standard gray-level rendering.  For monochrome output, use
-   *     @FT_LOAD_TARGET_MONO instead.
+   *     The default hinting algorithm, optimized for standard gray-level
+   *     rendering.  For monochrome output, use @FT_LOAD_TARGET_MONO
+   *     instead.
    *
    *   FT_LOAD_TARGET_LIGHT ::
    *     A lighter hinting algorithm for gray-level modes.  Many generated
@@ -2880,7 +2927,7 @@
    *     (Y-axis), as is done by Microsoft's ClearType and Adobe's
    *     proprietary font renderer.  This preserves inter-glyph spacing in
    *     horizontal text.  The snapping is done either by the native font
-   *     driver if the driver itself and the font support it or by the
+   *     driver, if the driver itself and the font support it, or by the
    *     auto-hinter.
    *
    *   FT_LOAD_TARGET_MONO ::
@@ -2946,18 +2993,17 @@
   /*    FT_Set_Transform                                                   */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A function used to set the transformation that is applied to glyph */
-  /*    images when they are loaded into a glyph slot through              */
-  /*    @FT_Load_Glyph.                                                    */
+  /*    Set the transformation that is applied to glyph images when they   */
+  /*    are loaded into a glyph slot through @FT_Load_Glyph.               */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face   :: A handle to the source face object.                      */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    matrix :: A pointer to the transformation's 2x2 matrix.  Use~0 for */
-  /*              the identity matrix.                                     */
-  /*    delta  :: A pointer to the translation vector.  Use~0 for the null */
-  /*              vector.                                                  */
+  /*    matrix :: A pointer to the transformation's 2x2 matrix.  Use NULL  */
+  /*              for the identity matrix.                                 */
+  /*    delta  :: A pointer to the translation vector.  Use NULL for the   */
+  /*              null vector.                                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The transformation is only applied to scalable image formats after */
@@ -2980,9 +3026,8 @@
   /*    FT_Render_Mode                                                     */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    An enumeration type that lists the render modes supported by       */
-  /*    FreeType~2.  Each mode corresponds to a specific type of scanline  */
-  /*    conversion performed on the outline.                               */
+  /*    Render modes supported by FreeType~2.  Each mode corresponds to a  */
+  /*    specific type of scanline conversion performed on the outline.     */
   /*                                                                       */
   /*    For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode'     */
   /*    field in the @FT_GlyphSlotRec structure gives the format of the    */
@@ -2995,8 +3040,8 @@
   /*                                                                       */
   /* <Values>                                                              */
   /*    FT_RENDER_MODE_NORMAL ::                                           */
-  /*      This is the default render mode; it corresponds to 8-bit         */
-  /*      anti-aliased bitmaps.                                            */
+  /*      Default render mode; it corresponds to 8-bit anti-aliased        */
+  /*      bitmaps.                                                         */
   /*                                                                       */
   /*    FT_RENDER_MODE_LIGHT ::                                            */
   /*      This is equivalent to @FT_RENDER_MODE_NORMAL.  It is only        */
@@ -3021,11 +3066,11 @@
   /*      glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode.   */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */
-  /*    filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */
-  /*    (not active in the default builds).  It is up to the caller to     */
-  /*    either call @FT_Library_SetLcdFilter (if available) or do the      */
-  /*    filtering itself.                                                  */
+  /*    The LCD-optimized glyph bitmaps produced by `FT_Render_Glyph' can  */
+  /*    be filtered to reduce color-fringes by using                       */
+  /*    @FT_Library_SetLcdFilter (not active in the default builds).  It   */
+  /*    is up to the caller to either call `FT_Library_SetLcdFilter' (if   */
+  /*    available) or do the filtering itself.                             */
   /*                                                                       */
   /*    The selected render mode only affects vector glyphs of a font.     */
   /*    Embedded bitmaps often have a different pixel mode like            */
@@ -3066,16 +3111,16 @@
   /*                   convert.                                            */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    render_mode :: This is the render mode used to render the glyph    */
-  /*                   image into a bitmap.  See @FT_Render_Mode for a     */
-  /*                   list of possible values.                            */
+  /*    render_mode :: The render mode used to render the glyph image into */
+  /*                   a bitmap.  See @FT_Render_Mode for a list of        */
+  /*                   possible values.                                    */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    To get meaningful results, font scaling values must be set with    */
-  /*    functions like @FT_Set_Char_Size before calling FT_Render_Glyph.   */
+  /*    functions like @FT_Set_Char_Size before calling `FT_Render_Glyph'. */
   /*                                                                       */
   /*    When FreeType outputs a bitmap of a glyph, it really outputs an    */
   /*    alpha coverage map.  If a pixel is completely covered by a         */
@@ -3165,17 +3210,15 @@
   /*    FT_Kerning_Mode                                                    */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    An enumeration used to specify which kerning values to return in   */
+  /*    An enumeration to specify the format of kerning values returned by */
   /*    @FT_Get_Kerning.                                                   */
   /*                                                                       */
   /* <Values>                                                              */
   /*    FT_KERNING_DEFAULT  :: Return grid-fitted kerning distances in     */
-  /*                           pixels (value is~0).  Whether they are      */
-  /*                           scaled depends on @FT_LOAD_NO_SCALE.        */
+  /*                           26.6 fractional pixels.                     */
   /*                                                                       */
   /*    FT_KERNING_UNFITTED :: Return un-grid-fitted kerning distances in  */
-  /*                           26.6 fractional pixels.  Whether they are   */
-  /*                           scaled depends on @FT_LOAD_NO_SCALE.        */
+  /*                           26.6 fractional pixels.                     */
   /*                                                                       */
   /*    FT_KERNING_UNSCALED :: Return the kerning vector in original font  */
   /*                           units.                                      */
@@ -3185,9 +3228,13 @@
   /*    FreeType heuristically scale down kerning distances at small ppem  */
   /*    values so that they don't become too big.                          */
   /*                                                                       */
+  /*    Both FT_KERNING_DEFAULT and FT_KERNING_UNFITTED use the current    */
+  /*    horizontal scaling factor (as set e.g. with @FT_Set_Char_Size) to  */
+  /*    convert font units to pixels.                                      */
+  /*                                                                       */
   typedef enum  FT_Kerning_Mode_
   {
-    FT_KERNING_DEFAULT  = 0,
+    FT_KERNING_DEFAULT = 0,
     FT_KERNING_UNFITTED,
     FT_KERNING_UNSCALED
 
@@ -3207,7 +3254,7 @@
   /*    FT_Get_Kerning                                                     */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Return the kerning vector between two glyphs of a same face.       */
+  /*    Return the kerning vector between two glyphs of the same face.     */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face        :: A handle to a source face object.                   */
@@ -3235,6 +3282,10 @@
   /*    kernings, are out of the scope of this API function -- they can be */
   /*    implemented through format-specific interfaces.                    */
   /*                                                                       */
+  /*    Kerning for OpenType fonts implemented in a `GPOS' table is not    */
+  /*    supported; use @FT_HAS_KERNING to find out whether a font has data */
+  /*    that can be extracted with `FT_Get_Kerning'.                       */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Get_Kerning( FT_Face     face,
                   FT_UInt     left_glyph,
@@ -3274,7 +3325,7 @@
   /*    @FT_Attach_Stream).                                                */
   /*                                                                       */
   /*    Only very few AFM files come with track kerning data; please refer */
-  /*    to the Adobe's AFM specification for more details.                 */
+  /*    to Adobe's AFM specification for more details.                     */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Get_Track_Kerning( FT_Face    face,
@@ -3336,7 +3387,7 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    Retrieve the ASCII PostScript name of a given face, if available.  */
-  /*    This only works with PostScript and TrueType fonts.                */
+  /*    This only works with PostScript, TrueType, and OpenType fonts.     */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face :: A handle to the source face object.                        */
@@ -3407,7 +3458,8 @@
   /*    the face (i.e., if it is not listed in the `face->charmaps'        */
   /*    table).                                                            */
   /*                                                                       */
-  /*    It also fails if a type~14 charmap is selected.                    */
+  /*    It also fails if an OpenType type~14 charmap is selected (which    */
+  /*    doesn't map character codes to glyph indices at all).              */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Set_Charmap( FT_Face     face,
@@ -3442,7 +3494,7 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    Return the glyph index of a given character code.  This function   */
-  /*    uses a charmap object to do the mapping.                           */
+  /*    uses the currently selected charmap to do the mapping.             */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face     :: A handle to the source face object.                    */
@@ -3476,9 +3528,8 @@
   /*    FT_Get_First_Char                                                  */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This function is used to return the first character code in the    */
-  /*    current charmap of a given face.  It also returns the              */
-  /*    corresponding glyph index.                                         */
+  /*    Return the first character code in the current charmap of a given  */
+  /*    face, together with its corresponding glyph index.                 */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face    :: A handle to the source face object.                     */
@@ -3491,7 +3542,7 @@
   /*    The charmap's first character code.                                */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    You should use this function with @FT_Get_Next_Char to be able to  */
+  /*    You should use this function together with @FT_Get_Next_Char to    */
   /*    parse all character codes available in a given charmap.  The code  */
   /*    should look like this:                                             */
   /*                                                                       */
@@ -3531,12 +3582,13 @@
   /*    FT_Get_Next_Char                                                   */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This function is used to return the next character code in the     */
-  /*    current charmap of a given face following the value `char_code',   */
-  /*    as well as the corresponding glyph index.                          */
+  /*    Return the next character code in the current charmap of a given   */
+  /*    face following the value `char_code', as well as the corresponding */
+  /*    glyph index.                                                       */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face      :: A handle to the source face object.                   */
+  /*                                                                       */
   /*    char_code :: The starting character code.                          */
   /*                                                                       */
   /* <Output>                                                              */
@@ -3549,7 +3601,7 @@
   /* <Note>                                                                */
   /*    You should use this function with @FT_Get_First_Char to walk       */
   /*    over all character codes available in a given charmap.  See the    */
-  /*    note for this function for a simple code example.                  */
+  /*    note for that function for a simple code example.                  */
   /*                                                                       */
   /*    Note that `*agindex' is set to~0 when there are no more codes in   */
   /*    the charmap.                                                       */
@@ -3566,8 +3618,7 @@
   /*    FT_Get_Name_Index                                                  */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Return the glyph index of a given glyph name.  This function uses  */
-  /*    driver specific objects to do the translation.                     */
+  /*    Return the glyph index of a given glyph name.                      */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face       :: A handle to the source face object.                  */
@@ -3588,8 +3639,10 @@
    *   FT_SUBGLYPH_FLAG_XXX
    *
    * @description:
-   *   A list of constants used to describe subglyphs.  Please refer to the
-   *   TrueType specification for the meaning of the various flags.
+   *   A list of constants describing subglyphs.  Please refer to the
+   *   `glyf' table description in the OpenType specification for the
+   *   meaning of the various flags (which get synthesized for
+   *   non-OpenType subglyphs).
    *
    * @values:
    *   FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS ::
@@ -3650,7 +3703,7 @@
    * @note:
    *   The values of `*p_arg1', `*p_arg2', and `*p_transform' must be
    *   interpreted depending on the flags returned in `*p_flags'.  See the
-   *   TrueType specification for details.
+   *   OpenType specification for details.
    *
    */
   FT_EXPORT( FT_Error )
@@ -3690,33 +3743,31 @@
   /*      the font software copyright owner.                               */
   /*                                                                       */
   /*    FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING ::                           */
-  /*      If this bit is set, the font may be embedded and temporarily     */
-  /*      loaded on the remote system.  Documents containing Preview &     */
-  /*      Print fonts must be opened `read-only'; no edits can be applied  */
-  /*      to the document.                                                 */
+  /*      The font may be embedded and temporarily loaded on the remote    */
+  /*      system.  Documents containing Preview & Print fonts must be      */
+  /*      opened `read-only'; no edits can be applied to the document.     */
   /*                                                                       */
   /*    FT_FSTYPE_EDITABLE_EMBEDDING ::                                    */
-  /*      If this bit is set, the font may be embedded but must only be    */
-  /*      installed temporarily on other systems.  In contrast to Preview  */
-  /*      & Print fonts, documents containing editable fonts may be opened */
-  /*      for reading, editing is permitted, and changes may be saved.     */
+  /*      The font may be embedded but must only be installed temporarily  */
+  /*      on other systems.  In contrast to Preview & Print fonts,         */
+  /*      documents containing editable fonts may be opened for reading,   */
+  /*      editing is permitted, and changes may be saved.                  */
   /*                                                                       */
   /*    FT_FSTYPE_NO_SUBSETTING ::                                         */
-  /*      If this bit is set, the font may not be subsetted prior to       */
-  /*      embedding.                                                       */
+  /*      The font may not be subsetted prior to embedding.                */
   /*                                                                       */
   /*    FT_FSTYPE_BITMAP_EMBEDDING_ONLY ::                                 */
-  /*      If this bit is set, only bitmaps contained in the font may be    */
-  /*      embedded; no outline data may be embedded.  If there are no      */
-  /*      bitmaps available in the font, then the font is unembeddable.    */
+  /*      Only bitmaps contained in the font may be embedded; no outline   */
+  /*      data may be embedded.  If there are no bitmaps available in the  */
+  /*      font, then the font is unembeddable.                             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The flags are ORed together, thus more than a single value can be  */
   /*    returned.                                                          */
   /*                                                                       */
-  /*    While the fsType flags can indicate that a font may be embedded, a */
-  /*    license with the font vendor may be separately required to use the */
-  /*    font in this way.                                                  */
+  /*    While the `fsType' flags can indicate that a font may be embedded, */
+  /*    a license with the font vendor may be separately required to use   */
+  /*    the font in this way.                                              */
   /*                                                                       */
 #define FT_FSTYPE_INSTALLABLE_EMBEDDING         0x0000
 #define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING  0x0002
@@ -3732,13 +3783,13 @@
   /*    FT_Get_FSType_Flags                                                */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Return the fsType flags for a font.                                */
+  /*    Return the `fsType' flags for a font.                              */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face :: A handle to the source face object.                        */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    The fsType flags, @FT_FSTYPE_XXX.                                  */
+  /*    The `fsType' flags, see @FT_FSTYPE_XXX.                            */
   /*                                                                       */
   /* <Note>                                                                */
   /*    Use this function rather than directly reading the `fs_type' field */
@@ -3758,39 +3809,51 @@
   /*    glyph_variants                                                     */
   /*                                                                       */
   /* <Title>                                                               */
-  /*    Glyph Variants                                                     */
+  /*    Unicode Variation Sequences                                        */
   /*                                                                       */
   /* <Abstract>                                                            */
-  /*    The FreeType~2 interface to Unicode Ideographic Variation          */
-  /*    Sequences (IVS), using the SFNT cmap format~14.                    */
+  /*    The FreeType~2 interface to Unicode Variation Sequences (UVS),     */
+  /*    using the SFNT cmap format~14.                                     */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Many CJK characters have variant forms.  They are a sort of grey   */
-  /*    area somewhere between being totally irrelevant and semantically   */
-  /*    distinct; for this reason, the Unicode consortium decided to       */
-  /*    introduce Ideographic Variation Sequences (IVS), consisting of a   */
-  /*    Unicode base character and one of 240 variant selectors            */
-  /*    (U+E0100-U+E01EF), instead of further extending the already huge   */
-  /*    code range for CJK characters.                                     */
+  /*    Many characters, especially for CJK scripts, have variant forms.   */
+  /*    They are a sort of grey area somewhere between being totally       */
+  /*    irrelevant and semantically distinct; for this reason, the Unicode */
+  /*    consortium decided to introduce Variation Sequences (VS),          */
+  /*    consisting of a Unicode base character and a variation selector    */
+  /*    instead of further extending the already huge number of            */
+  /*    characters.                                                        */
   /*                                                                       */
-  /*    An IVS is registered and unique; for further details please refer  */
-  /*    to Unicode Technical Standard #37, the Ideographic Variation       */
-  /*    Database:                                                          */
+  /*    Unicode maintains two different sets, namely `Standardized         */
+  /*    Variation Sequences' and registered `Ideographic Variation         */
+  /*    Sequences' (IVS), collected in the `Ideographic Variation          */
+  /*    Database' (IVD).                                                   */
   /*                                                                       */
-  /*      http://www.unicode.org/reports/tr37/                             */
+  /*      http://unicode.org/Public/UCD/latest/ucd/StandardizedVariants.txt */
+  /*      http://unicode.org/reports/tr37/                                 */
+  /*      http://unicode.org/ivd/                                          */
   /*                                                                       */
-  /*    To date (November 2014), the character with the most variants is   */
-  /*    U+9089, having 32 such IVS.                                        */
+  /*    To date (January 2017), the character with the most ideographic    */
+  /*    variations is U+9089, having 32 such IVS.                          */
   /*                                                                       */
-  /*    Adobe and MS decided to support IVS with a new cmap subtable       */
-  /*    (format~14).  It is an odd subtable because it is not a mapping of */
-  /*    input code points to glyphs, but contains lists of all variants    */
-  /*    supported by the font.                                             */
+  /*    Three Mongolian Variation Selectors have the values U+180B-U+180D; */
+  /*    256 generic Variation Selectors are encoded in the ranges          */
+  /*    U+FE00-U+FE0F and U+E0100-U+E01EF.  IVS currently use Variation    */
+  /*    Selectors from the range U+E0100-U+E01EF only.                     */
   /*                                                                       */
-  /*    A variant may be either `default' or `non-default'.  A default     */
-  /*    variant is the one you will get for that code point if you look it */
-  /*    up in the standard Unicode cmap.  A non-default variant is a       */
-  /*    different glyph.                                                   */
+  /*    A VS consists of the base character value followed by a single     */
+  /*    Variation Selector.  For example, to get the first variation of    */
+  /*    U+9089, you have to write the character sequence `U+9089 U+E0100'. */
+  /*                                                                       */
+  /*    Adobe and MS decided to support both standardized and ideographic  */
+  /*    VS with a new cmap subtable (format~14).  It is an odd subtable    */
+  /*    because it is not a mapping of input code points to glyphs, but    */
+  /*    contains lists of all variations supported by the font.            */
+  /*                                                                       */
+  /*    A variation may be either `default' or `non-default' for a given   */
+  /*    font.  A default variation is the one you will get for that code   */
+  /*    point if you look it up in the standard Unicode cmap.  A           */
+  /*    non-default variation is a different glyph.                        */
   /*                                                                       */
   /*************************************************************************/
 
@@ -3846,8 +3909,8 @@
   /*    FT_Face_GetCharVariantIsDefault                                    */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Check whether this variant of this Unicode character is the one to */
-  /*    be found in the `cmap'.                                            */
+  /*    Check whether this variation of this Unicode character is the one  */
+  /*    to be found in the `cmap'.                                         */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face ::                                                            */
@@ -3861,7 +3924,7 @@
   /*                                                                       */
   /* <Return>                                                              */
   /*    1~if found in the standard (Unicode) cmap, 0~if found in the       */
-  /*    variation selector cmap, or -1 if it is not a variant.             */
+  /*    variation selector cmap, or -1 if it is not a variation.           */
   /*                                                                       */
   /* <Note>                                                                */
   /*    This function is only meaningful if the font has a variation       */
@@ -3882,7 +3945,7 @@
   /*    FT_Face_GetVariantSelectors                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Return a zero-terminated list of Unicode variant selectors found   */
+  /*    Return a zero-terminated list of Unicode variation selectors found */
   /*    in the font.                                                       */
   /*                                                                       */
   /* <Input>                                                               */
@@ -3891,7 +3954,7 @@
   /*                                                                       */
   /* <Return>                                                              */
   /*    A pointer to an array of selector code points, or NULL if there is */
-  /*    no valid variant selector cmap subtable.                           */
+  /*    no valid variation selector cmap subtable.                         */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The last item in the array is~0; the array is owned by the         */
@@ -3911,7 +3974,7 @@
   /*    FT_Face_GetVariantsOfChar                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Return a zero-terminated list of Unicode variant selectors found   */
+  /*    Return a zero-terminated list of Unicode variation selectors found */
   /*    for the specified character code.                                  */
   /*                                                                       */
   /* <Input>                                                               */
@@ -3922,7 +3985,7 @@
   /*      The character codepoint in Unicode.                              */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    A pointer to an array of variant selector code points that are     */
+  /*    A pointer to an array of variation selector code points that are   */
   /*    active for the given character, or NULL if the corresponding list  */
   /*    is empty.                                                          */
   /*                                                                       */
@@ -3946,19 +4009,19 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    Return a zero-terminated list of Unicode character codes found for */
-  /*    the specified variant selector.                                    */
+  /*    the specified variation selector.                                  */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face ::                                                            */
   /*      A handle to the source face object.                              */
   /*                                                                       */
   /*    variantSelector ::                                                 */
-  /*      The variant selector code point in Unicode.                      */
+  /*      The variation selector code point in Unicode.                    */
   /*                                                                       */
   /* <Return>                                                              */
   /*    A list of all the code points that are specified by this selector  */
   /*    (both default and non-default codes are returned) or NULL if there */
-  /*    is no valid cmap or the variant selector is invalid.               */
+  /*    is no valid cmap or the variation selector is invalid.             */
   /*                                                                       */
   /* <Note>                                                                */
   /*    The last item in the array is~0; the array is owned by the         */
@@ -4008,16 +4071,17 @@
   /*    FT_MulDiv                                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A very simple function used to perform the computation `(a*b)/c'   */
-  /*    with maximum accuracy (it uses a 64-bit intermediate integer       */
-  /*    whenever necessary).                                               */
+  /*    Compute `(a*b)/c' with maximum accuracy, using a 64-bit            */
+  /*    intermediate integer whenever necessary.                           */
   /*                                                                       */
   /*    This function isn't necessarily as fast as some processor specific */
   /*    operations, but is at least completely portable.                   */
   /*                                                                       */
   /* <Input>                                                               */
   /*    a :: The first multiplier.                                         */
+  /*                                                                       */
   /*    b :: The second multiplier.                                        */
+  /*                                                                       */
   /*    c :: The divisor.                                                  */
   /*                                                                       */
   /* <Return>                                                              */
@@ -4037,12 +4101,12 @@
   /*    FT_MulFix                                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A very simple function used to perform the computation             */
-  /*    `(a*b)/0x10000' with maximum accuracy.  Most of the time this is   */
-  /*    used to multiply a given value by a 16.16 fixed-point factor.      */
+  /*    Compute `(a*b)/0x10000' with maximum accuracy.  Its main use is to */
+  /*    multiply a given value by a 16.16 fixed-point factor.              */
   /*                                                                       */
   /* <Input>                                                               */
   /*    a :: The first multiplier.                                         */
+  /*                                                                       */
   /*    b :: The second multiplier.  Use a 16.16 factor here whenever      */
   /*         possible (see note below).                                    */
   /*                                                                       */
@@ -4071,12 +4135,12 @@
   /*    FT_DivFix                                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A very simple function used to perform the computation             */
-  /*    `(a*0x10000)/b' with maximum accuracy.  Most of the time, this is  */
-  /*    used to divide a given value by a 16.16 fixed-point factor.        */
+  /*    Compute `(a*0x10000)/b' with maximum accuracy.  Its main use is to */
+  /*    divide a given value by a 16.16 fixed-point factor.                */
   /*                                                                       */
   /* <Input>                                                               */
   /*    a :: The numerator.                                                */
+  /*                                                                       */
   /*    b :: The denominator.  Use a 16.16 factor here.                    */
   /*                                                                       */
   /* <Return>                                                              */
@@ -4093,13 +4157,13 @@
   /*    FT_RoundFix                                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A very simple function used to round a 16.16 fixed number.         */
+  /*    Round a 16.16 fixed number.                                        */
   /*                                                                       */
   /* <Input>                                                               */
   /*    a :: The number to be rounded.                                     */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    `a' rounded to nearest 16.16 fixed integer, halfway cases away     */
+  /*    `a' rounded to the nearest 16.16 fixed integer, halfway cases away */
   /*    from zero.                                                         */
   /*                                                                       */
   FT_EXPORT( FT_Fixed )
@@ -4112,8 +4176,7 @@
   /*    FT_CeilFix                                                         */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A very simple function used to compute the ceiling function of a   */
-  /*    16.16 fixed number.                                                */
+  /*    Compute the smallest following integer of a 16.16 fixed number.    */
   /*                                                                       */
   /* <Input>                                                               */
   /*    a :: The number for which the ceiling function is to be computed.  */
@@ -4131,8 +4194,7 @@
   /*    FT_FloorFix                                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A very simple function used to compute the floor function of a     */
-  /*    16.16 fixed number.                                                */
+  /*    Compute the largest previous integer of a 16.16 fixed number.      */
   /*                                                                       */
   /* <Input>                                                               */
   /*    a :: The number for which the floor function is to be computed.    */
@@ -4219,7 +4281,7 @@
    */
 #define FREETYPE_MAJOR  2
 #define FREETYPE_MINOR  7
-#define FREETYPE_PATCH  0
+#define FREETYPE_PATCH  1
 
 
   /*************************************************************************/
diff --git a/include/freetype/ftadvanc.h b/include/freetype/ftadvanc.h
index 023dd84..dea96e0 100644
--- a/include/freetype/ftadvanc.h
+++ b/include/freetype/ftadvanc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Quick computation of advance widths (specification only).            */
 /*                                                                         */
-/*  Copyright 2008-2016 by                                                 */
+/*  Copyright 2008-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftautoh.h b/include/freetype/ftautoh.h
index 48ff1aa..69f07cf 100644
--- a/include/freetype/ftautoh.h
+++ b/include/freetype/ftautoh.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for controlling the auto-hinter (specification only).   */
 /*                                                                         */
-/*  Copyright 2012-2016 by                                                 */
+/*  Copyright 2012-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftbbox.h b/include/freetype/ftbbox.h
index 2a4d214..f03bdc1 100644
--- a/include/freetype/ftbbox.h
+++ b/include/freetype/ftbbox.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType exact bbox computation (specification).                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftbdf.h b/include/freetype/ftbdf.h
index 016dba0..3d3106b 100644
--- a/include/freetype/ftbdf.h
+++ b/include/freetype/ftbdf.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing BDF-specific strings (specification).     */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftbitmap.h b/include/freetype/ftbitmap.h
index 0eac7b9..04b2402 100644
--- a/include/freetype/ftbitmap.h
+++ b/include/freetype/ftbitmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility functions for bitmaps (specification).              */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftbzip2.h b/include/freetype/ftbzip2.h
index b7f2eee..9147a79 100644
--- a/include/freetype/ftbzip2.h
+++ b/include/freetype/ftbzip2.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Bzip2-compressed stream support.                                     */
 /*                                                                         */
-/*  Copyright 2010-2016 by                                                 */
+/*  Copyright 2010-2017 by                                                 */
 /*  Joel Klinghed.                                                         */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftcache.h b/include/freetype/ftcache.h
index 883c88d..5ff3ccf 100644
--- a/include/freetype/ftcache.h
+++ b/include/freetype/ftcache.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType Cache subsystem (specification).                            */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftcffdrv.h b/include/freetype/ftcffdrv.h
index 8f88cc4..35758f8 100644
--- a/include/freetype/ftcffdrv.h
+++ b/include/freetype/ftcffdrv.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for controlling the CFF driver (specification only).    */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftchapters.h b/include/freetype/ftchapters.h
index ab43895..a0a121b 100644
--- a/include/freetype/ftchapters.h
+++ b/include/freetype/ftchapters.h
@@ -77,6 +77,7 @@
 /*    auto_hinter                                                          */
 /*    cff_driver                                                           */
 /*    tt_driver                                                            */
+/*    pcf_driver                                                           */
 /*                                                                         */
 /***************************************************************************/
 
diff --git a/include/freetype/ftcid.h b/include/freetype/ftcid.h
index e1bc9fe..4adcbee 100644
--- a/include/freetype/ftcid.h
+++ b/include/freetype/ftcid.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing CID font information (specification).     */
 /*                                                                         */
-/*  Copyright 2007-2016 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  Dereg Clegg and Michael Toftdal.                                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h
index 3f53dd5..232dccd 100644
--- a/include/freetype/fterrdef.h
+++ b/include/freetype/fterrdef.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType error codes (specification).                                */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/fterrors.h b/include/freetype/fterrors.h
index e15bfb0..021989d 100644
--- a/include/freetype/fterrors.h
+++ b/include/freetype/fterrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType error code handling (specification).                        */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftfntfmt.h b/include/freetype/ftfntfmt.h
index bd42324..3377583 100644
--- a/include/freetype/ftfntfmt.h
+++ b/include/freetype/ftfntfmt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Support functions for font formats.                                  */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftgasp.h b/include/freetype/ftgasp.h
index 3f5b3bc..ce18d64 100644
--- a/include/freetype/ftgasp.h
+++ b/include/freetype/ftgasp.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Access of TrueType's `gasp' table (specification).                   */
 /*                                                                         */
-/*  Copyright 2007-2016 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -92,8 +92,8 @@
 #define FT_GASP_NO_TABLE               -1
 #define FT_GASP_DO_GRIDFIT           0x01
 #define FT_GASP_DO_GRAY              0x02
+#define FT_GASP_SYMMETRIC_GRIDFIT    0x04
 #define FT_GASP_SYMMETRIC_SMOOTHING  0x08
-#define FT_GASP_SYMMETRIC_GRIDFIT    0x10
 
 
   /*************************************************************************
@@ -102,17 +102,25 @@
    *   FT_Get_Gasp
    *
    * @description:
-   *   Read the `gasp' table from a TrueType or OpenType font file and
-   *   return the entry corresponding to a given character pixel size.
+   *   For a TrueType or OpenType font file, return the rasterizer behaviour
+   *   flags from the font's `gasp' table corresponding to a given
+   *   character pixel size.
    *
    * @input:
    *   face :: The source face handle.
+   *
    *   ppem :: The vertical character pixel size.
    *
    * @return:
    *   Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no
    *   `gasp' table in the face.
    *
+   * @note:
+   *   If you want to use the MM functionality of OpenType variation fonts
+   *   (i.e., using @FT_Set_Var_Design_Coordinates and friends), call this
+   *   function *after* setting an instance since the return values can
+   *   change.
+   *
    * @since:
    *   2.3.0
    */
diff --git a/include/freetype/ftglyph.h b/include/freetype/ftglyph.h
index d9840a8..79879a7 100644
--- a/include/freetype/ftglyph.h
+++ b/include/freetype/ftglyph.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType convenience functions to handle glyphs (specification).     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -453,7 +453,7 @@
   /*                                                                       */
   /*                                                                       */
   /*        // load glyph                                                  */
-  /*        error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT );     */
+  /*        error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAULT );    */
   /*                                                                       */
   /*        // extract glyph image                                         */
   /*        error = FT_Get_Glyph( face->glyph, &glyph );                   */
diff --git a/include/freetype/ftgxval.h b/include/freetype/ftgxval.h
index a58e86a..f239c71 100644
--- a/include/freetype/ftgxval.h
+++ b/include/freetype/ftgxval.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for validating TrueTypeGX/AAT tables (specification).   */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  Masatake YAMATO, Redhat K.K,                                           */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
diff --git a/include/freetype/ftgzip.h b/include/freetype/ftgzip.h
index 3932ce6..bd5ceaa 100644
--- a/include/freetype/ftgzip.h
+++ b/include/freetype/ftgzip.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Gzip-compressed stream support.                                      */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h
index 4f86c56..e21a220 100644
--- a/include/freetype/ftimage.h
+++ b/include/freetype/ftimage.h
@@ -5,7 +5,7 @@
 /*    FreeType glyph image formats and default raster interface            */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -1180,6 +1180,7 @@
   typedef struct  FT_Raster_Funcs_
   {
     FT_Glyph_Format        glyph_format;
+
     FT_Raster_NewFunc      raster_new;
     FT_Raster_ResetFunc    raster_reset;
     FT_Raster_SetModeFunc  raster_set_mode;
diff --git a/include/freetype/ftincrem.h b/include/freetype/ftincrem.h
index 46b58b7..f6ae2ba 100644
--- a/include/freetype/ftincrem.h
+++ b/include/freetype/ftincrem.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType incremental loading (specification).                        */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftlcdfil.h b/include/freetype/ftlcdfil.h
index e06a895..928bb0f 100644
--- a/include/freetype/ftlcdfil.h
+++ b/include/freetype/ftlcdfil.h
@@ -5,7 +5,7 @@
 /*    FreeType API for color filtering of subpixel bitmap glyphs           */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftlist.h b/include/freetype/ftlist.h
index 82f437a..5309cb1 100644
--- a/include/freetype/ftlist.h
+++ b/include/freetype/ftlist.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Generic list support for FreeType (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftlzw.h b/include/freetype/ftlzw.h
index 582e2c1..a82c95e 100644
--- a/include/freetype/ftlzw.h
+++ b/include/freetype/ftlzw.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    LZW-compressed stream support.                                       */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftmac.h b/include/freetype/ftmac.h
index adb15ca..ad97c6e 100644
--- a/include/freetype/ftmac.h
+++ b/include/freetype/ftmac.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Additional Mac-specific API.                                         */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftmm.h b/include/freetype/ftmm.h
index b5d6858..96dd625 100644
--- a/include/freetype/ftmm.h
+++ b/include/freetype/ftmm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType Multiple Master font interface (specification).             */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -43,11 +43,10 @@
   /*    Master fonts, i.e., the selection of specific design instances by  */
   /*    setting design axis coordinates.                                   */
   /*                                                                       */
-  /*    George Williams has extended this interface to make it work with   */
-  /*    both Type~1 Multiple Masters fonts and GX distortable (var)        */
-  /*    fonts.  Some of these routines only work with MM fonts, others     */
-  /*    will work with both types.  They are similar enough that a         */
-  /*    consistent interface makes sense.                                  */
+  /*    Besides Adobe MM fonts, the interface supports Apple's TrueType GX */
+  /*    and OpenType variation fonts.  Some of the routines only work with */
+  /*    Adobe MM fonts, others will work with all three types.  They are   */
+  /*    similar enough that a consistent interface makes sense.            */
   /*                                                                       */
   /*************************************************************************/
 
@@ -58,10 +57,11 @@
   /*    FT_MM_Axis                                                         */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A simple structure used to model a given axis in design space for  */
-  /*    Multiple Masters fonts.                                            */
+  /*    A structure to model a given axis in design space for Multiple     */
+  /*    Masters fonts.                                                     */
   /*                                                                       */
-  /*    This structure can't be used for GX var fonts.                     */
+  /*    This structure can't be used for TrueType GX or OpenType variation */
+  /*    fonts.                                                             */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    name    :: The axis's name.                                        */
@@ -85,10 +85,11 @@
   /*    FT_Multi_Master                                                    */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model the axes and space of a Multiple Masters */
+  /*    A structure to model the axes and space of a Multiple Masters      */
   /*    font.                                                              */
   /*                                                                       */
-  /*    This structure can't be used for GX var fonts.                     */
+  /*    This structure can't be used for TrueType GX or OpenType variation */
+  /*    fonts.                                                             */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    num_axis    :: Number of axes.  Cannot exceed~4.                   */
@@ -115,27 +116,35 @@
   /*    FT_Var_Axis                                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A simple structure used to model a given axis in design space for  */
-  /*    Multiple Masters and GX var fonts.                                 */
+  /*    A structure to model a given axis in design space for Multiple     */
+  /*    Masters, TrueType GX, and OpenType variation fonts.                */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    name    :: The axis's name.                                        */
-  /*               Not always meaningful for GX.                           */
+  /*               Not always meaningful for TrueType GX or OpenType       */
+  /*               variation fonts.                                        */
   /*                                                                       */
   /*    minimum :: The axis's minimum design coordinate.                   */
   /*                                                                       */
   /*    def     :: The axis's default design coordinate.                   */
-  /*               FreeType computes meaningful default values for MM; it  */
-  /*               is then an integer value, not in 16.16 format.          */
+  /*               FreeType computes meaningful default values for Adobe   */
+  /*               MM fonts.                                               */
   /*                                                                       */
   /*    maximum :: The axis's maximum design coordinate.                   */
   /*                                                                       */
-  /*    tag     :: The axis's tag (the GX equivalent to `name').           */
-  /*               FreeType provides default values for MM if possible.    */
+  /*    tag     :: The axis's tag (the equivalent to `name' for TrueType   */
+  /*               GX and OpenType variation fonts).  FreeType provides    */
+  /*               default values for Adobe MM fonts if possible.          */
   /*                                                                       */
-  /*    strid   :: The entry in `name' table (another GX version of        */
-  /*               `name').                                                */
-  /*               Not meaningful for MM.                                  */
+  /*    strid   :: The axis name entry in the font's `name' table.  This   */
+  /*               is another (and often better) version of the `name'     */
+  /*               field for TrueType GX or OpenType variation fonts.  Not */
+  /*               meaningful for Adobe MM fonts.                          */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The fields `minimum', `def', and `maximum' are 16.16 fractional    */
+  /*    values for TrueType GX and OpenType variation fonts.  For Adobe MM */
+  /*    fonts, the values are integers.                                    */
   /*                                                                       */
   typedef struct  FT_Var_Axis_
   {
@@ -157,9 +166,10 @@
   /*    FT_Var_Named_Style                                                 */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A simple structure used to model a named style in a GX var font.   */
+  /*    A structure to model a named style in a TrueType GX or OpenType    */
+  /*    variation font.                                                    */
   /*                                                                       */
-  /*    This structure can't be used for MM fonts.                         */
+  /*    This structure can't be used for Adobe MM fonts.                   */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    coords :: The design coordinates for this style.                   */
@@ -167,10 +177,14 @@
   /*                                                                       */
   /*    strid  :: The entry in `name' table identifying this style.        */
   /*                                                                       */
+  /*    psid   :: The entry in `name' table identifying a PostScript name  */
+  /*              for this style.                                          */
+  /*                                                                       */
   typedef struct  FT_Var_Named_Style_
   {
     FT_Fixed*  coords;
     FT_UInt    strid;
+    FT_UInt    psid;   /* since 2.7.1 */
 
   } FT_Var_Named_Style;
 
@@ -181,17 +195,19 @@
   /*    FT_MM_Var                                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model the axes and space of a Multiple Masters */
-  /*    or GX var distortable font.                                        */
+  /*    A structure to model the axes and space of a Adobe MM, TrueType    */
+  /*    GX, or OpenType variation font.                                    */
   /*                                                                       */
-  /*    Some fields are specific to one format and not to the other.       */
+  /*    Some fields are specific to one format and not to the others.      */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    num_axis        :: The number of axes.  The maximum value is~4 for */
-  /*                       MM; no limit in GX.                             */
+  /*                       Adobe MM fonts; no limit in TrueType GX or      */
+  /*                       OpenType variation fonts.                       */
   /*                                                                       */
   /*    num_designs     :: The number of designs; should be normally       */
-  /*                       2^num_axis for MM fonts.  Not meaningful for GX */
+  /*                       2^num_axis for Adobe MM fonts.  Not meaningful  */
+  /*                       for TrueType GX or OpenType variation fonts     */
   /*                       (where every glyph could have a different       */
   /*                       number of designs).                             */
   /*                                                                       */
@@ -201,19 +217,20 @@
   /*                       The font can tell the user that, for example,   */
   /*                       [Weight=1.5,Width=1.1] is `Bold'.               */
   /*                                                                       */
-  /*                       For Type 1 Multiple Masters fonts, this value   */
-  /*                       is always zero because the format does not      */
-  /*                       support named styles.                           */
+  /*                       For Adobe Multiple Masters fonts, this value is */
+  /*                       always zero because the format does not support */
+  /*                       named styles.                                   */
   /*                                                                       */
   /*    axis            :: An axis descriptor table.                       */
-  /*                       GX fonts contain slightly more data than MM.    */
+  /*                       TrueType GX and OpenType variation fonts        */
+  /*                       contain slightly more data than Adobe MM fonts. */
   /*                       Memory management of this pointer is done       */
   /*                       internally by FreeType.                         */
   /*                                                                       */
   /*    namedstyle      :: A named style table.                            */
-  /*                       Only meaningful with GX.                        */
-  /*                       Memory management of this pointer is done       */
-  /*                       internally by FreeType.                         */
+  /*                       Only meaningful for TrueType GX and OpenType    */
+  /*                       variation fonts.  Memory management of this     */
+  /*                       pointer is done internally by FreeType.         */
   /*                                                                       */
   typedef struct  FT_MM_Var_
   {
@@ -232,9 +249,10 @@
   /*    FT_Get_Multi_Master                                                */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Retrieve the Multiple Master descriptor of a given font.           */
+  /*    Retrieve a variation descriptor of a given Adobe MM font.          */
   /*                                                                       */
-  /*    This function can't be used with GX fonts.                         */
+  /*    This function can't be used with TrueType GX or OpenType variation */
+  /*    fonts.                                                             */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face    :: A handle to the source face.                            */
@@ -256,13 +274,15 @@
   /*    FT_Get_MM_Var                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Retrieve the Multiple Master/GX var descriptor of a given font.    */
+  /*    Retrieve a variation descriptor for a given font.                  */
+  /*                                                                       */
+  /*    This function works with all supported variation formats.          */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face    :: A handle to the source face.                            */
   /*                                                                       */
   /* <Output>                                                              */
-  /*    amaster :: The Multiple Masters/GX var descriptor.                 */
+  /*    amaster :: The variation descriptor.                               */
   /*               Allocates a data structure, which the user must         */
   /*               deallocate with `free' after use.                       */
   /*                                                                       */
@@ -280,10 +300,11 @@
   /*    FT_Set_MM_Design_Coordinates                                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    For Multiple Masters fonts, choose an interpolated font design     */
-  /*    through design coordinates.                                        */
+  /*    For Adobe MM fonts, choose an interpolated font design through     */
+  /*    design coordinates.                                                */
   /*                                                                       */
-  /*    This function can't be used with GX fonts.                         */
+  /*    This function can't be used with TrueType GX or OpenType variation */
+  /*    fonts.                                                             */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face       :: A handle to the source face.                         */
@@ -311,8 +332,9 @@
   /*    FT_Set_Var_Design_Coordinates                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    For Multiple Master or GX Var fonts, choose an interpolated font   */
-  /*    design through design coordinates.                                 */
+  /*    Choose an interpolated font design through design coordinates.     */
+  /*                                                                       */
+  /*    This function works with all supported variation formats.          */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face       :: A handle to the source face.                         */
@@ -337,11 +359,43 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Get_Var_Design_Coordinates                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Get the design coordinates of the currently selected interpolated  */
+  /*    font.                                                              */
+  /*                                                                       */
+  /*    This function works with all supported variation formats.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face       :: A handle to the source face.                         */
+  /*                                                                       */
+  /*    num_coords :: The number of design coordinates to retrieve.  If it */
+  /*                  is larger than the number of axes, set the excess    */
+  /*                  values to~0.                                         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    coords     :: The design coordinates array.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Get_Var_Design_Coordinates( FT_Face    face,
+                                 FT_UInt    num_coords,
+                                 FT_Fixed*  coords );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Set_MM_Blend_Coordinates                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    For Multiple Masters and GX var fonts, choose an interpolated font */
-  /*    design through normalized blend coordinates.                       */
+  /*    Choose an interpolated font design through normalized blend        */
+  /*    coordinates.                                                       */
+  /*                                                                       */
+  /*    This function works with all supported variation formats.          */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face       :: A handle to the source face.                         */
@@ -353,7 +407,9 @@
   /*                  use default values for the remaining axes.           */
   /*                                                                       */
   /*    coords     :: The design coordinates array (each element must be   */
-  /*                  between 0 and 1.0).                                  */
+  /*                  between 0 and 1.0 for Adobe MM fonts, and between    */
+  /*                  -1.0 and 1.0 for TrueType GX and OpenType variation  */
+  /*                  fonts).                                              */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0~means success.                             */
@@ -367,6 +423,37 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Get_MM_Blend_Coordinates                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Get the normalized blend coordinates of the currently selected     */
+  /*    interpolated font.                                                 */
+  /*                                                                       */
+  /*    This function works with all supported variation formats.          */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face       :: A handle to the source face.                         */
+  /*                                                                       */
+  /*    num_coords :: The number of normalized blend coordinates to        */
+  /*                  retrieve.  If it is larger than the number of axes,  */
+  /*                  set the excess values to~0.5 for Adobe MM fonts, and */
+  /*                  to~0 for TrueType GX and OpenType variation fonts.   */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    coords     :: The normalized blend coordinates array.              */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Get_MM_Blend_Coordinates( FT_Face    face,
+                               FT_UInt    num_coords,
+                               FT_Fixed*  coords );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Set_Var_Blend_Coordinates                                       */
   /*                                                                       */
   /* <Description>                                                         */
@@ -377,6 +464,20 @@
                                 FT_UInt    num_coords,
                                 FT_Fixed*  coords );
 
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Var_Blend_Coordinates                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This is another name of @FT_Get_MM_Blend_Coordinates.              */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Get_Var_Blend_Coordinates( FT_Face    face,
+                                FT_UInt    num_coords,
+                                FT_Fixed*  coords );
+
   /* */
 
 
diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h
index b4d2758..4147aad 100644
--- a/include/freetype/ftmodapi.h
+++ b/include/freetype/ftmodapi.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType modules public interface (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -89,6 +89,7 @@
   /*                                                                       */
   /*    FT_Property_Set                                                    */
   /*    FT_Property_Get                                                    */
+  /*    FT_Set_Default_Properties                                          */
   /*                                                                       */
   /*    FT_New_Library                                                     */
   /*    FT_Done_Library                                                    */
@@ -440,6 +441,47 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    FT_Set_Default_Properties                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is   */
+  /*    set, this function reads the `FREETYPE_PROPERTIES' environment     */
+  /*    variable to control driver properties.  See sections @auto_hinter, */
+  /*    @cff_driver, @pcf_driver, and @tt_driver for more.                 */
+  /*                                                                       */
+  /*    If the compilation option is not set, this function does nothing.  */
+  /*                                                                       */
+  /*    `FREETYPE_PROPERTIES' has the following syntax form (broken here   */
+  /*    into multiple lines for better readability).                       */
+  /*                                                                       */
+  /*    {                                                                  */
+  /*      <optional whitespace>                                            */
+  /*      <module-name1> ':'                                               */
+  /*      <property-name1> '=' <property-value1>                           */
+  /*      <whitespace>                                                     */
+  /*      <module-name2> ':'                                               */
+  /*      <property-name2> '=' <property-value2>                           */
+  /*      ...                                                              */
+  /*    }                                                                  */
+  /*                                                                       */
+  /*    Example:                                                           */
+  /*                                                                       */
+  /*    {                                                                  */
+  /*      FREETYPE_PROPERTIES=truetype:interpreter-version=35 \            */
+  /*                          cff:no-stem-darkening=1 \                    */
+  /*                          autofitter:warping=1                         */
+  /*    }                                                                  */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    library :: A handle to a new library object.                       */
+  /*                                                                       */
+  FT_EXPORT( void )
+  FT_Set_Default_Properties( FT_Library  library );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    FT_Reference_Library                                               */
   /*                                                                       */
   /* <Description>                                                         */
@@ -477,8 +519,9 @@
   /*    valid for the life of the @FT_Library object.                      */
   /*                                                                       */
   /*    Normally, you would call this function (followed by a call to      */
-  /*    @FT_Add_Default_Modules or a series of calls to @FT_Add_Module)    */
-  /*    instead of @FT_Init_FreeType to initialize the FreeType library.   */
+  /*    @FT_Add_Default_Modules or a series of calls to @FT_Add_Module,    */
+  /*    and a call to @FT_Set_Default_Properties) instead of               */
+  /*    @FT_Init_FreeType to initialize the FreeType library.              */
   /*                                                                       */
   /*    Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a      */
   /*    library instance.                                                  */
diff --git a/include/freetype/ftmoderr.h b/include/freetype/ftmoderr.h
index 2a7671c..7f60837 100644
--- a/include/freetype/ftmoderr.h
+++ b/include/freetype/ftmoderr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType module error offsets (specification).                       */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftotval.h b/include/freetype/ftotval.h
index 3e6e18d..b5d27cf 100644
--- a/include/freetype/ftotval.h
+++ b/include/freetype/ftotval.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for validating OpenType tables (specification).         */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftoutln.h b/include/freetype/ftoutln.h
index ef66d48..07f73eb 100644
--- a/include/freetype/ftoutln.h
+++ b/include/freetype/ftoutln.h
@@ -5,7 +5,7 @@
 /*    Support for the FT_Outline type used to store glyph shapes of        */
 /*    most scalable font formats (specification).                          */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftpcfdrv.h b/include/freetype/ftpcfdrv.h
new file mode 100644
index 0000000..6622c93
--- /dev/null
+++ b/include/freetype/ftpcfdrv.h
@@ -0,0 +1,105 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftpcfdrv.h                                                             */
+/*                                                                         */
+/*    FreeType API for controlling the PCF driver (specification only).    */
+/*                                                                         */
+/*  Copyright 2017 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 FTPCFDRV_H_
+#define FTPCFDRV_H_
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifdef FREETYPE_H
+#error "freetype.h of FreeType 1 has been loaded!"
+#error "Please fix the directory search order for header files"
+#error "so that freetype.h of FreeType 2 is found first."
+#endif
+
+
+FT_BEGIN_HEADER
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   pcf_driver
+   *
+   * @title:
+   *   The PCF driver
+   *
+   * @abstract:
+   *   Controlling the PCF driver module.
+   *
+   * @description:
+   *   While FreeType's PCF driver doesn't expose API functions by itself,
+   *   it is possible to control its behaviour with @FT_Property_Set and
+   *   @FT_Property_Get.  Right now, there is a single property
+   *   `no-long-family-names' available if FreeType is compiled with
+   *   PCF_CONFIG_OPTION_LONG_FAMILY_NAMES.
+   *
+   *   The PCF driver's module name is `pcf'.
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @property:
+   *   no-long-family-names
+   *
+   * @description:
+   *   If PCF_CONFIG_OPTION_LONG_FAMILY_NAMES is active while compiling
+   *   FreeType, the PCF driver constructs long family names.
+   *
+   *   There are many PCF fonts just called `Fixed' which look completely
+   *   different, and which have nothing to do with each other.  When
+   *   selecting `Fixed' in KDE or Gnome one gets results that appear rather
+   *   random, the style changes often if one changes the size and one
+   *   cannot select some fonts at all.  The improve this situation, the PCF
+   *   module prepends the foundry name (plus a space) to the family name. 
+   *   It also checks whether there are `wide' characters; all put together,
+   *   family names like `Sony Fixed' or `Misc Fixed Wide' are constructed.
+   *
+   *   If `no-long-family-names' is set, this feature gets switched off.
+   *
+   *   {
+   *     FT_Library  library;
+   *     FT_Bool     no_long_family_names = TRUE;
+   *
+   *
+   *     FT_Init_FreeType( &library );
+   *
+   *     FT_Property_Set( library, "pcf",
+   *                               "no-long-family-names",
+   *                               &no_long_family_names );
+   *   }
+   *
+   * @note:
+   *   This property can be used with @FT_Property_Get also.
+   *
+   *   This property can be set via the `FREETYPE_PROPERTIES' environment
+   *   variable (using values 1 and 0 for `on' and `off', respectively).
+   *
+   */
+
+
+FT_END_HEADER
+
+
+#endif /* FTPCFDRV_H_ */
+
+
+/* END */
diff --git a/include/freetype/ftpfr.h b/include/freetype/ftpfr.h
index 2e1bff2..f2a6ae9 100644
--- a/include/freetype/ftpfr.h
+++ b/include/freetype/ftpfr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing PFR-specific data (specification only).   */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftrender.h b/include/freetype/ftrender.h
index 9f7ed9e..9608375 100644
--- a/include/freetype/ftrender.h
+++ b/include/freetype/ftrender.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType renderer modules public interface (specification).          */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -75,6 +75,7 @@
   {
     FT_Long                 glyph_size;
     FT_Glyph_Format         glyph_format;
+
     FT_Glyph_InitFunc       glyph_init;
     FT_Glyph_DoneFunc       glyph_done;
     FT_Glyph_CopyFunc       glyph_copy;
diff --git a/include/freetype/ftsizes.h b/include/freetype/ftsizes.h
index 55e0d5c..2f3958a 100644
--- a/include/freetype/ftsizes.h
+++ b/include/freetype/ftsizes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType size objects management (specification).                    */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftsnames.h b/include/freetype/ftsnames.h
index a7b51c2..ff888b7 100644
--- a/include/freetype/ftsnames.h
+++ b/include/freetype/ftsnames.h
@@ -2,12 +2,12 @@
 /*                                                                         */
 /*  ftsnames.h                                                             */
 /*                                                                         */
-/*    Simple interface to access SFNT name tables (which are used          */
+/*    Simple interface to access SFNT `name' tables (which are used        */
 /*    to hold font names, copyright info, notices, etc.) (specification).  */
 /*                                                                         */
 /*    This is _not_ used to retrieve glyph names!                          */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -49,7 +49,7 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    The TrueType and OpenType specifications allow the inclusion of    */
-  /*    a special `names table' in font files.  This table contains        */
+  /*    a special names table (`name') in font files.  This table contains */
   /*    textual (and internationalized) information regarding the font,    */
   /*    like family name, copyright, version, etc.                         */
   /*                                                                       */
@@ -70,30 +70,37 @@
   /*                                                                       */
   /* <Fields>                                                              */
   /*    platform_id :: The platform ID for `string'.                       */
+  /*                   See @TT_PLATFORM_XXX for possible values.           */
   /*                                                                       */
   /*    encoding_id :: The encoding ID for `string'.                       */
+  /*                   See @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX,               */
+  /*                   @TT_ISO_ID_XXX, @TT_MS_ID_XXX, and @TT_ADOBE_ID_XXX */
+  /*                   for possible values.                                */
   /*                                                                       */
   /*    language_id :: The language ID for `string'.                       */
+  /*                   See @TT_MAC_LANGID_XXX and @TT_MS_LANGID_XXX for    */
+  /*                   possible values.                                    */
+  /*                                                                       */
+  /*                   Registered OpenType values for `language_id' are    */
+  /*                   always smaller than 0x8000; values equal or larger  */
+  /*                   than 0x8000 usually indicate a language tag string  */
+  /*                   (introduced in OpenType version 1.6).  Use function */
+  /*                   @FT_Get_Sfnt_LangTag with `language_id' as its      */
+  /*                   argument to retrieve the associated language tag.   */
   /*                                                                       */
   /*    name_id     :: An identifier for `string'.                         */
+  /*                   See @TT_NAME_ID_XXX for possible values.            */
   /*                                                                       */
   /*    string      :: The `name' string.  Note that its format differs    */
-  /*                   depending on the (platform,encoding) pair.  It can  */
-  /*                   be a Pascal String, a UTF-16 one, etc.              */
-  /*                                                                       */
-  /*                   Generally speaking, the string is not               */
-  /*                   zero-terminated.  Please refer to the TrueType      */
-  /*                   specification for details.                          */
+  /*                   depending on the (platform,encoding) pair, being    */
+  /*                   either a string of bytes (without a terminating     */
+  /*                   NULL byte) or containing UTF-16BE entities.         */
   /*                                                                       */
   /*    string_len  :: The length of `string' in bytes.                    */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    Possible values for `platform_id', `encoding_id', `language_id',   */
-  /*    and `name_id' are given in the file `ttnameid.h'.  For details     */
-  /*    please refer to the TrueType or OpenType specification.            */
-  /*                                                                       */
-  /*    See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX,       */
-  /*    @TT_ISO_ID_XXX, and @TT_MS_ID_XXX.                                 */
+  /*    Please refer to the TrueType or OpenType specification for more    */
+  /*    details.                                                           */
   /*                                                                       */
   typedef struct  FT_SfntName_
   {
@@ -103,7 +110,7 @@
     FT_UShort  name_id;
 
     FT_Byte*   string;      /* this string is *not* null-terminated! */
-    FT_UInt    string_len;  /* in bytes */
+    FT_UInt    string_len;  /* in bytes                              */
 
   } FT_SfntName;
 
@@ -147,47 +154,127 @@
   /*                                                                       */
   /* <Note>                                                                */
   /*    The `string' array returned in the `aname' structure is not        */
-  /*    null-terminated.  The application should deallocate it if it is no */
-  /*    longer in use.                                                     */
+  /*    null-terminated.  Note that you don't have to deallocate `string'  */
+  /*    by yourself; FreeType takes care of it if you call @FT_Done_Face.  */
   /*                                                                       */
   /*    Use @FT_Get_Sfnt_Name_Count to get the total number of available   */
   /*    `name' table entries, then do a loop until you get the right       */
   /*    platform, encoding, and name ID.                                   */
   /*                                                                       */
+  /*    `name' table format~1 entries can use language tags also, see      */
+  /*    @FT_Get_Sfnt_LangTag.                                              */
+  /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Get_Sfnt_Name( FT_Face       face,
                     FT_UInt       idx,
                     FT_SfntName  *aname );
 
 
-  /***************************************************************************
-   *
-   * @constant:
-   *   FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY
-   *
-   * @description:
-   *   A constant used as the tag of @FT_Parameter structures to make
-   *   FT_Open_Face() ignore preferred family subfamily names in `name'
-   *   table since OpenType version 1.4.  For backwards compatibility with
-   *   legacy systems that have a 4-face-per-family restriction.
-   *
-   */
-#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY  FT_MAKE_TAG( 'i', 'g', 'p', 'f' )
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_SfntLangTag                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure to model a language tag entry from an SFNT `name'      */
+  /*    table.                                                             */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    string      :: The language tag string, encoded in UTF-16BE        */
+  /*                   (without trailing NULL bytes).                      */
+  /*                                                                       */
+  /*    string_len  :: The length of `string' in *bytes*.                  */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    Please refer to the TrueType or OpenType specification for more    */
+  /*    details.                                                           */
+  /*                                                                       */
+  typedef struct  FT_SfntLangTag_
+  {
+    FT_Byte*  string;      /* this string is *not* null-terminated! */
+    FT_UInt   string_len;  /* in bytes                              */
+
+  } FT_SfntLangTag;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Get_Sfnt_LangTag                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Retrieve the language tag associated with a language ID of an SFNT */
+  /*    `name' table entry.                                                */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face     :: A handle to the source face.                           */
+  /*                                                                       */
+  /*    langID   :: The language ID, as returned by @FT_Get_Sfnt_Name.     */
+  /*                This is always a value larger than 0x8000.             */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    alangTag :: The language tag associated with the `name' table      */
+  /*                entry's language ID.                                   */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The `string' array returned in the `alangTag' structure is not     */
+  /*    null-terminated.  Note that you don't have to deallocate `string'  */
+  /*    by yourself; FreeType takes care of it if you call @FT_Done_Face.  */
+  /*                                                                       */
+  /*    Only `name' table format~1 supports language tags.  For format~0   */
+  /*    tables, this function always returns FT_Err_Invalid_Table.  For    */
+  /*    invalid format~1 language ID values, FT_Err_Invalid_Argument is    */
+  /*    returned.                                                          */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Get_Sfnt_LangTag( FT_Face          face,
+                       FT_UInt          langID,
+                       FT_SfntLangTag  *alangTag );
 
 
   /***************************************************************************
    *
    * @constant:
-   *   FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY
+   *   FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY
    *
    * @description:
-   *   A constant used as the tag of @FT_Parameter structures to make
-   *   FT_Open_Face() ignore preferred subfamily names in `name' table since
-   *   OpenType version 1.4.  For backwards compatibility with legacy
-   *   systems that have a 4-face-per-family restriction.
+   *   A tag for @FT_Parameter to make @FT_Open_Face ignore typographic
+   *   family names in the `name' table (introduced in OpenType version
+   *   1.4).  Use this for backwards compatibility with legacy systems that
+   *   have a four-faces-per-family restriction.
    *
    */
-#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY  FT_MAKE_TAG( 'i', 'g', 'p', 's' )
+#define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY \
+          FT_MAKE_TAG( 'i', 'g', 'p', 'f' )
+
+
+  /* this constant is deprecated */
+#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY \
+          FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY
+
+
+  /***************************************************************************
+   *
+   * @constant:
+   *   FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY
+   *
+   * @description:
+   *   A tag for @FT_Parameter to make @FT_Open_Face ignore typographic
+   *   subfamily names in the `name' table (introduced in OpenType version
+   *   1.4).  Use this for backwards compatibility with legacy systems that
+   *   have a four-faces-per-family restriction.
+   *
+   */
+#define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY \
+          FT_MAKE_TAG( 'i', 'g', 'p', 's' )
+
+
+  /* this constant is deprecated */
+#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY \
+          FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY
 
   /* */
 
diff --git a/include/freetype/ftstroke.h b/include/freetype/ftstroke.h
index b3b9922..8a86808 100644
--- a/include/freetype/ftstroke.h
+++ b/include/freetype/ftstroke.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType path stroker (specification).                               */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftsynth.h b/include/freetype/ftsynth.h
index fdfcb69..1863fa2 100644
--- a/include/freetype/ftsynth.h
+++ b/include/freetype/ftsynth.h
@@ -5,7 +5,7 @@
 /*    FreeType synthesizing code for emboldening and slanting              */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2000-2016 by                                                 */
+/*  Copyright 2000-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftsystem.h b/include/freetype/ftsystem.h
index a75f958..1aa4762 100644
--- a/include/freetype/ftsystem.h
+++ b/include/freetype/ftsystem.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType low-level system interface definition (specification).      */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/fttrigon.h b/include/freetype/fttrigon.h
index f789b52..89f0350 100644
--- a/include/freetype/fttrigon.h
+++ b/include/freetype/fttrigon.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType trigonometric functions (specification).                    */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftttdrv.h b/include/freetype/ftttdrv.h
index 22186ee..79e3e6e 100644
--- a/include/freetype/ftttdrv.h
+++ b/include/freetype/ftttdrv.h
@@ -5,7 +5,7 @@
 /*    FreeType API for controlling the TrueType driver                     */
 /*    (specification only).                                                */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -138,7 +138,6 @@
    *   interpreter-version
    *
    * @description:
-
    *   Currently, three versions are available, two representing the
    *   bytecode interpreter with subpixel hinting support (old `Infinality'
    *   code and new stripped-down and higher performance `minimal' code) and
diff --git a/include/freetype/fttypes.h b/include/freetype/fttypes.h
index 2673e79..eab8ada 100644
--- a/include/freetype/fttypes.h
+++ b/include/freetype/fttypes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType simple types definitions (specification only).              */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ftwinfnt.h b/include/freetype/ftwinfnt.h
index a1a715b..1eeef6c 100644
--- a/include/freetype/ftwinfnt.h
+++ b/include/freetype/ftwinfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing Windows fnt-specific data.                */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/autohint.h b/include/freetype/internal/autohint.h
index 7ef82b8..bae83e7 100644
--- a/include/freetype/internal/autohint.h
+++ b/include/freetype/internal/autohint.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level `autohint' module-specific interface (specification).     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/ftcalc.h b/include/freetype/internal/ftcalc.h
index 8a884f6..c9ac9d8 100644
--- a/include/freetype/internal/ftcalc.h
+++ b/include/freetype/internal/ftcalc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Arithmetic computations (specification).                             */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/ftdebug.h b/include/freetype/internal/ftdebug.h
index d110457..5dcd2b1 100644
--- a/include/freetype/internal/ftdebug.h
+++ b/include/freetype/internal/ftdebug.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Debugging and logging component (specification).                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/ftdriver.h b/include/freetype/internal/ftdriver.h
index 902f02f..e82fa8d 100644
--- a/include/freetype/internal/ftdriver.h
+++ b/include/freetype/internal/ftdriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType font driver interface (specification).                      */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/ftgloadr.h b/include/freetype/internal/ftgloadr.h
index bebf5db..f41c3df 100644
--- a/include/freetype/internal/ftgloadr.h
+++ b/include/freetype/internal/ftgloadr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph loader (specification).                           */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/ftmemory.h b/include/freetype/internal/ftmemory.h
index fc33b2f..59e5b58 100644
--- a/include/freetype/internal/ftmemory.h
+++ b/include/freetype/internal/ftmemory.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType memory management macros (specification).               */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index 0a9f2d4..772d82c 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private base classes (specification).                   */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -193,6 +193,7 @@
   typedef struct  FT_CMap_ClassRec_
   {
     FT_ULong               size;
+
     FT_CMap_InitFunc       init;
     FT_CMap_DoneFunc       done;
     FT_CMap_CharIndexFunc  char_index;
@@ -530,7 +531,8 @@
 
   FT_BASE( FT_Pointer )
   ft_module_get_service( FT_Module    module,
-                         const char*  service_id );
+                         const char*  service_id,
+                         FT_Bool      global );
 
 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
   FT_BASE( FT_Error )
@@ -874,7 +876,7 @@
 #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
     FT_LcdFilter             lcd_filter;
     FT_Int                   lcd_extra;        /* number of extra pixels */
-    FT_Byte                  lcd_weights[7];   /* filter weights, if any */
+    FT_Byte                  lcd_weights[5];   /* filter weights, if any */
     FT_Bitmap_LcdFilterFunc  lcd_filter_func;  /* filtering callback     */
 #endif
 
diff --git a/include/freetype/internal/ftpic.h b/include/freetype/internal/ftpic.h
index 6d800a0..0d43ed2 100644
--- a/include/freetype/internal/ftpic.h
+++ b/include/freetype/internal/ftpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services (declaration).       */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/ftrfork.h b/include/freetype/internal/ftrfork.h
index b923401..25a44a4 100644
--- a/include/freetype/internal/ftrfork.h
+++ b/include/freetype/internal/ftrfork.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Embedded resource forks accessor (specification).                    */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  Masatake YAMATO and Redhat K.K.                                        */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -43,11 +43,12 @@
 
   typedef struct  FT_RFork_Ref_
   {
-    FT_UShort  res_id;
-    FT_Long    offset;
+    FT_Short  res_id;
+    FT_Long   offset;
 
   } FT_RFork_Ref;
 
+
 #ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
   typedef FT_Error
   (*ft_raccess_guess_func)( FT_Library  library,
diff --git a/include/freetype/internal/ftserv.h b/include/freetype/internal/ftserv.h
index 9189717..71ef9ca 100644
--- a/include/freetype/internal/ftserv.h
+++ b/include/freetype/internal/ftserv.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType services (specification only).                          */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -109,27 +109,27 @@
    */
 #ifdef __cplusplus
 
-#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
-  FT_BEGIN_STMNT                                                   \
-    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );    \
-    FT_Pointer   _tmp_;                                            \
-    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                     \
-                                                                   \
-                                                                   \
-    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
-    *_pptr_ = _tmp_;                                               \
+#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )                  \
+  FT_BEGIN_STMNT                                                      \
+    FT_Module    module = FT_MODULE( FT_FACE( face )->driver );       \
+    FT_Pointer   _tmp_;                                               \
+    FT_Pointer*  _pptr_ = (FT_Pointer*)&(ptr);                        \
+                                                                      \
+                                                                      \
+    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
+    *_pptr_ = _tmp_;                                                  \
   FT_END_STMNT
 
 #else /* !C++ */
 
-#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )               \
-  FT_BEGIN_STMNT                                                   \
-    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );     \
-    FT_Pointer  _tmp_;                                             \
-                                                                   \
-                                                                   \
-    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \
-    ptr   = _tmp_;                                                 \
+#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id )                  \
+  FT_BEGIN_STMNT                                                      \
+    FT_Module   module = FT_MODULE( FT_FACE( face )->driver );        \
+    FT_Pointer  _tmp_;                                                \
+                                                                      \
+                                                                      \
+    _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \
+    ptr   = _tmp_;                                                    \
   FT_END_STMNT
 
 #endif /* !C++ */
@@ -167,6 +167,7 @@
   /*    FT_DEFINE_SERVICEDESCREC5                                          */
   /*    FT_DEFINE_SERVICEDESCREC6                                          */
   /*    FT_DEFINE_SERVICEDESCREC7                                          */
+  /*    FT_DEFINE_SERVICEDESCREC8                                          */
   /*                                                                       */
   /* <Description>                                                         */
   /*    Used to initialize an array of FT_ServiceDescRec structures.       */
@@ -283,6 +284,52 @@
     { NULL, NULL }                                                          \
   };
 
+#define FT_DEFINE_SERVICEDESCREC8( class_,                                  \
+                                   serv_id_1, serv_data_1,                  \
+                                   serv_id_2, serv_data_2,                  \
+                                   serv_id_3, serv_data_3,                  \
+                                   serv_id_4, serv_data_4,                  \
+                                   serv_id_5, serv_data_5,                  \
+                                   serv_id_6, serv_data_6,                  \
+                                   serv_id_7, serv_data_7,                  \
+                                   serv_id_8, serv_data_8 )                 \
+  static const FT_ServiceDescRec  class_[] =                                \
+  {                                                                         \
+    { serv_id_1, serv_data_1 },                                             \
+    { serv_id_2, serv_data_2 },                                             \
+    { serv_id_3, serv_data_3 },                                             \
+    { serv_id_4, serv_data_4 },                                             \
+    { serv_id_5, serv_data_5 },                                             \
+    { serv_id_6, serv_data_6 },                                             \
+    { serv_id_7, serv_data_7 },                                             \
+    { serv_id_8, serv_data_8 },                                             \
+    { NULL, NULL }                                                          \
+  };
+
+#define FT_DEFINE_SERVICEDESCREC9( class_,                                  \
+                                   serv_id_1, serv_data_1,                  \
+                                   serv_id_2, serv_data_2,                  \
+                                   serv_id_3, serv_data_3,                  \
+                                   serv_id_4, serv_data_4,                  \
+                                   serv_id_5, serv_data_5,                  \
+                                   serv_id_6, serv_data_6,                  \
+                                   serv_id_7, serv_data_7,                  \
+                                   serv_id_8, serv_data_8,                  \
+                                   serv_id_9, serv_data_9 )                 \
+  static const FT_ServiceDescRec  class_[] =                                \
+  {                                                                         \
+    { serv_id_1, serv_data_1 },                                             \
+    { serv_id_2, serv_data_2 },                                             \
+    { serv_id_3, serv_data_3 },                                             \
+    { serv_id_4, serv_data_4 },                                             \
+    { serv_id_5, serv_data_5 },                                             \
+    { serv_id_6, serv_data_6 },                                             \
+    { serv_id_7, serv_data_7 },                                             \
+    { serv_id_8, serv_data_8 },                                             \
+    { serv_id_9, serv_data_9 },                                             \
+    { NULL, NULL }                                                          \
+  };
+
 #else /* FT_CONFIG_OPTION_PIC */
 
 #define FT_DEFINE_SERVICEDESCREC1( class_,                                  \
@@ -593,6 +640,121 @@
     return FT_Err_Ok;                                                       \
   }
 
+#define FT_DEFINE_SERVICEDESCREC8( class_,                                  \
+                                   serv_id_1, serv_data_1,                  \
+                                   serv_id_2, serv_data_2,                  \
+                                   serv_id_3, serv_data_3,                  \
+                                   serv_id_4, serv_data_4,                  \
+                                   serv_id_5, serv_data_5,                  \
+                                   serv_id_6, serv_data_6,                  \
+                                   serv_id_7, serv_data_7,                  \
+                                   serv_id_8, serv_data_8 )                 \
+  void                                                                      \
+  FT_Destroy_Class_ ## class_( FT_Library          library,                 \
+                               FT_ServiceDescRec*  clazz )                  \
+  {                                                                         \
+    FT_Memory  memory = library->memory;                                    \
+                                                                            \
+                                                                            \
+    if ( clazz )                                                            \
+      FT_FREE( clazz );                                                     \
+  }                                                                         \
+                                                                            \
+  FT_Error                                                                  \
+  FT_Create_Class_ ## class_( FT_Library           library,                 \
+                              FT_ServiceDescRec**  output_class)            \
+  {                                                                         \
+    FT_ServiceDescRec*  clazz  = NULL;                                      \
+    FT_Error            error;                                              \
+    FT_Memory           memory = library->memory;                           \
+                                                                            \
+                                                                            \
+    if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 9 ) )                         \
+      return error;                                                         \
+                                                                            \
+    clazz[0].serv_id   = serv_id_1;                                         \
+    clazz[0].serv_data = serv_data_1;                                       \
+    clazz[1].serv_id   = serv_id_2;                                         \
+    clazz[1].serv_data = serv_data_2;                                       \
+    clazz[2].serv_id   = serv_id_3;                                         \
+    clazz[2].serv_data = serv_data_3;                                       \
+    clazz[3].serv_id   = serv_id_4;                                         \
+    clazz[3].serv_data = serv_data_4;                                       \
+    clazz[4].serv_id   = serv_id_5;                                         \
+    clazz[4].serv_data = serv_data_5;                                       \
+    clazz[5].serv_id   = serv_id_6;                                         \
+    clazz[5].serv_data = serv_data_6;                                       \
+    clazz[6].serv_id   = serv_id_7;                                         \
+    clazz[6].serv_data = serv_data_7;                                       \
+    clazz[7].serv_id   = serv_id_8;                                         \
+    clazz[7].serv_data = serv_data_8;                                       \
+    clazz[8].serv_id   = NULL;                                              \
+    clazz[8].serv_data = NULL;                                              \
+                                                                            \
+    *output_class = clazz;                                                  \
+                                                                            \
+    return FT_Err_Ok;                                                       \
+  }
+
+#define FT_DEFINE_SERVICEDESCREC9( class_,                                  \
+                                   serv_id_1, serv_data_1,                  \
+                                   serv_id_2, serv_data_2,                  \
+                                   serv_id_3, serv_data_3,                  \
+                                   serv_id_4, serv_data_4,                  \
+                                   serv_id_5, serv_data_5,                  \
+                                   serv_id_6, serv_data_6,                  \
+                                   serv_id_7, serv_data_7,                  \
+                                   serv_id_8, serv_data_8,                  \
+                                   serv_id_9, serv_data_9 )                 \
+  void                                                                      \
+  FT_Destroy_Class_ ## class_( FT_Library          library,                 \
+                               FT_ServiceDescRec*  clazz )                  \
+  {                                                                         \
+    FT_Memory  memory = library->memory;                                    \
+                                                                            \
+                                                                            \
+    if ( clazz )                                                            \
+      FT_FREE( clazz );                                                     \
+  }                                                                         \
+                                                                            \
+  FT_Error                                                                  \
+  FT_Create_Class_ ## class_( FT_Library           library,                 \
+                              FT_ServiceDescRec**  output_class)            \
+  {                                                                         \
+    FT_ServiceDescRec*  clazz  = NULL;                                      \
+    FT_Error            error;                                              \
+    FT_Memory           memory = library->memory;                           \
+                                                                            \
+                                                                            \
+    if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 10 ) )                        \
+      return error;                                                         \
+                                                                            \
+    clazz[0].serv_id   = serv_id_1;                                         \
+    clazz[0].serv_data = serv_data_1;                                       \
+    clazz[1].serv_id   = serv_id_2;                                         \
+    clazz[1].serv_data = serv_data_2;                                       \
+    clazz[2].serv_id   = serv_id_3;                                         \
+    clazz[2].serv_data = serv_data_3;                                       \
+    clazz[3].serv_id   = serv_id_4;                                         \
+    clazz[3].serv_data = serv_data_4;                                       \
+    clazz[4].serv_id   = serv_id_5;                                         \
+    clazz[4].serv_data = serv_data_5;                                       \
+    clazz[5].serv_id   = serv_id_6;                                         \
+    clazz[5].serv_data = serv_data_6;                                       \
+    clazz[6].serv_id   = serv_id_7;                                         \
+    clazz[6].serv_data = serv_data_7;                                       \
+    clazz[7].serv_id   = serv_id_8;                                         \
+    clazz[7].serv_data = serv_data_8;                                       \
+    clazz[8].serv_id   = serv_id_9;                                         \
+    clazz[8].serv_data = serv_data_9;                                       \
+    clazz[9].serv_id   = NULL;                                              \
+    clazz[9].serv_data = NULL;                                              \
+                                                                            \
+    *output_class = clazz;                                                  \
+                                                                            \
+    return FT_Err_Ok;                                                       \
+  }
+
 #endif /* FT_CONFIG_OPTION_PIC */
 
 
@@ -635,6 +797,7 @@
   {
     FT_Pointer  service_POSTSCRIPT_FONT_NAME;
     FT_Pointer  service_MULTI_MASTERS;
+    FT_Pointer  service_METRICS_VARIATIONS;
     FT_Pointer  service_GLYPH_DICT;
     FT_Pointer  service_PFR_METRICS;
     FT_Pointer  service_WINFNT;
@@ -655,7 +818,7 @@
    *   FT_FACE_LOOKUP_SERVICE
    *
    * @description:
-   *   This macro is used to lookup a service from a face's driver module
+   *   This macro is used to look up a service from a face's driver module
    *   using its cache.
    *
    * @input:
@@ -739,6 +902,7 @@
 #define FT_SERVICE_GLYPH_DICT_H         <freetype/internal/services/svgldict.h>
 #define FT_SERVICE_GX_VALIDATE_H        <freetype/internal/services/svgxval.h>
 #define FT_SERVICE_KERNING_H            <freetype/internal/services/svkern.h>
+#define FT_SERVICE_METRICS_VARIATIONS_H <freetype/internal/services/svmetric.h>
 #define FT_SERVICE_MULTIPLE_MASTERS_H   <freetype/internal/services/svmm.h>
 #define FT_SERVICE_OPENTYPE_VALIDATE_H  <freetype/internal/services/svotval.h>
 #define FT_SERVICE_PFR_H                <freetype/internal/services/svpfr.h>
diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h
index 6d04875..02b2f0b 100644
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Stream handling (specification).                                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index efb3355..caf5fc9 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Tracing handling (specification only).                               */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/ftvalid.h b/include/freetype/internal/ftvalid.h
index aac92c9..df6f7c5 100644
--- a/include/freetype/internal/ftvalid.h
+++ b/include/freetype/internal/ftvalid.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType validation support (specification).                         */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h
index 8c3c14c..0204681 100644
--- a/include/freetype/internal/internal.h
+++ b/include/freetype/internal/internal.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Internal header files (specification only).                          */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index 15dedfd..286d604 100644
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -5,7 +5,7 @@
 /*    Auxiliary functions and data structures related to PostScript fonts  */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/pshints.h b/include/freetype/internal/pshints.h
index e60dc9c..49116eb 100644
--- a/include/freetype/internal/pshints.h
+++ b/include/freetype/internal/pshints.h
@@ -6,7 +6,7 @@
 /*    recorders (specification only).  These are used to support native    */
 /*    T1/T2 hints in the `type1', `cid', and `cff' font drivers.           */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svbdf.h b/include/freetype/internal/services/svbdf.h
index c24475f..eeebf67 100644
--- a/include/freetype/internal/services/svbdf.h
+++ b/include/freetype/internal/services/svbdf.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType BDF services (specification).                           */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svcid.h b/include/freetype/internal/services/svcid.h
index dbbe604..cce94d8 100644
--- a/include/freetype/internal/services/svcid.h
+++ b/include/freetype/internal/services/svcid.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType CID font services (specification).                      */
 /*                                                                         */
-/*  Copyright 2007-2016 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  Derek Clegg and Michael Toftdal.                                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svfntfmt.h b/include/freetype/internal/services/svfntfmt.h
index bd295c9..376d925 100644
--- a/include/freetype/internal/services/svfntfmt.h
+++ b/include/freetype/internal/services/svfntfmt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType font format service (specification only).               */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svgldict.h b/include/freetype/internal/services/svgldict.h
index fff29bc..0cd1361 100644
--- a/include/freetype/internal/services/svgldict.h
+++ b/include/freetype/internal/services/svgldict.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph dictionary services (specification).              */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svgxval.h b/include/freetype/internal/services/svgxval.h
index fb8ffba..71bfa97 100644
--- a/include/freetype/internal/services/svgxval.h
+++ b/include/freetype/internal/services/svgxval.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for validating TrueTypeGX/AAT tables (specification).   */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  Masatake YAMATO, Red Hat K.K.,                                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
diff --git a/include/freetype/internal/services/svkern.h b/include/freetype/internal/services/svkern.h
index a636f1a..b8344e9 100644
--- a/include/freetype/internal/services/svkern.h
+++ b/include/freetype/internal/services/svkern.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType Kerning service (specification).                        */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svmetric.h b/include/freetype/internal/services/svmetric.h
new file mode 100644
index 0000000..1f7d5dd
--- /dev/null
+++ b/include/freetype/internal/services/svmetric.h
@@ -0,0 +1,153 @@
+/***************************************************************************/
+/*                                                                         */
+/*  svmetric.h                                                             */
+/*                                                                         */
+/*    The FreeType services for metrics variations (specification).        */
+/*                                                                         */
+/*  Copyright 2016-2017 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 SVMETRIC_H_
+#define SVMETRIC_H_
+
+#include FT_INTERNAL_SERVICE_H
+
+
+FT_BEGIN_HEADER
+
+
+  /*
+   *  A service to manage the `HVAR, `MVAR', and `VVAR' OpenType tables.
+   *
+   */
+
+#define FT_SERVICE_ID_METRICS_VARIATIONS  "metrics-variations"
+
+
+  /* HVAR */
+
+  typedef FT_Error
+  (*FT_HAdvance_Adjust_Func)( FT_Face  face,
+                              FT_UInt  gindex,
+                              FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_LSB_Adjust_Func)( FT_Face  face,
+                         FT_UInt  gindex,
+                         FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_RSB_Adjust_Func)( FT_Face  face,
+                         FT_UInt  gindex,
+                         FT_Int  *avalue );
+
+  /* VVAR */
+
+  typedef FT_Error
+  (*FT_VAdvance_Adjust_Func)( FT_Face  face,
+                              FT_UInt  gindex,
+                              FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_TSB_Adjust_Func)( FT_Face  face,
+                         FT_UInt  gindex,
+                         FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_BSB_Adjust_Func)( FT_Face  face,
+                         FT_UInt  gindex,
+                         FT_Int  *avalue );
+
+  typedef FT_Error
+  (*FT_VOrg_Adjust_Func)( FT_Face  face,
+                          FT_UInt  gindex,
+                          FT_Int  *avalue );
+
+  /* MVAR */
+
+  typedef void
+  (*FT_Metrics_Adjust_Func)( FT_Face  face );
+
+
+  FT_DEFINE_SERVICE( MetricsVariations )
+  {
+    FT_HAdvance_Adjust_Func  hadvance_adjust;
+    FT_LSB_Adjust_Func       lsb_adjust;
+    FT_RSB_Adjust_Func       rsb_adjust;
+
+    FT_VAdvance_Adjust_Func  vadvance_adjust;
+    FT_TSB_Adjust_Func       tsb_adjust;
+    FT_BSB_Adjust_Func       bsb_adjust;
+    FT_VOrg_Adjust_Func      vorg_adjust;
+
+    FT_Metrics_Adjust_Func   metrics_adjust;
+  };
+
+
+#ifndef FT_CONFIG_OPTION_PIC
+
+#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_,            \
+                                                hadvance_adjust_,  \
+                                                lsb_adjust_,       \
+                                                rsb_adjust_,       \
+                                                vadvance_adjust_,  \
+                                                tsb_adjust_,       \
+                                                bsb_adjust_,       \
+                                                vorg_adjust_,      \
+                                                metrics_adjust_  ) \
+  static const FT_Service_MetricsVariationsRec  class_ =           \
+  {                                                                \
+    hadvance_adjust_,                                              \
+    lsb_adjust_,                                                   \
+    rsb_adjust_,                                                   \
+    vadvance_adjust_,                                              \
+    tsb_adjust_,                                                   \
+    bsb_adjust_,                                                   \
+    vorg_adjust_,                                                  \
+    metrics_adjust_                                                \
+  };
+
+#else /* FT_CONFIG_OPTION_PIC */
+
+#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_,               \
+                                                hadvance_adjust_,     \
+                                                lsb_adjust_,          \
+                                                rsb_adjust_,          \
+                                                vadvance_adjust_,     \
+                                                tsb_adjust_,          \
+                                                bsb_adjust_,          \
+                                                vorg_adjust_,         \
+                                                metrics_adjust_  )    \
+  void                                                                \
+  FT_Init_Class_ ## class_( FT_Service_MetricsVariationsRec*  clazz ) \
+  {                                                                   \
+    clazz->hadvance_adjust = hadvance_adjust_;                        \
+    clazz->lsb_adjust      = lsb_adjust_;                             \
+    clazz->rsb_adjust      = rsb_adjust_;                             \
+    clazz->vadvance_adjust = vadvance_adjust_;                        \
+    clazz->tsb_adjust      = tsb_adjust_;                             \
+    clazz->bsb_adjust      = bsb_adjust_;                             \
+    clazz->vorg_adjust     = vorg_adjust_;                            \
+    clazz->metrics_adjust  = metrics_adjust_;                         \
+  }
+
+#endif /* FT_CONFIG_OPTION_PIC */
+
+  /* */
+
+
+FT_END_HEADER
+
+#endif /* SVMETRIC_H_ */
+
+
+/* END */
diff --git a/include/freetype/internal/services/svmm.h b/include/freetype/internal/services/svmm.h
index b78a19f..97af1ac 100644
--- a/include/freetype/internal/services/svmm.h
+++ b/include/freetype/internal/services/svmm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType Multiple Masters and GX var services (specification).   */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -58,46 +58,91 @@
                            FT_UInt   num_coords,
                            FT_Long*  coords );
 
+  typedef FT_Error
+  (*FT_Get_Var_Design_Func)( FT_Face    face,
+                             FT_UInt    num_coords,
+                             FT_Fixed*  coords );
+
+  typedef FT_Error
+  (*FT_Get_MM_Blend_Func)( FT_Face   face,
+                           FT_UInt   num_coords,
+                           FT_Long*  coords );
+
+  typedef FT_Error
+  (*FT_Get_Var_Blend_Func)( FT_Face      face,
+                            FT_UInt     *num_coords,
+                            FT_Fixed*   *coords,
+                            FT_MM_Var*  *mm_var );
+
+  typedef void
+  (*FT_Done_Blend_Func)( FT_Face );
+
 
   FT_DEFINE_SERVICE( MultiMasters )
   {
     FT_Get_MM_Func          get_mm;
     FT_Set_MM_Design_Func   set_mm_design;
     FT_Set_MM_Blend_Func    set_mm_blend;
+    FT_Get_MM_Blend_Func    get_mm_blend;
     FT_Get_MM_Var_Func      get_mm_var;
     FT_Set_Var_Design_Func  set_var_design;
+    FT_Get_Var_Design_Func  get_var_design;
+
+    /* for internal use; only needed for code sharing between modules */
+    FT_Get_Var_Blend_Func   get_var_blend;
+    FT_Done_Blend_Func      done_blend;
   };
 
 
 #ifndef FT_CONFIG_OPTION_PIC
 
-#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,                          \
-                                           get_mm_,                         \
-                                           set_mm_design_,                  \
-                                           set_mm_blend_,                   \
-                                           get_mm_var_,                     \
-                                           set_var_design_ )                \
-  static const FT_Service_MultiMastersRec  class_ =                         \
-  {                                                                         \
-    get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_    \
+#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,           \
+                                           get_mm_,          \
+                                           set_mm_design_,   \
+                                           set_mm_blend_,    \
+                                           get_mm_blend_,    \
+                                           get_mm_var_,      \
+                                           set_var_design_,  \
+                                           get_var_design_,  \
+                                           get_var_blend_,   \
+                                           done_blend_     ) \
+  static const FT_Service_MultiMastersRec  class_ =          \
+  {                                                          \
+    get_mm_,                                                 \
+    set_mm_design_,                                          \
+    set_mm_blend_,                                           \
+    get_mm_blend_,                                           \
+    get_mm_var_,                                             \
+    set_var_design_,                                         \
+    get_var_design_,                                         \
+    get_var_blend_,                                          \
+    done_blend_                                              \
   };
 
 #else /* FT_CONFIG_OPTION_PIC */
 
-#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,                          \
-                                           get_mm_,                         \
-                                           set_mm_design_,                  \
-                                           set_mm_blend_,                   \
-                                           get_mm_var_,                     \
-                                           set_var_design_ )                \
-  void                                                                      \
-  FT_Init_Class_ ## class_( FT_Service_MultiMastersRec*  clazz )            \
-  {                                                                         \
-    clazz->get_mm         = get_mm_;                                        \
-    clazz->set_mm_design  = set_mm_design_;                                 \
-    clazz->set_mm_blend   = set_mm_blend_;                                  \
-    clazz->get_mm_var     = get_mm_var_;                                    \
-    clazz->set_var_design = set_var_design_;                                \
+#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,               \
+                                           get_mm_,              \
+                                           set_mm_design_,       \
+                                           set_mm_blend_,        \
+                                           get_mm_blend_,        \
+                                           get_mm_var_,          \
+                                           set_var_design_,      \
+                                           get_var_design_,      \
+                                           get_var_blend_,       \
+                                           done_blend_ )         \
+  void                                                           \
+  FT_Init_Class_ ## class_( FT_Service_MultiMastersRec*  clazz ) \
+  {                                                              \
+    clazz->get_mm         = get_mm_;                             \
+    clazz->set_mm_design  = set_mm_design_;                      \
+    clazz->set_mm_blend   = set_mm_blend_;                       \
+    clazz->get_mm_blend   = get_mm_blend_;                       \
+    clazz->get_mm_var     = get_mm_var_;                         \
+    clazz->set_var_design = set_var_design_;                     \
+    clazz->get_var_design = get_var_design_;                     \
+    clazz->get_var_blend  = get_var_blend_;                      \
+    clazz->done_blend     = done_blend_;                         \
   }
 
 #endif /* FT_CONFIG_OPTION_PIC */
diff --git a/include/freetype/internal/services/svotval.h b/include/freetype/internal/services/svotval.h
index bc929d4..ac84abe 100644
--- a/include/freetype/internal/services/svotval.h
+++ b/include/freetype/internal/services/svotval.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType OpenType validation service (specification).            */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svpfr.h b/include/freetype/internal/services/svpfr.h
index d0f7c4d..c9a182f 100644
--- a/include/freetype/internal/services/svpfr.h
+++ b/include/freetype/internal/services/svpfr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Internal PFR service functions (specification).                      */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svpostnm.h b/include/freetype/internal/services/svpostnm.h
index f124380..022cdec 100644
--- a/include/freetype/internal/services/svpostnm.h
+++ b/include/freetype/internal/services/svpostnm.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript name services (specification).               */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svprop.h b/include/freetype/internal/services/svprop.h
index 75e6244..eb2d4ee 100644
--- a/include/freetype/internal/services/svprop.h
+++ b/include/freetype/internal/services/svprop.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType property service (specification).                       */
 /*                                                                         */
-/*  Copyright 2012-2016 by                                                 */
+/*  Copyright 2012-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svpscmap.h b/include/freetype/internal/services/svpscmap.h
index 9acc216..b32122e 100644
--- a/include/freetype/internal/services/svpscmap.h
+++ b/include/freetype/internal/services/svpscmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript charmap service (specification).             */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svpsinfo.h b/include/freetype/internal/services/svpsinfo.h
index f2c8060..0220ce5 100644
--- a/include/freetype/internal/services/svpsinfo.h
+++ b/include/freetype/internal/services/svpsinfo.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript info service (specification).                */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svsfnt.h b/include/freetype/internal/services/svsfnt.h
index 0f38cf1..49d18e4 100644
--- a/include/freetype/internal/services/svsfnt.h
+++ b/include/freetype/internal/services/svsfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType SFNT table loading service (specification).             */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svttcmap.h b/include/freetype/internal/services/svttcmap.h
index 772c721..30f7fee 100644
--- a/include/freetype/internal/services/svttcmap.h
+++ b/include/freetype/internal/services/svttcmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType TrueType/sfnt cmap extra information service.           */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  Masatake YAMATO, Redhat K.K.,                                          */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
diff --git a/include/freetype/internal/services/svtteng.h b/include/freetype/internal/services/svtteng.h
index c55061a..e4b368a 100644
--- a/include/freetype/internal/services/svtteng.h
+++ b/include/freetype/internal/services/svtteng.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType TrueType engine query service (specification).          */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svttglyf.h b/include/freetype/internal/services/svttglyf.h
index c33edd4..b779305 100644
--- a/include/freetype/internal/services/svttglyf.h
+++ b/include/freetype/internal/services/svttglyf.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType TrueType glyph service.                                 */
 /*                                                                         */
-/*  Copyright 2007-2016 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  David Turner.                                                          */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/services/svwinfnt.h b/include/freetype/internal/services/svwinfnt.h
index c2f6d4c..c94b7e1 100644
--- a/include/freetype/internal/services/svwinfnt.h
+++ b/include/freetype/internal/services/svwinfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType Windows FNT/FONT service (specification).               */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h
index e139315..348b5a9 100644
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level `sfnt' driver interface (specification).                  */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h
index 494c011..b2e35d4 100644
--- a/include/freetype/internal/t1types.h
+++ b/include/freetype/internal/t1types.h
@@ -5,7 +5,7 @@
 /*    Basic Type1/Type2 type definitions and interface (specification      */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h
index 1767132..e779647 100644
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -5,7 +5,7 @@
 /*    Basic SFNT/TrueType type definitions and interface (specification    */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -243,7 +243,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Struct>                                                              */
-  /*    TT_NameEntryRec                                                    */
+  /*    TT_NameRec                                                         */
   /*                                                                       */
   /* <Description>                                                         */
   /*    A structure modeling TrueType name records.  Name records are used */
@@ -267,7 +267,7 @@
   /*    string       :: A pointer to the string's bytes.  Note that these  */
   /*                    are usually UTF-16 encoded characters.             */
   /*                                                                       */
-  typedef struct  TT_NameEntryRec_
+  typedef struct  TT_NameRec_
   {
     FT_UShort  platformID;
     FT_UShort  encodingID;
@@ -279,9 +279,39 @@
     /* this last field is not defined in the spec */
     /* but used by the FreeType engine            */
 
-    FT_Byte*   string;
+    FT_Byte*  string;
 
-  } TT_NameEntryRec, *TT_NameEntry;
+  } TT_NameRec, *TT_Name;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    TT_LangTagRec                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure modeling language tag records in SFNT `name' tables,   */
+  /*    introduced in OpenType version 1.6.                                */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    stringLength :: The length of the string in bytes.                 */
+  /*                                                                       */
+  /*    stringOffset :: The offset to the string in the `name' table.      */
+  /*                                                                       */
+  /*    string       :: A pointer to the string's bytes.  Note that these  */
+  /*                    are UTF-16BE encoded characters.                   */
+  /*                                                                       */
+  typedef struct TT_LangTagRec_
+  {
+    FT_UShort  stringLength;
+    FT_ULong   stringOffset;
+
+    /* this last field is not defined in the spec */
+    /* but used by the FreeType engine            */
+
+    FT_Byte*  string;
+
+  } TT_LangTagRec, *TT_LangTag;
 
 
   /*************************************************************************/
@@ -293,24 +323,30 @@
   /*    A structure modeling the TrueType name table.                      */
   /*                                                                       */
   /* <Fields>                                                              */
-  /*    format         :: The format of the name table.                    */
+  /*    format            :: The format of the name table.                 */
   /*                                                                       */
-  /*    numNameRecords :: The number of names in table.                    */
+  /*    numNameRecords    :: The number of names in table.                 */
   /*                                                                       */
-  /*    storageOffset  :: The offset of the name table in the `name'       */
-  /*                      TrueType table.                                  */
+  /*    storageOffset     :: The offset of the name table in the `name'    */
+  /*                         TrueType table.                               */
   /*                                                                       */
-  /*    names          :: An array of name records.                        */
+  /*    names             :: An array of name records.                     */
   /*                                                                       */
-  /*    stream         :: the file's input stream.                         */
+  /*    numLangTagRecords :: The number of language tags in table.         */
+  /*                                                                       */
+  /*    langTags          :: An array of language tag records.             */
+  /*                                                                       */
+  /*    stream            :: The file's input stream.                      */
   /*                                                                       */
   typedef struct  TT_NameTableRec_
   {
-    FT_UShort         format;
-    FT_UInt           numNameRecords;
-    FT_UInt           storageOffset;
-    TT_NameEntryRec*  names;
-    FT_Stream         stream;
+    FT_UShort       format;
+    FT_UInt         numNameRecords;
+    FT_UInt         storageOffset;
+    TT_NameRec*     names;
+    FT_UInt         numLangTagRecords;
+    TT_LangTagRec*  langTags;
+    FT_Stream       stream;
 
   } TT_NameTableRec, *TT_NameTable;
 
@@ -1060,6 +1096,34 @@
   } TT_SbitTableType;
 
 
+  /* OpenType 1.8 brings new tables for variation font support;  */
+  /* to make the old MM and GX fonts still work we need to check */
+  /* the presence (and validity) of the functionality provided   */
+  /* by those tables.  The following flag macros are for the     */
+  /* field `variation_support'.                                  */
+  /*                                                             */
+  /* Note that `fvar' gets checked immediately at font loading,  */
+  /* while the other features are only loaded if MM support is   */
+  /* actually requested.                                         */
+
+  /* FVAR */
+#define TT_FACE_FLAG_VAR_FVAR  ( 1 << 0 )
+
+  /* HVAR */
+#define TT_FACE_FLAG_VAR_HADVANCE  ( 1 << 1 )
+#define TT_FACE_FLAG_VAR_LSB       ( 1 << 2 )
+#define TT_FACE_FLAG_VAR_RSB       ( 1 << 3 )
+
+  /* VVAR */
+#define TT_FACE_FLAG_VAR_VADVANCE  ( 1 << 4 )
+#define TT_FACE_FLAG_VAR_TSB       ( 1 << 5 )
+#define TT_FACE_FLAG_VAR_BSB       ( 1 << 6 )
+#define TT_FACE_FLAG_VAR_VORG      ( 1 << 7 )
+
+  /* MVAR */
+#define TT_FACE_FLAG_VAR_MVAR  ( 1 << 8 )
+
+
   /*************************************************************************/
   /*                                                                       */
   /*                         TrueType Face Type                            */
@@ -1161,6 +1225,11 @@
   /*                                                                       */
   /*    psnames              :: A pointer to the PostScript names service. */
   /*                                                                       */
+  /*    mm                   :: A pointer to the Multiple Masters service. */
+  /*                                                                       */
+  /*    var                  :: A pointer to the Metrics Variations        */
+  /*                            service.                                   */
+  /*                                                                       */
   /*    hdmx                 :: The face's horizontal device metrics       */
   /*                            (`hdmx' table).  This table is optional in */
   /*                            TrueType/OpenType fonts.                   */
@@ -1182,18 +1251,6 @@
   /*                            file  `ttconfig.h' for comments on the     */
   /*                            TT_CONFIG_OPTION_POSTSCRIPT_NAMES option.  */
   /*                                                                       */
-  /*    num_locations        :: The number of glyph locations in this      */
-  /*                            TrueType file.  This should be             */
-  /*                            identical to the number of glyphs.         */
-  /*                            Ignored for Type 2 fonts.                  */
-  /*                                                                       */
-  /*    glyph_locations      :: An array of longs.  These are offsets to   */
-  /*                            glyph data within the `glyf' table.        */
-  /*                            Ignored for Type 2 font faces.             */
-  /*                                                                       */
-  /*    glyf_len             :: The length of the `glyf' table.  Needed    */
-  /*                            for malformed `loca' tables.               */
-  /*                                                                       */
   /*    font_program_size    :: Size in bytecodes of the face's font       */
   /*                            program.  0 if none defined.  Ignored for  */
   /*                            Type 2 fonts.                              */
@@ -1219,20 +1276,20 @@
   /*                            units.  Comes from the `cvt ' table.       */
   /*                            Ignored for Type 2 fonts.                  */
   /*                                                                       */
-  /*    num_kern_pairs       :: The number of kerning pairs present in the */
-  /*                            font file.  The engine only loads the      */
-  /*                            first horizontal format 0 kern table it    */
-  /*                            finds in the font file.  Ignored for       */
-  /*                            Type 2 fonts.                              */
-  /*                                                                       */
-  /*    kern_table_index     :: The index of the kerning table in the font */
-  /*                            kerning directory.  Ignored for Type 2     */
-  /*                            fonts.                                     */
-  /*                                                                       */
   /*    interpreter          :: A pointer to the TrueType bytecode         */
   /*                            interpreters field is also used to hook    */
   /*                            the debugger in `ttdebug'.                 */
   /*                                                                       */
+  /*    extra                :: Reserved for third-party font drivers.     */
+  /*                                                                       */
+  /*    postscript_name      :: The PS name of the font.  Used by the      */
+  /*                            postscript name service.                   */
+  /*                                                                       */
+  /*    glyf_len             :: The length of the `glyf' table.  Needed    */
+  /*                            for malformed `loca' tables.               */
+  /*                                                                       */
+  /*    glyf_offset          :: The file offset of the `glyf' table.       */
+  /*                                                                       */
   /*    doblend              :: A boolean which is set if the font should  */
   /*                            be blended (this is for GX var).           */
   /*                                                                       */
@@ -1240,10 +1297,89 @@
   /*                            variation tables (rather like Multiple     */
   /*                            Master data).                              */
   /*                                                                       */
-  /*    extra                :: Reserved for third-party font drivers.     */
+  /*    is_default_instance  :: Set if the glyph outlines can be used      */
+  /*                            unmodified (i.e., without applying glyph   */
+  /*                            variation deltas).                         */
   /*                                                                       */
-  /*    postscript_name      :: The PS name of the font.  Used by the      */
-  /*                            postscript name service.                   */
+  /*    variation_support    :: Flags that indicate which OpenType         */
+  /*                            functionality related to font variation    */
+  /*                            support is present, valid, and usable.     */
+  /*                            For example, TT_FACE_FLAG_VAR_FVAR is only */
+  /*                            set if we have at least one design axis.   */
+  /*                                                                       */
+  /*    horz_metrics_size    :: The size of the `hmtx' table.              */
+  /*                                                                       */
+  /*    vert_metrics_size    :: The size of the `vmtx' table.              */
+  /*                                                                       */
+  /*    num_locations        :: The number of glyph locations in this      */
+  /*                            TrueType file.  This should be             */
+  /*                            identical to the number of glyphs.         */
+  /*                            Ignored for Type 2 fonts.                  */
+  /*                                                                       */
+  /*    glyph_locations      :: An array of longs.  These are offsets to   */
+  /*                            glyph data within the `glyf' table.        */
+  /*                            Ignored for Type 2 font faces.             */
+  /*                                                                       */
+  /*    hdmx_table           :: A pointer to the `hdmx' table.             */
+  /*                                                                       */
+  /*    hdmx_table_size      :: The size of the `hdmx' table.              */
+  /*                                                                       */
+  /*    hdmx_record_count    :: The number of hdmx records.                */
+  /*                                                                       */
+  /*    hdmx_record_size     :: The size of a single hdmx record.          */
+  /*                                                                       */
+  /*    hdmx_record_sizes    :: An array holding the ppem sizes available  */
+  /*                            in the `hdmx' table.                       */
+  /*                                                                       */
+  /*    sbit_table           :: A pointer to the font's embedded bitmap    */
+  /*                            location table.                            */
+  /*                                                                       */
+  /*    sbit_table_size      :: The size of `sbit_table'.                  */
+  /*                                                                       */
+  /*    sbit_table_type      :: The sbit table type (CBLC, sbix, etc.).    */
+  /*                                                                       */
+  /*    sbit_num_strikes     :: The number of sbit strikes exposed by      */
+  /*                            FreeType's API, omitting invalid strikes.  */
+  /*                                                                       */
+  /*    sbit_strike_map      :: A mapping between the strike indices       */
+  /*                            exposed by the API and the indices used in */
+  /*                            the font's sbit table.                     */
+  /*                                                                       */
+  /*    kern_table           :: A pointer to the `kern' table.             */
+  /*                                                                       */
+  /*    kern_table_size      :: The size of the `kern' table.              */
+  /*                                                                       */
+  /*    num_kern_tables      :: The number of supported kern subtables     */
+  /*                            (up to 32; FreeType recognizes only        */
+  /*                            horizontal ones with format 0).            */
+  /*                                                                       */
+  /*    kern_avail_bits      :: The availability status of kern subtables; */
+  /*                            if bit n is set, table n is available.     */
+  /*                                                                       */
+  /*    kern_order_bits      :: The sortedness status of kern subtables;   */
+  /*                            if bit n is set, table n is sorted.        */
+  /*                                                                       */
+  /*    bdf                  :: Data related to an SFNT font's `bdf'       */
+  /*                            table; see `tttypes.h'.                    */
+  /*                                                                       */
+  /*    horz_metrics_offset  :: The file offset of the `hmtx' table.       */
+  /*                                                                       */
+  /*    vert_metrics_offset  :: The file offset of the `vmtx' table.       */
+  /*                                                                       */
+  /*    sph_found_func_flags :: Flags identifying special bytecode         */
+  /*                            functions (used by the v38 implementation  */
+  /*                            of the bytecode interpreter).              */
+  /*                                                                       */
+  /*    sph_compatibility_mode ::                                          */
+  /*                            This flag is set if we are in ClearType    */
+  /*                            backwards compatibility mode (used by the  */
+  /*                            v38 implementation of the bytecode         */
+  /*                            interpreter).                              */
+  /*                                                                       */
+  /*    ebdt_start           :: The file offset of the sbit data table     */
+  /*                            (CBDT, bdat, etc.).                        */
+  /*                                                                       */
+  /*    ebdt_size            :: The size of the sbit data table.           */
   /*                                                                       */
   typedef struct  TT_FaceRec_
   {
@@ -1288,6 +1424,16 @@
     /* handle glyph names <-> unicode & Mac values                   */
     void*                 psnames;
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    /* a typeless pointer to the FT_Service_MultiMasters table used to */
+    /* handle variation fonts                                          */
+    void*                 mm;
+
+    /* a typeless pointer to the FT_Service_MetricsVariationsRec table */
+    /* used to handle the HVAR, VVAR, and MVAR OpenType tables         */
+    void*                 var;
+#endif
+
 
     /***********************************************************************/
     /*                                                                     */
@@ -1344,18 +1490,21 @@
     const char*           postscript_name;
 
     FT_ULong              glyf_len;
+    FT_ULong              glyf_offset;    /* since 2.7.1 */
+
+    FT_Bool               isCFF2;         /* since 2.7.1 */
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     FT_Bool               doblend;
     GX_Blend              blend;
+
+    FT_Bool               is_default_instance;   /* since 2.7.1 */
+    FT_UInt32             variation_support;     /* since 2.7.1 */
 #endif
 
     /* since version 2.2 */
 
-    FT_Byte*              horz_metrics;
     FT_ULong              horz_metrics_size;
-
-    FT_Byte*              vert_metrics;
     FT_ULong              vert_metrics_size;
 
     FT_ULong              num_locations; /* in broken TTF, gid > 0xFFFF */
@@ -1492,8 +1641,6 @@
     FT_Vector        pp1;
     FT_Vector        pp2;
 
-    FT_ULong         glyf_offset;
-
     /* the zone where we load our glyphs */
     TT_GlyphZoneRec  base;
     TT_GlyphZoneRec  zone;
diff --git a/include/freetype/t1tables.h b/include/freetype/t1tables.h
index e272324..81c9034 100644
--- a/include/freetype/t1tables.h
+++ b/include/freetype/t1tables.h
@@ -5,7 +5,7 @@
 /*    Basic Type 1/Type 2 tables definitions and interface (specification  */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/include/freetype/ttnameid.h b/include/freetype/ttnameid.h
index ce707f1..ea7f134 100644
--- a/include/freetype/ttnameid.h
+++ b/include/freetype/ttnameid.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType name ID definitions (specification only).                   */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -36,7 +36,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* Possible values for the `platform' identifier code in the name        */
-  /* records of the TTF `name' table.                                      */
+  /* records of an SFNT `name' table.                                      */
   /*                                                                       */
   /*************************************************************************/
 
@@ -119,14 +119,19 @@
    *   TT_APPLE_ID_VARIANT_SELECTOR ::
    *     From Adobe, not Apple.  Not a normal cmap.  Specifies variations
    *     on a real cmap.
+   *
+   *   TT_APPLE_ID_FULL_UNICODE ::
+   *     Used for fallback fonts that provide complete Unicode coverage with
+   *     a type~13 cmap.
    */
 
-#define TT_APPLE_ID_DEFAULT           0 /* Unicode 1.0 */
-#define TT_APPLE_ID_UNICODE_1_1       1 /* specify Hangul at U+34xx */
-#define TT_APPLE_ID_ISO_10646         2 /* deprecated */
-#define TT_APPLE_ID_UNICODE_2_0       3 /* or later */
+#define TT_APPLE_ID_DEFAULT           0 /* Unicode 1.0                   */
+#define TT_APPLE_ID_UNICODE_1_1       1 /* specify Hangul at U+34xx      */
+#define TT_APPLE_ID_ISO_10646         2 /* deprecated                    */
+#define TT_APPLE_ID_UNICODE_2_0       3 /* or later                      */
 #define TT_APPLE_ID_UNICODE_32        4 /* 2.0 or later, full repertoire */
-#define TT_APPLE_ID_VARIANT_SELECTOR  5 /* variation selector data */
+#define TT_APPLE_ID_VARIANT_SELECTOR  5 /* variation selector data       */
+#define TT_APPLE_ID_FULL_UNICODE      6 /* used with type 13 cmaps       */
 
 
   /***********************************************************************
@@ -137,42 +142,6 @@
    * @description:
    *   A list of valid values for the `encoding_id' for
    *   @TT_PLATFORM_MACINTOSH charmaps and name entries.
-   *
-   * @values:
-   *   TT_MAC_ID_ROMAN ::
-   *   TT_MAC_ID_JAPANESE ::
-   *   TT_MAC_ID_TRADITIONAL_CHINESE ::
-   *   TT_MAC_ID_KOREAN ::
-   *   TT_MAC_ID_ARABIC ::
-   *   TT_MAC_ID_HEBREW ::
-   *   TT_MAC_ID_GREEK ::
-   *   TT_MAC_ID_RUSSIAN ::
-   *   TT_MAC_ID_RSYMBOL ::
-   *   TT_MAC_ID_DEVANAGARI ::
-   *   TT_MAC_ID_GURMUKHI ::
-   *   TT_MAC_ID_GUJARATI ::
-   *   TT_MAC_ID_ORIYA ::
-   *   TT_MAC_ID_BENGALI ::
-   *   TT_MAC_ID_TAMIL ::
-   *   TT_MAC_ID_TELUGU ::
-   *   TT_MAC_ID_KANNADA ::
-   *   TT_MAC_ID_MALAYALAM ::
-   *   TT_MAC_ID_SINHALESE ::
-   *   TT_MAC_ID_BURMESE ::
-   *   TT_MAC_ID_KHMER ::
-   *   TT_MAC_ID_THAI ::
-   *   TT_MAC_ID_LAOTIAN ::
-   *   TT_MAC_ID_GEORGIAN ::
-   *   TT_MAC_ID_ARMENIAN ::
-   *   TT_MAC_ID_MALDIVIAN ::
-   *   TT_MAC_ID_SIMPLIFIED_CHINESE ::
-   *   TT_MAC_ID_TIBETAN ::
-   *   TT_MAC_ID_MONGOLIAN ::
-   *   TT_MAC_ID_GEEZ ::
-   *   TT_MAC_ID_SLAVIC ::
-   *   TT_MAC_ID_VIETNAMESE ::
-   *   TT_MAC_ID_SINDHI ::
-   *   TT_MAC_ID_UNINTERP ::
    */
 
 #define TT_MAC_ID_ROMAN                 0
@@ -247,44 +216,47 @@
    *
    * @values:
    *   TT_MS_ID_SYMBOL_CS ::
-   *     Corresponds to Microsoft symbol encoding. See
-   *     @FT_ENCODING_MS_SYMBOL.
+   *     Microsoft symbol encoding.  See @FT_ENCODING_MS_SYMBOL.
    *
    *   TT_MS_ID_UNICODE_CS ::
-   *     Corresponds to a Microsoft WGL4 charmap, matching Unicode.  See
+   *     Microsoft WGL4 charmap, matching Unicode.  See
    *     @FT_ENCODING_UNICODE.
    *
    *   TT_MS_ID_SJIS ::
-   *     Corresponds to SJIS Japanese encoding.  See @FT_ENCODING_SJIS.
+   *     Shift JIS Japanese encoding.  See @FT_ENCODING_SJIS.
    *
-   *   TT_MS_ID_GB2312 ::
-   *     Corresponds to Simplified Chinese as used in Mainland China.  See
-   *     @FT_ENCODING_GB2312.
+   *   TT_MS_ID_PRC ::
+   *     Chinese encodings as used in the People's Republic of China (PRC).
+   *     This means the encodings GB~2312 and its supersets GBK and
+   *     GB~18030.  See @FT_ENCODING_PRC.
    *
    *   TT_MS_ID_BIG_5 ::
-   *     Corresponds to Traditional Chinese as used in Taiwan and Hong Kong.
-   *     See @FT_ENCODING_BIG5.
+   *     Traditional Chinese as used in Taiwan and Hong Kong.  See
+   *     @FT_ENCODING_BIG5.
    *
    *   TT_MS_ID_WANSUNG ::
-   *     Corresponds to Korean Wansung encoding.  See @FT_ENCODING_WANSUNG.
+   *     Korean Extended Wansung encoding.  See @FT_ENCODING_WANSUNG.
    *
    *   TT_MS_ID_JOHAB ::
-   *     Corresponds to Johab encoding.  See @FT_ENCODING_JOHAB.
+   *     Korean Johab encoding.  See @FT_ENCODING_JOHAB.
    *
    *   TT_MS_ID_UCS_4 ::
-   *     Corresponds to UCS-4 or UTF-32 charmaps.  This has been added to
-   *     the OpenType specification version 1.4 (mid-2001.)
+   *     UCS-4 or UTF-32 charmaps.  This has been added to the OpenType
+   *     specification version 1.4 (mid-2001).
    */
 
 #define TT_MS_ID_SYMBOL_CS    0
 #define TT_MS_ID_UNICODE_CS   1
 #define TT_MS_ID_SJIS         2
-#define TT_MS_ID_GB2312       3
+#define TT_MS_ID_PRC          3
 #define TT_MS_ID_BIG_5        4
 #define TT_MS_ID_WANSUNG      5
 #define TT_MS_ID_JOHAB        6
 #define TT_MS_ID_UCS_4       10
 
+  /* this value is deprecated */
+#define TT_MS_ID_GB2312  TT_MS_ID_PRC
+
 
   /***********************************************************************
    *
@@ -312,17 +284,22 @@
 #define TT_ADOBE_ID_LATIN_1   3
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Possible values of the language identifier field in the name records  */
-  /* of the TTF `name' table if the `platform' identifier code is          */
-  /* TT_PLATFORM_MACINTOSH.  These values are also used as return values   */
-  /* for function @FT_Get_CMap_Language_ID.                                */
-  /*                                                                       */
-  /* The canonical source for the Apple assigned Language ID's is at       */
-  /*                                                                       */
-  /*   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html */
-  /*                                                                       */
+  /***********************************************************************
+   *
+   * @enum:
+   *   TT_MAC_LANGID_XXX
+   *
+   * @description:
+   *   Possible values of the language identifier field in the name records
+   *   of the SFNT `name' table if the `platform' identifier code is
+   *   @TT_PLATFORM_MACINTOSH.  These values are also used as return values
+   *   for function @FT_Get_CMap_Language_ID.
+   *
+   *   The canonical source for Apple's IDs is
+   *
+   *     https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html
+   */
+
 #define TT_MAC_LANGID_ENGLISH                       0
 #define TT_MAC_LANGID_FRENCH                        1
 #define TT_MAC_LANGID_GERMAN                        2
@@ -433,15 +410,6 @@
 #define TT_MAC_LANGID_JAVANESE                    138
 #define TT_MAC_LANGID_SUNDANESE                   139
 
-
-#if 0  /* these seem to be errors that have been dropped */
-
-#define TT_MAC_LANGID_SCOTTISH_GAELIC             140
-#define TT_MAC_LANGID_IRISH_GAELIC                141
-
-#endif
-
-
   /* The following codes are new as of 2000-03-10 */
 #define TT_MAC_LANGID_GALICIAN                    140
 #define TT_MAC_LANGID_AFRIKAANS                   141
@@ -456,18 +424,30 @@
 #define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT    150
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Possible values of the language identifier field in the name records  */
-  /* of the TTF `name' table if the `platform' identifier code is          */
-  /* TT_PLATFORM_MICROSOFT.                                                */
-  /*                                                                       */
-  /* The canonical source for the MS assigned LCIDs is                     */
-  /*                                                                       */
-  /*   http://www.microsoft.com/globaldev/reference/lcid-all.mspx          */
-  /*                                                                       */
+  /***********************************************************************
+   *
+   * @enum:
+   *   TT_MS_LANGID_XXX
+   *
+   * @description:
+   *   Possible values of the language identifier field in the name records
+   *   of the SFNT `name' table if the `platform' identifier code is
+   *   @TT_PLATFORM_MICROSOFT.  These values are also used as return values
+   *   for function @FT_Get_CMap_Language_ID.
+   *
+   *   The canonical source for Microsoft's IDs is
+   *
+   *     http://www.microsoft.com/globaldev/reference/lcid-all.mspx ,
+   *
+   *   however, we only provide macros for language identifiers present in
+   *   the OpenType specification: Microsoft has abandoned the concept of
+   *   LCIDs (language code identifiers), and format~1 of the `name' table
+   *   provides a better mechanism for languages not covered here.
+   *
+   *   More legacy values not listed in the reference can be found in the
+   *   @FT_TRUETYPE_IDS_H header file.
+   */
 
-#define TT_MS_LANGID_ARABIC_GENERAL                    0x0001
 #define TT_MS_LANGID_ARABIC_SAUDI_ARABIA               0x0401
 #define TT_MS_LANGID_ARABIC_IRAQ                       0x0801
 #define TT_MS_LANGID_ARABIC_EGYPT                      0x0C01
@@ -485,39 +465,20 @@
 #define TT_MS_LANGID_ARABIC_BAHRAIN                    0x3C01
 #define TT_MS_LANGID_ARABIC_QATAR                      0x4001
 #define TT_MS_LANGID_BULGARIAN_BULGARIA                0x0402
-#define TT_MS_LANGID_CATALAN_SPAIN                     0x0403
-#define TT_MS_LANGID_CHINESE_GENERAL                   0x0004
+#define TT_MS_LANGID_CATALAN_CATALAN                   0x0403
 #define TT_MS_LANGID_CHINESE_TAIWAN                    0x0404
 #define TT_MS_LANGID_CHINESE_PRC                       0x0804
 #define TT_MS_LANGID_CHINESE_HONG_KONG                 0x0C04
 #define TT_MS_LANGID_CHINESE_SINGAPORE                 0x1004
-
-#if 1  /* this looks like the correct value */
-#define TT_MS_LANGID_CHINESE_MACAU                     0x1404
-#else  /* but beware, Microsoft may change its mind...
-          the most recent Word reference has the following: */
-#define TT_MS_LANGID_CHINESE_MACAU  TT_MS_LANGID_CHINESE_HONG_KONG
-#endif
-
-#if 0  /* used only with .NET `cultures'; commented out */
-#define TT_MS_LANGID_CHINESE_TRADITIONAL               0x7C04
-#endif
-
+#define TT_MS_LANGID_CHINESE_MACAO                     0x1404
 #define TT_MS_LANGID_CZECH_CZECH_REPUBLIC              0x0405
 #define TT_MS_LANGID_DANISH_DENMARK                    0x0406
 #define TT_MS_LANGID_GERMAN_GERMANY                    0x0407
 #define TT_MS_LANGID_GERMAN_SWITZERLAND                0x0807
 #define TT_MS_LANGID_GERMAN_AUSTRIA                    0x0C07
 #define TT_MS_LANGID_GERMAN_LUXEMBOURG                 0x1007
-#define TT_MS_LANGID_GERMAN_LIECHTENSTEI               0x1407
+#define TT_MS_LANGID_GERMAN_LIECHTENSTEIN              0x1407
 #define TT_MS_LANGID_GREEK_GREECE                      0x0408
-
-  /* don't ask what this one means... It is commented out currently. */
-#if 0
-#define TT_MS_LANGID_GREEK_GREECE2                     0x2008
-#endif
-
-#define TT_MS_LANGID_ENGLISH_GENERAL                   0x0009
 #define TT_MS_LANGID_ENGLISH_UNITED_STATES             0x0409
 #define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM            0x0809
 #define TT_MS_LANGID_ENGLISH_AUSTRALIA                 0x0C09
@@ -531,14 +492,12 @@
 #define TT_MS_LANGID_ENGLISH_TRINIDAD                  0x2C09
 #define TT_MS_LANGID_ENGLISH_ZIMBABWE                  0x3009
 #define TT_MS_LANGID_ENGLISH_PHILIPPINES               0x3409
-#define TT_MS_LANGID_ENGLISH_INDONESIA                 0x3809
-#define TT_MS_LANGID_ENGLISH_HONG_KONG                 0x3C09
 #define TT_MS_LANGID_ENGLISH_INDIA                     0x4009
 #define TT_MS_LANGID_ENGLISH_MALAYSIA                  0x4409
 #define TT_MS_LANGID_ENGLISH_SINGAPORE                 0x4809
 #define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT    0x040A
 #define TT_MS_LANGID_SPANISH_MEXICO                    0x080A
-#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT  0x0C0A
+#define TT_MS_LANGID_SPANISH_SPAIN_MODERN_SORT         0x0C0A
 #define TT_MS_LANGID_SPANISH_GUATEMALA                 0x100A
 #define TT_MS_LANGID_SPANISH_COSTA_RICA                0x140A
 #define TT_MS_LANGID_SPANISH_PANAMA                    0x180A
@@ -557,9 +516,6 @@
 #define TT_MS_LANGID_SPANISH_NICARAGUA                 0x4C0A
 #define TT_MS_LANGID_SPANISH_PUERTO_RICO               0x500A
 #define TT_MS_LANGID_SPANISH_UNITED_STATES             0x540A
-  /* The following ID blatantly violate MS specs by using a */
-  /* sublanguage > 0x1F.                                    */
-#define TT_MS_LANGID_SPANISH_LATIN_AMERICA             0xE40AU
 #define TT_MS_LANGID_FINNISH_FINLAND                   0x040B
 #define TT_MS_LANGID_FRENCH_FRANCE                     0x040C
 #define TT_MS_LANGID_FRENCH_BELGIUM                    0x080C
@@ -567,27 +523,13 @@
 #define TT_MS_LANGID_FRENCH_SWITZERLAND                0x100C
 #define TT_MS_LANGID_FRENCH_LUXEMBOURG                 0x140C
 #define TT_MS_LANGID_FRENCH_MONACO                     0x180C
-#define TT_MS_LANGID_FRENCH_WEST_INDIES                0x1C0C
-#define TT_MS_LANGID_FRENCH_REUNION                    0x200C
-#define TT_MS_LANGID_FRENCH_CONGO                      0x240C
-  /* which was formerly: */
-#define TT_MS_LANGID_FRENCH_ZAIRE  TT_MS_LANGID_FRENCH_CONGO
-#define TT_MS_LANGID_FRENCH_SENEGAL                    0x280C
-#define TT_MS_LANGID_FRENCH_CAMEROON                   0x2C0C
-#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE              0x300C
-#define TT_MS_LANGID_FRENCH_MALI                       0x340C
-#define TT_MS_LANGID_FRENCH_MOROCCO                    0x380C
-#define TT_MS_LANGID_FRENCH_HAITI                      0x3C0C
-  /* and another violation of the spec (see 0xE40AU) */
-#define TT_MS_LANGID_FRENCH_NORTH_AFRICA               0xE40CU
 #define TT_MS_LANGID_HEBREW_ISRAEL                     0x040D
 #define TT_MS_LANGID_HUNGARIAN_HUNGARY                 0x040E
 #define TT_MS_LANGID_ICELANDIC_ICELAND                 0x040F
 #define TT_MS_LANGID_ITALIAN_ITALY                     0x0410
 #define TT_MS_LANGID_ITALIAN_SWITZERLAND               0x0810
 #define TT_MS_LANGID_JAPANESE_JAPAN                    0x0411
-#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA     0x0412
-#define TT_MS_LANGID_KOREAN_JOHAB_KOREA                0x0812
+#define TT_MS_LANGID_KOREAN_KOREA                      0x0412
 #define TT_MS_LANGID_DUTCH_NETHERLANDS                 0x0413
 #define TT_MS_LANGID_DUTCH_BELGIUM                     0x0813
 #define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL           0x0414
@@ -595,26 +537,17 @@
 #define TT_MS_LANGID_POLISH_POLAND                     0x0415
 #define TT_MS_LANGID_PORTUGUESE_BRAZIL                 0x0416
 #define TT_MS_LANGID_PORTUGUESE_PORTUGAL               0x0816
-#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND        0x0417
+#define TT_MS_LANGID_ROMANSH_SWITZERLAND               0x0417
 #define TT_MS_LANGID_ROMANIAN_ROMANIA                  0x0418
-#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA                0x0818
 #define TT_MS_LANGID_RUSSIAN_RUSSIA                    0x0419
-#define TT_MS_LANGID_RUSSIAN_MOLDAVIA                  0x0819
 #define TT_MS_LANGID_CROATIAN_CROATIA                  0x041A
 #define TT_MS_LANGID_SERBIAN_SERBIA_LATIN              0x081A
 #define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC           0x0C1A
-
-#if 0  /* this used to be this value, but it looks like we were wrong */
-#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x101A
-#else  /* current sources say */
 #define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA       0x101A
 #define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA        0x141A
-       /* and XPsp2 Platform SDK added (2004-07-26) */
-       /* Names are shortened to be significant within 40 chars. */
 #define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN         0x181A
-#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC      0x181A
-#endif
-
+#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC      0x1C1A
+#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZ_CYRILLIC      0x201A
 #define TT_MS_LANGID_SLOVAK_SLOVAKIA                   0x041B
 #define TT_MS_LANGID_ALBANIAN_ALBANIA                  0x041C
 #define TT_MS_LANGID_SWEDISH_SWEDEN                    0x041D
@@ -622,36 +555,30 @@
 #define TT_MS_LANGID_THAI_THAILAND                     0x041E
 #define TT_MS_LANGID_TURKISH_TURKEY                    0x041F
 #define TT_MS_LANGID_URDU_PAKISTAN                     0x0420
-#define TT_MS_LANGID_URDU_INDIA                        0x0820
 #define TT_MS_LANGID_INDONESIAN_INDONESIA              0x0421
 #define TT_MS_LANGID_UKRAINIAN_UKRAINE                 0x0422
 #define TT_MS_LANGID_BELARUSIAN_BELARUS                0x0423
-#define TT_MS_LANGID_SLOVENE_SLOVENIA                  0x0424
+#define TT_MS_LANGID_SLOVENIAN_SLOVENIA                0x0424
 #define TT_MS_LANGID_ESTONIAN_ESTONIA                  0x0425
 #define TT_MS_LANGID_LATVIAN_LATVIA                    0x0426
 #define TT_MS_LANGID_LITHUANIAN_LITHUANIA              0x0427
-#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA      0x0827
 #define TT_MS_LANGID_TAJIK_TAJIKISTAN                  0x0428
-#define TT_MS_LANGID_FARSI_IRAN                        0x0429
 #define TT_MS_LANGID_VIETNAMESE_VIET_NAM               0x042A
 #define TT_MS_LANGID_ARMENIAN_ARMENIA                  0x042B
 #define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN            0x042C
 #define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC         0x082C
-#define TT_MS_LANGID_BASQUE_SPAIN                      0x042D
-#define TT_MS_LANGID_SORBIAN_GERMANY                   0x042E
+#define TT_MS_LANGID_BASQUE_BASQUE                     0x042D
+#define TT_MS_LANGID_UPPER_SORBIAN_GERMANY             0x042E
+#define TT_MS_LANGID_LOWER_SORBIAN_GERMANY             0x082E
 #define TT_MS_LANGID_MACEDONIAN_MACEDONIA              0x042F
-#define TT_MS_LANGID_SUTU_SOUTH_AFRICA                 0x0430
-#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA               0x0431
-#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA               0x0432
-#define TT_MS_LANGID_VENDA_SOUTH_AFRICA                0x0433
-#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA                0x0434
-#define TT_MS_LANGID_ZULU_SOUTH_AFRICA                 0x0435
+#define TT_MS_LANGID_SETSWANA_SOUTH_AFRICA             0x0432
+#define TT_MS_LANGID_ISIXHOSA_SOUTH_AFRICA             0x0434
+#define TT_MS_LANGID_ISIZULU_SOUTH_AFRICA              0x0435
 #define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA            0x0436
 #define TT_MS_LANGID_GEORGIAN_GEORGIA                  0x0437
 #define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS           0x0438
 #define TT_MS_LANGID_HINDI_INDIA                       0x0439
 #define TT_MS_LANGID_MALTESE_MALTA                     0x043A
-  /* Added by XPsp2 Platform SDK (2004-07-26) */
 #define TT_MS_LANGID_SAMI_NORTHERN_NORWAY              0x043B
 #define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN              0x083B
 #define TT_MS_LANGID_SAMI_NORTHERN_FINLAND             0x0C3B
@@ -661,37 +588,21 @@
 #define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN              0x1C3B
 #define TT_MS_LANGID_SAMI_SKOLT_FINLAND                0x203B
 #define TT_MS_LANGID_SAMI_INARI_FINLAND                0x243B
-  /* ... and we also keep our old identifier... */
-#define TT_MS_LANGID_SAAMI_LAPONIA                     0x043B
-
-#if 0 /* this seems to be a previous inversion */
-#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043C
-#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083C
-#else
-#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083C
-#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043C
-#endif
-
-#define TT_MS_LANGID_YIDDISH_GERMANY                   0x043D
+#define TT_MS_LANGID_IRISH_IRELAND                     0x083C
 #define TT_MS_LANGID_MALAY_MALAYSIA                    0x043E
 #define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM           0x083E
-#define TT_MS_LANGID_KAZAK_KAZAKSTAN                   0x043F
-#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440
-  /* alias declared in Windows 2000 */
-#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \
-          TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN
-
-#define TT_MS_LANGID_SWAHILI_KENYA                     0x0441
+#define TT_MS_LANGID_KAZAKH_KAZAKHSTAN                 0x043F
+#define TT_MS_LANGID_KYRGYZ_KYRGYZSTAN /* Cyrillic*/   0x0440
+#define TT_MS_LANGID_KISWAHILI_KENYA                   0x0441
 #define TT_MS_LANGID_TURKMEN_TURKMENISTAN              0x0442
 #define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN            0x0443
 #define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC         0x0843
-#define TT_MS_LANGID_TATAR_TATARSTAN                   0x0444
+#define TT_MS_LANGID_TATAR_RUSSIA                      0x0444
 #define TT_MS_LANGID_BENGALI_INDIA                     0x0445
 #define TT_MS_LANGID_BENGALI_BANGLADESH                0x0845
 #define TT_MS_LANGID_PUNJABI_INDIA                     0x0446
-#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN           0x0846
 #define TT_MS_LANGID_GUJARATI_INDIA                    0x0447
-#define TT_MS_LANGID_ORIYA_INDIA                       0x0448
+#define TT_MS_LANGID_ODIA_INDIA                        0x0448
 #define TT_MS_LANGID_TAMIL_INDIA                       0x0449
 #define TT_MS_LANGID_TELUGU_INDIA                      0x044A
 #define TT_MS_LANGID_KANNADA_INDIA                     0x044B
@@ -700,142 +611,241 @@
 #define TT_MS_LANGID_MARATHI_INDIA                     0x044E
 #define TT_MS_LANGID_SANSKRIT_INDIA                    0x044F
 #define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450
-#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN      0x0850
-#define TT_MS_LANGID_TIBETAN_CHINA                     0x0451
-  /* Don't use the next constant!  It has            */
-  /*   (1) the wrong spelling (Dzonghka)             */
-  /*   (2) Microsoft doesn't officially define it -- */
-  /*       at least it is not in the List of Local   */
-  /*       ID Values.                                */
-  /*   (3) Dzongkha is not the same language as      */
-  /*       Tibetan, so merging it is wrong anyway.   */
-  /*                                                 */
-  /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW.    */
-#define TT_MS_LANGID_DZONGHKA_BHUTAN                   0x0851
-
-#if 0
-  /* the following used to be defined */
-#define TT_MS_LANGID_TIBETAN_BHUTAN                    0x0451
-  /* ... but it was changed; */
-#else
-  /* So we will continue to #define it, but with the correct value */
-#define TT_MS_LANGID_TIBETAN_BHUTAN   TT_MS_LANGID_DZONGHKA_BHUTAN
-#endif
-
-#define TT_MS_LANGID_WELSH_WALES                       0x0452
+#define TT_MS_LANGID_MONGOLIAN_PRC                     0x0850
+#define TT_MS_LANGID_TIBETAN_PRC                       0x0451
+#define TT_MS_LANGID_WELSH_UNITED_KINGDOM              0x0452
 #define TT_MS_LANGID_KHMER_CAMBODIA                    0x0453
 #define TT_MS_LANGID_LAO_LAOS                          0x0454
-#define TT_MS_LANGID_BURMESE_MYANMAR                   0x0455
-#define TT_MS_LANGID_GALICIAN_SPAIN                    0x0456
+#define TT_MS_LANGID_GALICIAN_GALICIAN                 0x0456
 #define TT_MS_LANGID_KONKANI_INDIA                     0x0457
-#define TT_MS_LANGID_MANIPURI_INDIA  /* Bengali */     0x0458
-#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */         0x0459
-#define TT_MS_LANGID_SINDHI_PAKISTAN                   0x0859
-  /* Missing a LCID for Sindhi in Devanagari script */
 #define TT_MS_LANGID_SYRIAC_SYRIA                      0x045A
-#define TT_MS_LANGID_SINHALESE_SRI_LANKA               0x045B
-#define TT_MS_LANGID_CHEROKEE_UNITED_STATES            0x045C
+#define TT_MS_LANGID_SINHALA_SRI_LANKA                 0x045B
 #define TT_MS_LANGID_INUKTITUT_CANADA                  0x045D
+#define TT_MS_LANGID_INUKTITUT_CANADA_LATIN            0x085D
 #define TT_MS_LANGID_AMHARIC_ETHIOPIA                  0x045E
-#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */    0x045F
-#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN           0x085F
-  /* Missing a LCID for Tifinagh script */
-#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */    0x0460
-  /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */
-  /* script is yet unclear... might be Arabic, Nagari or Sharada */
-#define TT_MS_LANGID_KASHMIRI_SASIA                    0x0860
-  /* ... and aliased (by MS) for compatibility reasons. */
-#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA
+#define TT_MS_LANGID_TAMAZIGHT_ALGERIA                 0x085F
 #define TT_MS_LANGID_NEPALI_NEPAL                      0x0461
-#define TT_MS_LANGID_NEPALI_INDIA                      0x0861
 #define TT_MS_LANGID_FRISIAN_NETHERLANDS               0x0462
 #define TT_MS_LANGID_PASHTO_AFGHANISTAN                0x0463
 #define TT_MS_LANGID_FILIPINO_PHILIPPINES              0x0464
 #define TT_MS_LANGID_DHIVEHI_MALDIVES                  0x0465
-  /* alias declared in Windows 2000 */
-#define TT_MS_LANGID_DIVEHI_MALDIVES  TT_MS_LANGID_DHIVEHI_MALDIVES
-#define TT_MS_LANGID_EDO_NIGERIA                       0x0466
-#define TT_MS_LANGID_FULFULDE_NIGERIA                  0x0467
 #define TT_MS_LANGID_HAUSA_NIGERIA                     0x0468
-#define TT_MS_LANGID_IBIBIO_NIGERIA                    0x0469
 #define TT_MS_LANGID_YORUBA_NIGERIA                    0x046A
 #define TT_MS_LANGID_QUECHUA_BOLIVIA                   0x046B
 #define TT_MS_LANGID_QUECHUA_ECUADOR                   0x086B
 #define TT_MS_LANGID_QUECHUA_PERU                      0x0C6B
-#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA               0x046C
-  /* Also spelled by XPsp2 Platform SDK (2004-07-26) */
-#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \
-          TT_MS_LANGID_SEPEDI_SOUTH_AFRICA
-  /* language codes 0x046D, 0x046E and 0x046F are (still) unknown. */
+#define TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA     0x046C
+#define TT_MS_LANGID_BASHKIR_RUSSIA                    0x046D
+#define TT_MS_LANGID_LUXEMBOURGISH_LUXEMBOURG          0x046E
+#define TT_MS_LANGID_GREENLANDIC_GREENLAND             0x046F
 #define TT_MS_LANGID_IGBO_NIGERIA                      0x0470
+#define TT_MS_LANGID_YI_PRC                            0x0478
+#define TT_MS_LANGID_MAPUDUNGUN_CHILE                  0x047A
+#define TT_MS_LANGID_MOHAWK_MOHAWK                     0x047C
+#define TT_MS_LANGID_BRETON_FRANCE                     0x047E
+#define TT_MS_LANGID_UIGHUR_PRC                        0x0480
+#define TT_MS_LANGID_MAORI_NEW_ZEALAND                 0x0481
+#define TT_MS_LANGID_OCCITAN_FRANCE                    0x0482
+#define TT_MS_LANGID_CORSICAN_FRANCE                   0x0483
+#define TT_MS_LANGID_ALSATIAN_FRANCE                   0x0484
+#define TT_MS_LANGID_YAKUT_RUSSIA                      0x0485
+#define TT_MS_LANGID_KICHE_GUATEMALA                   0x0486
+#define TT_MS_LANGID_KINYARWANDA_RWANDA                0x0487
+#define TT_MS_LANGID_WOLOF_SENEGAL                     0x0488
+#define TT_MS_LANGID_DARI_AFGHANISTAN                  0x048C
+
+  /* */
+
+
+  /* legacy macro definitions not present in OpenType 1.8.1 */
+#define TT_MS_LANGID_ARABIC_GENERAL                    0x0001
+#define TT_MS_LANGID_CATALAN_SPAIN \
+          TT_MS_LANGID_CATALAN_CATALAN
+#define TT_MS_LANGID_CHINESE_GENERAL                   0x0004
+#define TT_MS_LANGID_CHINESE_MACAU \
+          TT_MS_LANGID_CHINESE_MACAO
+#define TT_MS_LANGID_GERMAN_LIECHTENSTEI \
+          TT_MS_LANGID_GERMAN_LIECHTENSTEIN
+#define TT_MS_LANGID_ENGLISH_GENERAL                   0x0009
+#define TT_MS_LANGID_ENGLISH_INDONESIA                 0x3809
+#define TT_MS_LANGID_ENGLISH_HONG_KONG                 0x3C09
+#define TT_MS_LANGID_SPANISH_INTERNATIONAL_SORT \
+          TT_MS_LANGID_SPANISH_SPAIN_MODERN_SORT
+#define TT_MS_LANGID_SPANISH_LATIN_AMERICA             0xE40AU
+#define TT_MS_LANGID_FRENCH_WEST_INDIES                0x1C0C
+#define TT_MS_LANGID_FRENCH_REUNION                    0x200C
+#define TT_MS_LANGID_FRENCH_CONGO                      0x240C
+  /* which was formerly: */
+#define TT_MS_LANGID_FRENCH_ZAIRE \
+          TT_MS_LANGID_FRENCH_CONGO
+#define TT_MS_LANGID_FRENCH_SENEGAL                    0x280C
+#define TT_MS_LANGID_FRENCH_CAMEROON                   0x2C0C
+#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE              0x300C
+#define TT_MS_LANGID_FRENCH_MALI                       0x340C
+#define TT_MS_LANGID_FRENCH_MOROCCO                    0x380C
+#define TT_MS_LANGID_FRENCH_HAITI                      0x3C0C
+#define TT_MS_LANGID_FRENCH_NORTH_AFRICA               0xE40CU
+#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA \
+          TT_MS_LANGID_KOREAN_KOREA
+#define TT_MS_LANGID_KOREAN_JOHAB_KOREA                0x0812
+#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND \
+          TT_MS_LANGID_ROMANSH_SWITZERLAND
+#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA                0x0818
+#define TT_MS_LANGID_RUSSIAN_MOLDAVIA                  0x0819
+#define TT_MS_LANGID_URDU_INDIA                        0x0820
+#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA      0x0827
+#define TT_MS_LANGID_SLOVENE_SLOVENIA \
+          TT_MS_LANGID_SLOVENIAN_SLOVENIA
+#define TT_MS_LANGID_FARSI_IRAN                        0x0429
+#define TT_MS_LANGID_BASQUE_SPAIN \
+          TT_MS_LANGID_BASQUE_BASQUE
+#define TT_MS_LANGID_SORBIAN_GERMANY \
+          TT_MS_LANGID_UPPER_SORBIAN_GERMANY
+#define TT_MS_LANGID_SUTU_SOUTH_AFRICA                 0x0430
+#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA               0x0431
+#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA \
+          TT_MS_LANGID_SETSWANA_SOUTH_AFRICA
+#define TT_MS_LANGID_VENDA_SOUTH_AFRICA                0x0433
+#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA \
+          TT_MS_LANGID_ISIXHOSA_SOUTH_AFRICA
+#define TT_MS_LANGID_ZULU_SOUTH_AFRICA \
+          TT_MS_LANGID_ISIZULU_SOUTH_AFRICA
+#define TT_MS_LANGID_SAAMI_LAPONIA                     0x043B
+  /* the next two values are incorrectly inverted */
+#define TT_MS_LANGID_IRISH_GAELIC_IRELAND              0x043C
+#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM    0x083C
+#define TT_MS_LANGID_YIDDISH_GERMANY                   0x043D
+#define TT_MS_LANGID_KAZAK_KAZAKSTAN \
+          TT_MS_LANGID_KAZAKH_KAZAKHSTAN
+#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \
+          TT_MS_LANGID_KYRGYZ_KYRGYZSTAN
+#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN \
+          TT_MS_LANGID_KYRGYZ_KYRGYZSTAN
+#define TT_MS_LANGID_SWAHILI_KENYA \
+          TT_MS_LANGID_KISWAHILI_KENYA
+#define TT_MS_LANGID_TATAR_TATARSTAN \
+          TT_MS_LANGID_TATAR_RUSSIA
+#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN           0x0846
+#define TT_MS_LANGID_ORIYA_INDIA \
+          TT_MS_LANGID_ODIA_INDIA
+#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIA \
+          TT_MS_LANGID_MONGOLIAN_PRC
+#define TT_MS_LANGID_TIBETAN_CHINA \
+          TT_MS_LANGID_TIBETAN_PRC
+#define TT_MS_LANGID_DZONGHKA_BHUTAN                   0x0851
+#define TT_MS_LANGID_TIBETAN_BHUTAN \
+          TT_MS_LANGID_DZONGHKA_BHUTAN
+#define TT_MS_LANGID_WELSH_WALES \
+          TT_MS_LANGID_WELSH_UNITED_KINGDOM
+#define TT_MS_LANGID_BURMESE_MYANMAR                   0x0455
+#define TT_MS_LANGID_GALICIAN_SPAIN \
+          TT_MS_LANGID_GALICIAN_GALICIAN
+#define TT_MS_LANGID_MANIPURI_INDIA  /* Bengali */     0x0458
+#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */         0x0459
+#define TT_MS_LANGID_SINDHI_PAKISTAN                   0x0859
+#define TT_MS_LANGID_SINHALESE_SRI_LANKA \
+          TT_MS_LANGID_SINHALA_SRI_LANKA
+#define TT_MS_LANGID_CHEROKEE_UNITED_STATES            0x045C
+#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */    0x045F
+#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN \
+          TT_MS_LANGID_TAMAZIGHT_ALGERIA
+#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */    0x0460
+#define TT_MS_LANGID_KASHMIRI_SASIA                    0x0860
+#define TT_MS_LANGID_KASHMIRI_INDIA \
+          TT_MS_LANGID_KASHMIRI_SASIA
+#define TT_MS_LANGID_NEPALI_INDIA                      0x0861
+#define TT_MS_LANGID_DIVEHI_MALDIVES \
+          TT_MS_LANGID_DHIVEHI_MALDIVES
+#define TT_MS_LANGID_EDO_NIGERIA                       0x0466
+#define TT_MS_LANGID_FULFULDE_NIGERIA                  0x0467
+#define TT_MS_LANGID_IBIBIO_NIGERIA                    0x0469
+#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA \
+          TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA
+#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \
+          TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA
 #define TT_MS_LANGID_KANURI_NIGERIA                    0x0471
 #define TT_MS_LANGID_OROMO_ETHIOPIA                    0x0472
 #define TT_MS_LANGID_TIGRIGNA_ETHIOPIA                 0x0473
 #define TT_MS_LANGID_TIGRIGNA_ERYTHREA                 0x0873
-  /* also spelled in the `Passport SDK' list as: */
-#define TT_MS_LANGID_TIGRIGNA_ERYTREA  TT_MS_LANGID_TIGRIGNA_ERYTHREA
+#define TT_MS_LANGID_TIGRIGNA_ERYTREA \
+          TT_MS_LANGID_TIGRIGNA_ERYTHREA
 #define TT_MS_LANGID_GUARANI_PARAGUAY                  0x0474
 #define TT_MS_LANGID_HAWAIIAN_UNITED_STATES            0x0475
 #define TT_MS_LANGID_LATIN                             0x0476
 #define TT_MS_LANGID_SOMALI_SOMALIA                    0x0477
-  /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */
-  /*       not written (but OTOH the peculiar writing system is worth     */
-  /*       studying).                                                     */
-#define TT_MS_LANGID_YI_CHINA                          0x0478
+#define TT_MS_LANGID_YI_CHINA \
+          TT_MS_LANGID_YI_PRC
 #define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES   0x0479
-  /* language codes from 0x047A to 0x047F are (still) unknown. */
-#define TT_MS_LANGID_UIGHUR_CHINA                      0x0480
-#define TT_MS_LANGID_MAORI_NEW_ZEALAND                 0x0481
-
-#if 0  /* not deemed useful for fonts */
-#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE            0x04FF
-#endif
+#define TT_MS_LANGID_UIGHUR_CHINA \
+          TT_MS_LANGID_UIGHUR_PRC
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Possible values of the `name' identifier field in the name records of */
-  /* the TTF `name' table.  These values are platform independent.         */
-  /*                                                                       */
-#define TT_NAME_ID_COPYRIGHT            0
-#define TT_NAME_ID_FONT_FAMILY          1
-#define TT_NAME_ID_FONT_SUBFAMILY       2
-#define TT_NAME_ID_UNIQUE_ID            3
-#define TT_NAME_ID_FULL_NAME            4
-#define TT_NAME_ID_VERSION_STRING       5
-#define TT_NAME_ID_PS_NAME              6
-#define TT_NAME_ID_TRADEMARK            7
+  /***********************************************************************
+   *
+   * @enum:
+   *   TT_NAME_ID_XXX
+   *
+   * @description:
+   *   Possible values of the `name' identifier field in the name records of
+   *   an SFNT `name' table.  These values are platform independent.
+   */
+
+#define TT_NAME_ID_COPYRIGHT              0
+#define TT_NAME_ID_FONT_FAMILY            1
+#define TT_NAME_ID_FONT_SUBFAMILY         2
+#define TT_NAME_ID_UNIQUE_ID              3
+#define TT_NAME_ID_FULL_NAME              4
+#define TT_NAME_ID_VERSION_STRING         5
+#define TT_NAME_ID_PS_NAME                6
+#define TT_NAME_ID_TRADEMARK              7
 
   /* the following values are from the OpenType spec */
-#define TT_NAME_ID_MANUFACTURER         8
-#define TT_NAME_ID_DESIGNER             9
-#define TT_NAME_ID_DESCRIPTION          10
-#define TT_NAME_ID_VENDOR_URL           11
-#define TT_NAME_ID_DESIGNER_URL         12
-#define TT_NAME_ID_LICENSE              13
-#define TT_NAME_ID_LICENSE_URL          14
+#define TT_NAME_ID_MANUFACTURER           8
+#define TT_NAME_ID_DESIGNER               9
+#define TT_NAME_ID_DESCRIPTION            10
+#define TT_NAME_ID_VENDOR_URL             11
+#define TT_NAME_ID_DESIGNER_URL           12
+#define TT_NAME_ID_LICENSE                13
+#define TT_NAME_ID_LICENSE_URL            14
   /* number 15 is reserved */
-#define TT_NAME_ID_PREFERRED_FAMILY     16
-#define TT_NAME_ID_PREFERRED_SUBFAMILY  17
-#define TT_NAME_ID_MAC_FULL_NAME        18
+#define TT_NAME_ID_TYPOGRAPHIC_FAMILY     16
+#define TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY  17
+#define TT_NAME_ID_MAC_FULL_NAME          18
 
   /* The following code is new as of 2000-01-21 */
-#define TT_NAME_ID_SAMPLE_TEXT          19
+#define TT_NAME_ID_SAMPLE_TEXT            19
 
   /* This is new in OpenType 1.3 */
-#define TT_NAME_ID_CID_FINDFONT_NAME    20
+#define TT_NAME_ID_CID_FINDFONT_NAME      20
 
   /* This is new in OpenType 1.5 */
-#define TT_NAME_ID_WWS_FAMILY           21
-#define TT_NAME_ID_WWS_SUBFAMILY        22
+#define TT_NAME_ID_WWS_FAMILY             21
+#define TT_NAME_ID_WWS_SUBFAMILY          22
+
+  /* This is new in OpenType 1.7 */
+#define TT_NAME_ID_LIGHT_BACKGROUND       23
+#define TT_NAME_ID_DARK_BACKGROUND        24
+
+  /* This is new in OpenType 1.8 */
+#define TT_NAME_ID_VARIATIONS_PREFIX      25
+
+  /* these two values are deprecated */
+#define TT_NAME_ID_PREFERRED_FAMILY     TT_NAME_ID_TYPOGRAPHIC_FAMILY
+#define TT_NAME_ID_PREFERRED_SUBFAMILY  TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table.     */
-  /*                                                                       */
-  /* Updated 08-Nov-2008.                                                  */
-  /*                                                                       */
+  /***********************************************************************
+   *
+   * @enum:
+   *   TT_UCR_XXX
+   *
+   * @description:
+   *   Possible bit mask values for the `ulUnicodeRangeX' fields in an SFNT
+   *   `OS/2' table.
+   */
+
+  /* ulUnicodeRange1 */
+  /* --------------- */
 
   /* Bit  0   Basic Latin */
 #define TT_UCR_BASIC_LATIN                     (1L <<  0) /* U+0020-U+007E */
@@ -857,7 +867,7 @@
                                                           /* U+A700-U+A71F */
   /* Bit  6   Combining Diacritical Marks            */
   /*          Combining Diacritical Marks Supplement */
-#define TT_UCR_COMBINING_DIACRITICS            (1L <<  6) /* U+0300-U+036F */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS     (1L <<  6) /* U+0300-U+036F */
                                                           /* U+1DC0-U+1DFF */
   /* Bit  7   Greek and Coptic */
 #define TT_UCR_GREEK                           (1L <<  7) /* U+0370-U+03FF */
@@ -925,12 +935,17 @@
   /*          Supplemental Punctuation */
 #define TT_UCR_GENERAL_PUNCTUATION             (1L << 31) /* U+2000-U+206F */
                                                           /* U+2E00-U+2E7F */
+
+  /* ulUnicodeRange2 */
+  /* --------------- */
+
   /* Bit 32   Superscripts And Subscripts */
 #define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS         (1L <<  0) /* U+2070-U+209F */
   /* Bit 33   Currency Symbols */
 #define TT_UCR_CURRENCY_SYMBOLS                (1L <<  1) /* U+20A0-U+20CF */
   /* Bit 34   Combining Diacritical Marks For Symbols */
-#define TT_UCR_COMBINING_DIACRITICS_SYMB       (1L <<  2) /* U+20D0-U+20FF */
+#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \
+                                               (1L <<  2) /* U+20D0-U+20FF */
   /* Bit 35   Letterlike Symbols */
 #define TT_UCR_LETTERLIKE_SYMBOLS              (1L <<  3) /* U+2100-U+214F */
   /* Bit 36   Number Forms */
@@ -996,13 +1011,13 @@
   /* Bit 57   High Surrogates              */
   /*          High Private Use Surrogates  */
   /*          Low Surrogates               */
-  /*                                       */
+
   /* According to OpenType specs v.1.3+,   */
   /* setting bit 57 implies that there is  */
   /* at least one codepoint beyond the     */
   /* Basic Multilingual Plane that is      */
   /* supported by this font.  So it really */
-  /* means >= U+10000                      */
+  /* means >= U+10000.                     */
 #define TT_UCR_SURROGATES                      (1L << 25) /* U+D800-U+DB7F */
                                                           /* U+DB80-U+DBFF */
                                                           /* U+DC00-U+DFFF */
@@ -1034,7 +1049,11 @@
   /* Bit 62   Alphabetic Presentation Forms */
 #define TT_UCR_ALPHABETIC_PRESENTATION_FORMS   (1L << 30) /* U+FB00-U+FB4F */
   /* Bit 63   Arabic Presentation Forms-A */
-#define TT_UCR_ARABIC_PRESENTATIONS_A          (1L << 31) /* U+FB50-U+FDFF */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_A     (1L << 31) /* U+FB50-U+FDFF */
+
+  /* ulUnicodeRange3 */
+  /* --------------- */
+
   /* Bit 64   Combining Half Marks */
 #define TT_UCR_COMBINING_HALF_MARKS            (1L <<  0) /* U+FE20-U+FE2F */
   /* Bit 65   Vertical forms          */
@@ -1044,7 +1063,7 @@
   /* Bit 66   Small Form Variants */
 #define TT_UCR_SMALL_FORM_VARIANTS             (1L <<  2) /* U+FE50-U+FE6F */
   /* Bit 67   Arabic Presentation Forms-B */
-#define TT_UCR_ARABIC_PRESENTATIONS_B          (1L <<  3) /* U+FE70-U+FEFE */
+#define TT_UCR_ARABIC_PRESENTATION_FORMS_B     (1L <<  3) /* U+FE70-U+FEFE */
   /* Bit 68   Halfwidth and Fullwidth Forms */
 #define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS       (1L <<  4) /* U+FF00-U+FFEF */
   /* Bit 69   Specials */
@@ -1123,6 +1142,10 @@
 #define TT_UCR_TAI_LE                          (1L << 30) /* U+1950-U+197F */
   /* Bit 95   New Tai Lue */
 #define TT_UCR_NEW_TAI_LUE                     (1L << 31) /* U+1980-U+19DF */
+
+  /* ulUnicodeRange4 */
+  /* --------------- */
+
   /* Bit 96   Buginese */
 #define TT_UCR_BUGINESE                        (1L <<  0) /* U+1A00-U+1A1F */
   /* Bit 97   Glagolitic */
@@ -1191,42 +1214,18 @@
                                                           /*U+1F000-U+1F02F*/
   /* Bit 123-127 Reserved for process-internal usage */
 
+  /* */
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* Some compilers have a very limited length of identifiers.             */
-  /*                                                                       */
-#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ )
-#define HAVE_LIMIT_ON_IDENTS
-#endif
+  /* for backwards compatibility with older FreeType versions */
+#define TT_UCR_ARABIC_PRESENTATION_A         \
+          TT_UCR_ARABIC_PRESENTATION_FORMS_A
+#define TT_UCR_ARABIC_PRESENTATION_B         \
+          TT_UCR_ARABIC_PRESENTATION_FORMS_B
 
-
-#ifndef HAVE_LIMIT_ON_IDENTS
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Here some alias #defines in order to be clearer.                      */
-  /*                                                                       */
-  /* These are not always #defined to stay within the 31~character limit,  */
-  /* which some compilers have.                                            */
-  /*                                                                       */
-  /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern  */
-  /* Borland compilers (read: from BC++ 3.1 on) can increase this limit.   */
-  /* If you get a warning with such a compiler, use the -i40 switch.       */
-  /*                                                                       */
-#define TT_UCR_ARABIC_PRESENTATION_FORMS_A      \
-         TT_UCR_ARABIC_PRESENTATIONS_A
-#define TT_UCR_ARABIC_PRESENTATION_FORMS_B      \
-         TT_UCR_ARABIC_PRESENTATIONS_B
-
-#define TT_UCR_COMBINING_DIACRITICAL_MARKS      \
-         TT_UCR_COMBINING_DIACRITICS
-#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \
-         TT_UCR_COMBINING_DIACRITICS_SYMB
-
-
-#endif /* !HAVE_LIMIT_ON_IDENTS */
+#define TT_UCR_COMBINING_DIACRITICS          \
+          TT_UCR_COMBINING_DIACRITICAL_MARKS
+#define TT_UCR_COMBINING_DIACRITICS_SYMB          \
+          TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB
 
 
 FT_END_HEADER
diff --git a/include/freetype/tttables.h b/include/freetype/tttables.h
index 1c075dc..5831204 100644
--- a/include/freetype/tttables.h
+++ b/include/freetype/tttables.h
@@ -5,7 +5,7 @@
 /*    Basic SFNT/TrueType tables definitions and interface                 */
 /*    (specification only).                                                */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -45,8 +45,9 @@
   /*    TrueType specific table types and functions.                       */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    This section contains the definition of TrueType-specific tables   */
-  /*    as well as some routines used to access and process them.          */
+  /*    This section contains definitions of some basic tables specific to */
+  /*    TrueType and OpenType as well as some routines used to access and  */
+  /*    process them.                                                      */
   /*                                                                       */
   /* <Order>                                                               */
   /*    TT_Header                                                          */
@@ -76,8 +77,8 @@
   /*    TT_Header                                                          */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a TrueType font header table.  All       */
-  /*    fields follow the TrueType specification.                          */
+  /*    A structure to model a TrueType font header table.  All fields     */
+  /*    follow the OpenType specification.                                 */
   /*                                                                       */
   typedef struct  TT_Header_
   {
@@ -114,9 +115,9 @@
   /*    TT_HoriHeader                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a TrueType horizontal header, the `hhea' */
+  /*    A structure to model a TrueType horizontal header, the `hhea'      */
   /*    table, as well as the corresponding horizontal metrics table,      */
-  /*    i.e., the `hmtx' table.                                            */
+  /*    `hmtx'.                                                            */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    Version                :: The table version.                       */
@@ -131,7 +132,7 @@
   /*                              glyphs found in the font (maybe ASCII).  */
   /*                                                                       */
   /*                              You should use the `sTypoAscender' field */
-  /*                              of the OS/2 table instead if you want    */
+  /*                              of the `OS/2' table instead if you want  */
   /*                              the correct one.                         */
   /*                                                                       */
   /*    Descender              :: The font's descender, i.e., the distance */
@@ -145,7 +146,7 @@
   /*                              glyphs found in the font (maybe ASCII).  */
   /*                                                                       */
   /*                              You should use the `sTypoDescender'      */
-  /*                              field of the OS/2 table instead if you   */
+  /*                              field of the `OS/2' table instead if you */
   /*                              want the correct one.                    */
   /*                                                                       */
   /*    Line_Gap               :: The font's line gap, i.e., the distance  */
@@ -175,6 +176,8 @@
   /*    caret_Slope_Run        :: The run coefficient of the cursor's      */
   /*                              slope.                                   */
   /*                                                                       */
+  /*    caret_Offset           :: The cursor's offset for slanted fonts.   */
+  /*                                                                       */
   /*    Reserved               :: 8~reserved bytes.                        */
   /*                                                                       */
   /*    metric_Data_Format     :: Always~0.                                */
@@ -188,13 +191,10 @@
   /*    short_metrics          :: A pointer into the `hmtx' table.         */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
-  /*               be identical except for the names of their fields,      */
-  /*               which are different.                                    */
-  /*                                                                       */
-  /*               This ensures that a single function in the `ttload'     */
-  /*               module is able to read both the horizontal and vertical */
-  /*               headers.                                                */
+  /*    For an OpenType variation font, the values of the following fields */
+  /*    can change after a call to @FT_Set_Var_Design_Coordinates (and     */
+  /*    friends) if the font contains an `MVAR' table: `caret_Slope_Rise', */
+  /*    `caret_Slope_Run', and `caret_Offset'.                             */
   /*                                                                       */
   typedef struct  TT_HoriHeader_
   {
@@ -217,9 +217,9 @@
     FT_Short   metric_Data_Format;
     FT_UShort  number_Of_HMetrics;
 
-    /* The following fields are not defined by the TrueType specification */
+    /* The following fields are not defined by the OpenType specification */
     /* but they are used to connect the metrics header to the relevant    */
-    /* `HMTX' table.                                                      */
+    /* `hmtx' table.                                                      */
 
     void*      long_metrics;
     void*      short_metrics;
@@ -234,8 +234,8 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    A structure used to model a TrueType vertical header, the `vhea'   */
-  /*    table, as well as the corresponding vertical metrics table, i.e.,  */
-  /*    the `vmtx' table.                                                  */
+  /*    table, as well as the corresponding vertical metrics table,        */
+  /*    `vmtx'.                                                            */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    Version                 :: The table version.                      */
@@ -251,8 +251,8 @@
   /*                               ASCII).                                 */
   /*                                                                       */
   /*                               You should use the `sTypoAscender'      */
-  /*                               field of the OS/2 table instead if you  */
-  /*                               want the correct one.                   */
+  /*                               field of the `OS/2' table instead if    */
+  /*                               you want the correct one.               */
   /*                                                                       */
   /*    Descender               :: The font's descender, i.e., the         */
   /*                               distance from the baseline to the       */
@@ -266,8 +266,8 @@
   /*                               ASCII).                                 */
   /*                                                                       */
   /*                               You should use the `sTypoDescender'     */
-  /*                               field of the OS/2 table instead if you  */
-  /*                               want the correct one.                   */
+  /*                               field of the `OS/2' table instead if    */
+  /*                               you want the correct one.               */
   /*                                                                       */
   /*    Line_Gap                :: The font's line gap, i.e., the distance */
   /*                               to add to the ascender and descender to */
@@ -297,30 +297,26 @@
   /*                               slope.                                  */
   /*                                                                       */
   /*    caret_Offset            :: The cursor's offset for slanted fonts.  */
-  /*                               This value is `reserved' in vmtx        */
-  /*                               version 1.0.                            */
   /*                                                                       */
   /*    Reserved                :: 8~reserved bytes.                       */
   /*                                                                       */
   /*    metric_Data_Format      :: Always~0.                               */
   /*                                                                       */
-  /*    number_Of_HMetrics      :: Number of VMetrics entries in the       */
+  /*    number_Of_VMetrics      :: Number of VMetrics entries in the       */
   /*                               `vmtx' table -- this value can be       */
   /*                               smaller than the total number of glyphs */
   /*                               in the font.                            */
   /*                                                                       */
-  /*    long_metrics           :: A pointer into the `vmtx' table.         */
+  /*    long_metrics            :: A pointer into the `vmtx' table.        */
   /*                                                                       */
-  /*    short_metrics          :: A pointer into the `vmtx' table.         */
+  /*    short_metrics           :: A pointer into the `vmtx' table.        */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
-  /*               be identical except for the names of their fields,      */
-  /*               which are different.                                    */
-  /*                                                                       */
-  /*               This ensures that a single function in the `ttload'     */
-  /*               module is able to read both the horizontal and vertical */
-  /*               headers.                                                */
+  /*    For an OpenType variation font, the values of the following fields */
+  /*    can change after a call to @FT_Set_Var_Design_Coordinates (and     */
+  /*    friends) if the font contains an `MVAR' table: `Ascender',         */
+  /*    `Descender', `Line_Gap', `caret_Slope_Rise', `caret_Slope_Run',    */
+  /*    and `caret_Offset'.                                                */
   /*                                                                       */
   typedef struct  TT_VertHeader_
   {
@@ -331,9 +327,9 @@
 
     FT_UShort  advance_Height_Max;      /* advance height maximum */
 
-    FT_Short   min_Top_Side_Bearing;    /* minimum left-sb or top-sb       */
-    FT_Short   min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb   */
-    FT_Short   yMax_Extent;             /* xmax or ymax extents            */
+    FT_Short   min_Top_Side_Bearing;    /* minimum top-sb          */
+    FT_Short   min_Bottom_Side_Bearing; /* minimum bottom-sb       */
+    FT_Short   yMax_Extent;             /* ymax extents            */
     FT_Short   caret_Slope_Rise;
     FT_Short   caret_Slope_Run;
     FT_Short   caret_Offset;
@@ -343,9 +339,9 @@
     FT_Short   metric_Data_Format;
     FT_UShort  number_Of_VMetrics;
 
-    /* The following fields are not defined by the TrueType specification */
-    /* but they're used to connect the metrics header to the relevant     */
-    /* `HMTX' or `VMTX' table.                                            */
+    /* The following fields are not defined by the OpenType specification */
+    /* but they are used to connect the metrics header to the relevant    */
+    /* `vmtx' table.                                                      */
 
     void*      long_metrics;
     void*      short_metrics;
@@ -359,12 +355,28 @@
   /*    TT_OS2                                                             */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a TrueType OS/2 table.  All fields       */
-  /*    comply to the OpenType specification.                              */
+  /*    A structure to model a TrueType `OS/2' table.  All fields comply   */
+  /*    to the OpenType specification.                                     */
   /*                                                                       */
-  /*    Note that we now support old Mac fonts that do not include an OS/2 */
-  /*    table.  In this case, the `version' field is always set to 0xFFFF. */
+  /*    Note that we now support old Mac fonts that do not include an      */
+  /*    `OS/2' table.  In this case, the `version' field is always set to  */
+  /*    0xFFFF.                                                            */
   /*                                                                       */
+  /* <Note>                                                                */
+  /*    For an OpenType variation font, the values of the following fields */
+  /*    can change after a call to @FT_Set_Var_Design_Coordinates (and     */
+  /*    friends) if the font contains an `MVAR' table: `sCapHeight',       */
+  /*    `sTypoAscender', `sTypoDescender', `sTypoLineGap', `sxHeight',     */
+  /*    `usWinAscent', `usWinDescent', `yStrikeoutPosition',               */
+  /*    `yStrikeoutSize', `ySubscriptXOffset', `ySubScriptXSize',          */
+  /*    `ySubscriptYOffset', `ySubscriptYSize', `ySuperscriptXOffset',     */
+  /*    `ySuperscriptXSize', `ySuperscriptYOffset', and                    */
+  /*    `ySuperscriptYSize'.                                               */
+  /*                                                                       */
+  /*    Possible values for bits in the `ulUnicodeRangeX' fields are given */
+  /*    by the @TT_UCR_XXX macros.                                         */
+  /*                                                                       */
+
   typedef struct  TT_OS2_
   {
     FT_UShort  version;                /* 0x0001 - more or 0xFFFF */
@@ -429,10 +441,16 @@
   /*    TT_Postscript                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a TrueType PostScript table.  All fields */
-  /*    comply to the TrueType specification.  This structure does not     */
-  /*    reference the PostScript glyph names, which can be nevertheless    */
-  /*    accessed with the `ttpost' module.                                 */
+  /*    A structure to model a TrueType `post' table.  All fields comply   */
+  /*    to the OpenType specification.  This structure does not reference  */
+  /*    a font's PostScript glyph names; use @FT_Get_Glyph_Name to         */
+  /*    retrieve them.                                                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    For an OpenType variation font, the values of the following fields */
+  /*    can change after a call to @FT_Set_Var_Design_Coordinates (and     */
+  /*    friends) if the font contains an `MVAR' table: `underlinePosition' */
+  /*    and `underlineThickness'.                                          */
   /*                                                                       */
   typedef struct  TT_Postscript_
   {
@@ -446,8 +464,8 @@
     FT_ULong  minMemType1;
     FT_ULong  maxMemType1;
 
-    /* Glyph names follow in the file, but we don't   */
-    /* load them by default.  See the ttpost.c file.  */
+    /* Glyph names follow in the `post' table, but we don't */
+    /* load them by default.                                */
 
   } TT_Postscript;
 
@@ -458,8 +476,8 @@
   /*    TT_PCLT                                                            */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    A structure used to model a TrueType PCLT table.  All fields       */
-  /*    comply to the TrueType specification.                              */
+  /*    A structure to model a TrueType `PCLT' table.  All fields comply   */
+  /*    to the OpenType specification.                                     */
   /*                                                                       */
   typedef struct  TT_PCLT_
   {
@@ -488,9 +506,9 @@
   /*    TT_MaxProfile                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    The maximum profile is a table containing many max values, which   */
-  /*    can be used to pre-allocate arrays.  This ensures that no memory   */
-  /*    allocation occurs during a glyph load.                             */
+  /*    The maximum profile (`maxp') table contains many max values, which */
+  /*    can be used to pre-allocate arrays for speeding up glyph loading   */
+  /*    and hinting.                                                       */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    version               :: The version number.                       */
@@ -500,21 +518,19 @@
   /*                                                                       */
   /*    maxPoints             :: The maximum number of points in a         */
   /*                             non-composite TrueType glyph.  See also   */
-  /*                             the structure element                     */
   /*                             `maxCompositePoints'.                     */
   /*                                                                       */
   /*    maxContours           :: The maximum number of contours in a       */
   /*                             non-composite TrueType glyph.  See also   */
-  /*                             the structure element                     */
   /*                             `maxCompositeContours'.                   */
   /*                                                                       */
   /*    maxCompositePoints    :: The maximum number of points in a         */
-  /*                             composite TrueType glyph.  See also the   */
-  /*                             structure element `maxPoints'.            */
+  /*                             composite TrueType glyph.  See also       */
+  /*                             `maxPoints'.                              */
   /*                                                                       */
   /*    maxCompositeContours  :: The maximum number of contours in a       */
-  /*                             composite TrueType glyph.  See also the   */
-  /*                             structure element `maxContours'.          */
+  /*                             composite TrueType glyph.  See also       */
+  /*                             `maxContours'.                            */
   /*                                                                       */
   /*    maxZones              :: The maximum number of zones used for      */
   /*                             glyph hinting.                            */
@@ -575,8 +591,9 @@
   /*    FT_Sfnt_Tag                                                        */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    An enumeration used to specify the index of an SFNT table.         */
-  /*    Used in the @FT_Get_Sfnt_Table API function.                       */
+  /*    An enumeration to specify indices of SFNT tables loaded and parsed */
+  /*    by FreeType during initialization of an SFNT font.  Used in the    */
+  /*    @FT_Get_Sfnt_Table API function.                                   */
   /*                                                                       */
   /* <Values>                                                              */
   /*    FT_SFNT_HEAD :: To access the font's @TT_Header structure.         */
@@ -624,7 +641,7 @@
   /*    FT_Get_Sfnt_Table                                                  */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Return a pointer to a given SFNT table within a face.              */
+  /*    Return a pointer to a given SFNT table stored within a face.       */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face :: A handle to the source.                                    */
@@ -632,7 +649,7 @@
   /*    tag  :: The index of the SFNT table.                               */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    A type-less pointer to the table.  This will be~0 in case of       */
+  /*    A type-less pointer to the table.  This will be NULL in case of    */
   /*    error, or if the corresponding table was not found *OR* loaded     */
   /*    from the file.                                                     */
   /*                                                                       */
@@ -661,70 +678,70 @@
                      FT_Sfnt_Tag  tag );
 
 
- /**************************************************************************
-  *
-  * @function:
-  *   FT_Load_Sfnt_Table
-  *
-  * @description:
-  *   Load any font table into client memory.
-  *
-  * @input:
-  *   face ::
-  *     A handle to the source face.
-  *
-  *   tag ::
-  *     The four-byte tag of the table to load.  Use the value~0 if you want
-  *     to access the whole font file.  Otherwise, you can use one of the
-  *     definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new
-  *     one with @FT_MAKE_TAG.
-  *
-  *   offset ::
-  *     The starting offset in the table (or file if tag == 0).
-  *
-  * @output:
-  *   buffer ::
-  *     The target buffer address.  The client must ensure that the memory
-  *     array is big enough to hold the data.
-  *
-  * @inout:
-  *   length ::
-  *     If the `length' parameter is NULL, then try to load the whole table.
-  *     Return an error code if it fails.
-  *
-  *     Else, if `*length' is~0, exit immediately while returning the
-  *     table's (or file) full size in it.
-  *
-  *     Else the number of bytes to read from the table or file, from the
-  *     starting offset.
-  *
-  * @return:
-  *   FreeType error code.  0~means success.
-  *
-  * @note:
-  *   If you need to determine the table's length you should first call this
-  *   function with `*length' set to~0, as in the following example:
-  *
-  *     {
-  *       FT_ULong  length = 0;
-  *
-  *
-  *       error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length );
-  *       if ( error ) { ... table does not exist ... }
-  *
-  *       buffer = malloc( length );
-  *       if ( buffer == NULL ) { ... not enough memory ... }
-  *
-  *       error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length );
-  *       if ( error ) { ... could not load table ... }
-  *     }
-  *
-  *   Note that structures like @TT_Header or @TT_OS2 can't be used with
-  *   this function; they are limited to @FT_Get_Sfnt_Table.  Reason is that
-  *   those structures depend on the processor architecture, with varying
-  *   size (e.g. 32bit vs. 64bit) or order (big endian vs. little endian).
-  *
-  */
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Load_Sfnt_Table
+   *
+   * @description:
+   *   Load any SFNT font table into client memory.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the source face.
+   *
+   *   tag ::
+   *     The four-byte tag of the table to load.  Use value~0 if you want
+   *     to access the whole font file.  Otherwise, you can use one of the
+   *     definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new
+   *     one with @FT_MAKE_TAG.
+   *
+   *   offset ::
+   *     The starting offset in the table (or file if tag~==~0).
+   *
+   * @output:
+   *   buffer ::
+   *     The target buffer address.  The client must ensure that the memory
+   *     array is big enough to hold the data.
+   *
+   * @inout:
+   *   length ::
+   *     If the `length' parameter is NULL, try to load the whole table.
+   *     Return an error code if it fails.
+   *
+   *     Else, if `*length' is~0, exit immediately while returning the
+   *     table's (or file) full size in it.
+   *
+   *     Else the number of bytes to read from the table or file, from the
+   *     starting offset.
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   If you need to determine the table's length you should first call this
+   *   function with `*length' set to~0, as in the following example:
+   *
+   *     {
+   *       FT_ULong  length = 0;
+   *
+   *
+   *       error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length );
+   *       if ( error ) { ... table does not exist ... }
+   *
+   *       buffer = malloc( length );
+   *       if ( buffer == NULL ) { ... not enough memory ... }
+   *
+   *       error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length );
+   *       if ( error ) { ... could not load table ... }
+   *     }
+   *
+   *   Note that structures like @TT_Header or @TT_OS2 can't be used with
+   *   this function; they are limited to @FT_Get_Sfnt_Table.  Reason is that
+   *   those structures depend on the processor architecture, with varying
+   *   size (e.g. 32bit vs. 64bit) or order (big endian vs. little endian).
+   *
+   */
   FT_EXPORT( FT_Error )
   FT_Load_Sfnt_Table( FT_Face    face,
                       FT_ULong   tag,
@@ -733,41 +750,41 @@
                       FT_ULong*  length );
 
 
- /**************************************************************************
-  *
-  * @function:
-  *   FT_Sfnt_Table_Info
-  *
-  * @description:
-  *   Return information on an SFNT table.
-  *
-  * @input:
-  *   face ::
-  *     A handle to the source face.
-  *
-  *   table_index ::
-  *     The index of an SFNT table.  The function returns
-  *     FT_Err_Table_Missing for an invalid value.
-  *
-  * @inout:
-  *   tag ::
-  *     The name tag of the SFNT table.  If the value is NULL, `table_index'
-  *     is ignored, and `length' returns the number of SFNT tables in the
-  *     font.
-  *
-  * @output:
-  *   length ::
-  *     The length of the SFNT table (or the number of SFNT tables, depending
-  *     on `tag').
-  *
-  * @return:
-  *   FreeType error code.  0~means success.
-  *
-  * @note:
-  *   While parsing fonts, FreeType handles SFNT tables with length zero as
-  *   missing.
-  *
-  */
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Sfnt_Table_Info
+   *
+   * @description:
+   *   Return information on an SFNT table.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the source face.
+   *
+   *   table_index ::
+   *     The index of an SFNT table.  The function returns
+   *     FT_Err_Table_Missing for an invalid value.
+   *
+   * @inout:
+   *   tag ::
+   *     The name tag of the SFNT table.  If the value is NULL, `table_index'
+   *     is ignored, and `length' returns the number of SFNT tables in the
+   *     font.
+   *
+   * @output:
+   *   length ::
+   *     The length of the SFNT table (or the number of SFNT tables, depending
+   *     on `tag').
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   While parsing fonts, FreeType handles SFNT tables with length zero as
+   *   missing.
+   *
+   */
   FT_EXPORT( FT_Error )
   FT_Sfnt_Table_Info( FT_Face    face,
                       FT_UInt    table_index,
@@ -781,16 +798,16 @@
   /*    FT_Get_CMap_Language_ID                                            */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Return TrueType/sfnt specific cmap language ID.  Definitions of    */
-  /*    language ID values are in `ttnameid.h'.                            */
+  /*    Return cmap language ID as specified in the OpenType standard.     */
+  /*    Definitions of language ID values are in file @FT_TRUETYPE_IDS_H.  */
   /*                                                                       */
   /* <Input>                                                               */
   /*    charmap ::                                                         */
   /*      The target charmap.                                              */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    The language ID of `charmap'.  If `charmap' doesn't belong to a    */
-  /*    TrueType/sfnt face, just return~0 as the default value.            */
+  /*    The language ID of `charmap'.  If `charmap' doesn't belong to an   */
+  /*    SFNT face, just return~0 as the default value.                     */
   /*                                                                       */
   /*    For a format~14 cmap (to access Unicode IVS), the return value is  */
   /*    0xFFFFFFFF.                                                        */
@@ -805,15 +822,15 @@
   /*    FT_Get_CMap_Format                                                 */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Return TrueType/sfnt specific cmap format.                         */
+  /*    Return the format of an SFNT `cmap' table.                         */
   /*                                                                       */
   /* <Input>                                                               */
   /*    charmap ::                                                         */
   /*      The target charmap.                                              */
   /*                                                                       */
   /* <Return>                                                              */
-  /*    The format of `charmap'.  If `charmap' doesn't belong to a         */
-  /*    TrueType/sfnt face, return -1.                                     */
+  /*    The format of `charmap'.  If `charmap' doesn't belong to an SFNT   */
+  /*    face, return -1.                                                   */
   /*                                                                       */
   FT_EXPORT( FT_Long )
   FT_Get_CMap_Format( FT_CharMap  charmap );
diff --git a/include/freetype/tttags.h b/include/freetype/tttags.h
index f3c9aa5..32eb2fd 100644
--- a/include/freetype/tttags.h
+++ b/include/freetype/tttags.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Tags for TrueType and OpenType tables (specification only).          */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -43,6 +43,7 @@
 #define TTAG_CBDT  FT_MAKE_TAG( 'C', 'B', 'D', 'T' )
 #define TTAG_CBLC  FT_MAKE_TAG( 'C', 'B', 'L', 'C' )
 #define TTAG_CFF   FT_MAKE_TAG( 'C', 'F', 'F', ' ' )
+#define TTAG_CFF2  FT_MAKE_TAG( 'C', 'F', 'F', '2' )
 #define TTAG_CID   FT_MAKE_TAG( 'C', 'I', 'D', ' ' )
 #define TTAG_cmap  FT_MAKE_TAG( 'c', 'm', 'a', 'p' )
 #define TTAG_cvar  FT_MAKE_TAG( 'c', 'v', 'a', 'r' )
@@ -61,6 +62,7 @@
 #define TTAG_GPOS  FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
 #define TTAG_GSUB  FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
 #define TTAG_gvar  FT_MAKE_TAG( 'g', 'v', 'a', 'r' )
+#define TTAG_HVAR  FT_MAKE_TAG( 'H', 'V', 'A', 'R' )
 #define TTAG_hdmx  FT_MAKE_TAG( 'h', 'd', 'm', 'x' )
 #define TTAG_head  FT_MAKE_TAG( 'h', 'e', 'a', 'd' )
 #define TTAG_hhea  FT_MAKE_TAG( 'h', 'h', 'e', 'a' )
@@ -79,6 +81,7 @@
 #define TTAG_MMSD  FT_MAKE_TAG( 'M', 'M', 'S', 'D' )
 #define TTAG_mort  FT_MAKE_TAG( 'm', 'o', 'r', 't' )
 #define TTAG_morx  FT_MAKE_TAG( 'm', 'o', 'r', 'x' )
+#define TTAG_MVAR  FT_MAKE_TAG( 'M', 'V', 'A', 'R' )
 #define TTAG_name  FT_MAKE_TAG( 'n', 'a', 'm', 'e' )
 #define TTAG_opbd  FT_MAKE_TAG( 'o', 'p', 'b', 'd' )
 #define TTAG_OS2   FT_MAKE_TAG( 'O', 'S', '/', '2' )
@@ -100,6 +103,7 @@
 #define TTAG_VDMX  FT_MAKE_TAG( 'V', 'D', 'M', 'X' )
 #define TTAG_vhea  FT_MAKE_TAG( 'v', 'h', 'e', 'a' )
 #define TTAG_vmtx  FT_MAKE_TAG( 'v', 'm', 't', 'x' )
+#define TTAG_VVAR  FT_MAKE_TAG( 'V', 'V', 'A', 'R' )
 #define TTAG_wOFF  FT_MAKE_TAG( 'w', 'O', 'F', 'F' )
 
 
diff --git a/include/freetype/ttunpat.h b/include/freetype/ttunpat.h
index ca4676b..11f6ded 100644
--- a/include/freetype/ttunpat.h
+++ b/include/freetype/ttunpat.h
@@ -5,7 +5,7 @@
 /*    Definitions for the unpatented TrueType hinting system.              */
 /*    Obsolete, retained for backwards compatibility.                      */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  Written by Graham Asher <graham.asher@btinternet.com>                  */
diff --git a/include/ft2build.h b/include/ft2build.h
index c89cb46..e7d808f 100644
--- a/include/ft2build.h
+++ b/include/ft2build.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType 2 build and setup macros.                                   */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afangles.c b/src/autofit/afangles.c
index b856e57..ccdae84 100644
--- a/src/autofit/afangles.c
+++ b/src/autofit/afangles.c
@@ -5,7 +5,7 @@
 /*    Routines used to compute vector angles with limited accuracy         */
 /*    and very high speed.  It also contains sorting routines (body).      */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afblue.c b/src/autofit/afblue.c
index 7719c02..524f688 100644
--- a/src/autofit/afblue.c
+++ b/src/autofit/afblue.c
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (body).                            */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -168,7 +168,9 @@
     '\0',
     'f', ' ', 'i', ' ', 'j', ' ', 'k', ' ', 'd', ' ', 'b', ' ', 'h',  /* f i j k d b h */
     '\0',
-    'x', ' ', 'z', ' ', 'r', ' ', 'o', ' ', 'e', ' ', 's', ' ', 'c',  /* x z r o e s c */
+    'u', ' ', 'v', ' ', 'x', ' ', 'z', ' ', 'o', ' ', 'e', ' ', 's', ' ', 'c',  /* u v x z o e s c */
+    '\0',
+    'n', ' ', 'r', ' ', 'x', ' ', 'z', ' ', 'o', ' ', 'e', ' ', 's', ' ', 'c',  /* n r x z o e s c */
     '\0',
     'p', ' ', 'q', ' ', 'g', ' ', 'j', ' ', 'y',  /* p q g j y */
     '\0',
@@ -392,9 +394,9 @@
     { AF_BLUE_STRING_LATIN_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
     { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM,  0                                 },
     { AF_BLUE_STRING_LATIN_SMALL_F_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
-    { AF_BLUE_STRING_LATIN_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
+    { AF_BLUE_STRING_LATIN_SMALL_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
                                             AF_BLUE_PROPERTY_LATIN_X_HEIGHT   },
-    { AF_BLUE_STRING_LATIN_SMALL,           0                                 },
+    { AF_BLUE_STRING_LATIN_SMALL_BOTTOM,    0                                 },
     { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0                                 },
     { AF_BLUE_STRING_MAX,                   0                                 },
     { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        },
diff --git a/src/autofit/afblue.cin b/src/autofit/afblue.cin
index 0c3cae8..f9080c5 100644
--- a/src/autofit/afblue.cin
+++ b/src/autofit/afblue.cin
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (body).                            */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afblue.dat b/src/autofit/afblue.dat
index f5f04f2..8b75aec 100644
--- a/src/autofit/afblue.dat
+++ b/src/autofit/afblue.dat
@@ -2,7 +2,7 @@
 //
 //    Auto-fitter data for blue strings.
 //
-//  Copyright 2013-2016 by
+//  Copyright 2013-2017 by
 //  David Turner, Robert Wilhelm, and Werner Lemberg.
 //
 //  This file is part of the FreeType project, and may only be used,
@@ -242,8 +242,10 @@
     "H E Z L O C U S"
   AF_BLUE_STRING_LATIN_SMALL_F_TOP
     "f i j k d b h"
-  AF_BLUE_STRING_LATIN_SMALL
-    "x z r o e s c"
+  AF_BLUE_STRING_LATIN_SMALL_TOP
+    "u v x z o e s c"
+  AF_BLUE_STRING_LATIN_SMALL_BOTTOM
+    "n r x z o e s c"
   AF_BLUE_STRING_LATIN_SMALL_DESCENDER
     "p q g j y"
 
@@ -630,9 +632,9 @@
     { AF_BLUE_STRING_LATIN_CAPITAL_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
     { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM,  0                                 }
     { AF_BLUE_STRING_LATIN_SMALL_F_TOP,     AF_BLUE_PROPERTY_LATIN_TOP        }
-    { AF_BLUE_STRING_LATIN_SMALL,           AF_BLUE_PROPERTY_LATIN_TOP      |
+    { AF_BLUE_STRING_LATIN_SMALL_TOP,       AF_BLUE_PROPERTY_LATIN_TOP      |
                                             AF_BLUE_PROPERTY_LATIN_X_HEIGHT   }
-    { AF_BLUE_STRING_LATIN_SMALL,           0                                 }
+    { AF_BLUE_STRING_LATIN_SMALL_BOTTOM,    0                                 }
     { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0                                 }
     { AF_BLUE_STRING_MAX,                   0                                 }
 
diff --git a/src/autofit/afblue.h b/src/autofit/afblue.h
index 75c3ab5..f4720ed 100644
--- a/src/autofit/afblue.h
+++ b/src/autofit/afblue.h
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (specification).                   */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -148,39 +148,40 @@
     AF_BLUE_STRING_LATIN_CAPITAL_TOP = 1852,
     AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 1868,
     AF_BLUE_STRING_LATIN_SMALL_F_TOP = 1884,
-    AF_BLUE_STRING_LATIN_SMALL = 1898,
-    AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 1912,
-    AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 1922,
-    AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 1942,
-    AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 1962,
-    AF_BLUE_STRING_LATIN_SUBS_SMALL = 1982,
-    AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 2018,
-    AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 2038,
-    AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 2069,
-    AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 2098,
-    AF_BLUE_STRING_LATIN_SUPS_SMALL = 2124,
-    AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 2149,
-    AF_BLUE_STRING_MALAYALAM_TOP = 2160,
-    AF_BLUE_STRING_MALAYALAM_BOTTOM = 2204,
-    AF_BLUE_STRING_MYANMAR_TOP = 2236,
-    AF_BLUE_STRING_MYANMAR_BOTTOM = 2268,
-    AF_BLUE_STRING_MYANMAR_ASCENDER = 2300,
-    AF_BLUE_STRING_MYANMAR_DESCENDER = 2328,
-    AF_BLUE_STRING_SINHALA_TOP = 2360,
-    AF_BLUE_STRING_SINHALA_BOTTOM = 2392,
-    AF_BLUE_STRING_SINHALA_DESCENDER = 2424,
-    AF_BLUE_STRING_TAMIL_TOP = 2468,
-    AF_BLUE_STRING_TAMIL_BOTTOM = 2500,
-    AF_BLUE_STRING_TELUGU_TOP = 2532,
-    AF_BLUE_STRING_TELUGU_BOTTOM = 2560,
-    AF_BLUE_STRING_THAI_TOP = 2588,
-    AF_BLUE_STRING_THAI_BOTTOM = 2612,
-    AF_BLUE_STRING_THAI_ASCENDER = 2640,
-    AF_BLUE_STRING_THAI_LARGE_ASCENDER = 2652,
-    AF_BLUE_STRING_THAI_DESCENDER = 2664,
-    AF_BLUE_STRING_THAI_LARGE_DESCENDER = 2680,
-    AF_BLUE_STRING_THAI_DIGIT_TOP = 2688,
-    af_blue_1_1 = 2699,
+    AF_BLUE_STRING_LATIN_SMALL_TOP = 1898,
+    AF_BLUE_STRING_LATIN_SMALL_BOTTOM = 1914,
+    AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 1930,
+    AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 1940,
+    AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 1960,
+    AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 1980,
+    AF_BLUE_STRING_LATIN_SUBS_SMALL = 2000,
+    AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 2036,
+    AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 2056,
+    AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 2087,
+    AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 2116,
+    AF_BLUE_STRING_LATIN_SUPS_SMALL = 2142,
+    AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 2167,
+    AF_BLUE_STRING_MALAYALAM_TOP = 2178,
+    AF_BLUE_STRING_MALAYALAM_BOTTOM = 2222,
+    AF_BLUE_STRING_MYANMAR_TOP = 2254,
+    AF_BLUE_STRING_MYANMAR_BOTTOM = 2286,
+    AF_BLUE_STRING_MYANMAR_ASCENDER = 2318,
+    AF_BLUE_STRING_MYANMAR_DESCENDER = 2346,
+    AF_BLUE_STRING_SINHALA_TOP = 2378,
+    AF_BLUE_STRING_SINHALA_BOTTOM = 2410,
+    AF_BLUE_STRING_SINHALA_DESCENDER = 2442,
+    AF_BLUE_STRING_TAMIL_TOP = 2486,
+    AF_BLUE_STRING_TAMIL_BOTTOM = 2518,
+    AF_BLUE_STRING_TELUGU_TOP = 2550,
+    AF_BLUE_STRING_TELUGU_BOTTOM = 2578,
+    AF_BLUE_STRING_THAI_TOP = 2606,
+    AF_BLUE_STRING_THAI_BOTTOM = 2630,
+    AF_BLUE_STRING_THAI_ASCENDER = 2658,
+    AF_BLUE_STRING_THAI_LARGE_ASCENDER = 2670,
+    AF_BLUE_STRING_THAI_DESCENDER = 2682,
+    AF_BLUE_STRING_THAI_LARGE_DESCENDER = 2698,
+    AF_BLUE_STRING_THAI_DIGIT_TOP = 2706,
+    af_blue_1_1 = 2717,
 #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,
diff --git a/src/autofit/afblue.hin b/src/autofit/afblue.hin
index dd44e77..268bcbc 100644
--- a/src/autofit/afblue.hin
+++ b/src/autofit/afblue.hin
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter data for blue strings (specification).                   */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 4823c1d..f172a9f 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for CJK writing system (body).          */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -563,7 +563,7 @@
                                FT_Face        face )
   {
     FT_Bool   started = 0, same_width = 1;
-    FT_Fixed  advance, old_advance = 0;
+    FT_Fixed  advance = 0, old_advance = 0;
 
     void*  shaper_buf;
 
@@ -2351,13 +2351,13 @@
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init,
-    (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths,
+    (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init,        /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale,       /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                       /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_cjk_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_cjk_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_cjk_hints_init,          /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_cjk_hints_apply          /* style_hints_apply     */
   )
 
 
@@ -2371,13 +2371,13 @@
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) NULL,
-    (AF_WritingSystem_ScaleMetricsFunc)NULL,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)NULL,
+    (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   NULL,
-    (AF_WritingSystem_ApplyHintsFunc)  NULL
+    (AF_WritingSystem_InitHintsFunc)   NULL, /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  NULL  /* style_hints_apply     */
   )
 
 
diff --git a/src/autofit/afcjk.h b/src/autofit/afcjk.h
index 40d1184..84f892f 100644
--- a/src/autofit/afcjk.h
+++ b/src/autofit/afcjk.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for CJK writing system (specification). */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afcover.h b/src/autofit/afcover.h
index 1c39a70..1b18c66 100644
--- a/src/autofit/afcover.h
+++ b/src/autofit/afcover.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter coverages (specification only).                          */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afdummy.c b/src/autofit/afdummy.c
index f3960c8..61c32db 100644
--- a/src/autofit/afdummy.c
+++ b/src/autofit/afdummy.c
@@ -5,7 +5,7 @@
 /*    Auto-fitter dummy routines to be used if no hinting should be        */
 /*    performed (body).                                                    */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -62,13 +62,13 @@
 
     sizeof ( AF_StyleMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) NULL,
-    (AF_WritingSystem_ScaleMetricsFunc)NULL,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)NULL,
+    (AF_WritingSystem_InitMetricsFunc) NULL,                /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)NULL,                /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)NULL,                /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_dummy_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_dummy_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_dummy_hints_init, /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_dummy_hints_apply /* style_hints_apply     */
   )
 
 
diff --git a/src/autofit/afdummy.h b/src/autofit/afdummy.h
index 7e58d1a..ebaa7d7 100644
--- a/src/autofit/afdummy.h
+++ b/src/autofit/afdummy.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter dummy routines to be used if no hinting should be        */
 /*    performed (specification).                                           */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/aferrors.h b/src/autofit/aferrors.h
index 53c01f6..dde182f 100644
--- a/src/autofit/aferrors.h
+++ b/src/autofit/aferrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Autofitter error codes (specification only).                         */
 /*                                                                         */
-/*  Copyright 2005-2016 by                                                 */
+/*  Copyright 2005-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c
index ac6dcaf..85bef00 100644
--- a/src/autofit/afglobal.c
+++ b/src/autofit/afglobal.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter routines to compute global hinting values (body).        */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -168,7 +168,7 @@
       AF_Script_UniRange  range;
 
 
-      if ( script_class->script_uni_ranges == NULL )
+      if ( !script_class->script_uni_ranges )
         continue;
 
       /*
@@ -411,23 +411,11 @@
 
 #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
       hb_font_destroy( globals->hb_font );
-      globals->hb_font = NULL;
-
       hb_buffer_destroy( globals->hb_buf );
-      globals->hb_buf = NULL;
 #endif
 
-      globals->glyph_count               = 0;
-      globals->stem_darkening_for_ppem   = 0;
-      globals->darken_x                  = 0;
-      globals->darken_y                  = 0;
-      globals->standard_vertical_width   = 0;
-      globals->standard_horizontal_width = 0;
-      globals->scale_down_factor         = 0;
-      /* no need to free this one! */
-      globals->glyph_styles              = NULL;
-      globals->face                      = NULL;
-
+      /* no need to free `globals->glyph_styles'; */
+      /* it is part of the `globals' array        */
       FT_FREE( globals );
     }
   }
@@ -465,7 +453,7 @@
                              [style_class->writing_system];
 
     metrics = globals->metrics[style];
-    if ( metrics == NULL )
+    if ( !metrics )
     {
       /* create the global metrics object if necessary */
       FT_Memory  memory = globals->face->memory;
diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h
index ce6b9e8..de6142e 100644
--- a/src/autofit/afglobal.h
+++ b/src/autofit/afglobal.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter routines to compute global hinting values                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afhints.c b/src/autofit/afhints.c
index 0f7f6e5..f1ff0ba 100644
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines (body).                                 */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -45,7 +45,7 @@
 
     if ( axis->num_segments < AF_SEGMENTS_EMBEDDED )
     {
-      if ( axis->segments == NULL )
+      if ( !axis->segments )
       {
         axis->segments     = axis->embedded.segments;
         axis->max_segments = AF_SEGMENTS_EMBEDDED;
@@ -110,7 +110,7 @@
 
     if ( axis->num_edges < AF_EDGES_EMBEDDED )
     {
-      if ( axis->edges == NULL )
+      if ( !axis->edges )
       {
         axis->edges     = axis->embedded.edges;
         axis->max_edges = AF_EDGES_EMBEDDED;
@@ -743,7 +743,7 @@
 
     if ( new_max <= AF_CONTOURS_EMBEDDED )
     {
-      if ( hints->contours == NULL )
+      if ( !hints->contours )
       {
         hints->contours     = hints->embedded.contours;
         hints->max_contours = AF_CONTOURS_EMBEDDED;
@@ -772,7 +772,7 @@
 
     if ( new_max <= AF_POINTS_EMBEDDED )
     {
-      if ( hints->points == NULL )
+      if ( !hints->points )
       {
         hints->points     = hints->embedded.points;
         hints->max_points = AF_POINTS_EMBEDDED;
@@ -1182,7 +1182,7 @@
         AF_Point  point, first, last;
 
 
-        if ( edge == NULL )
+        if ( !edge )
           continue;
 
         first = seg->first;
@@ -1208,7 +1208,7 @@
         AF_Point  point, first, last;
 
 
-        if ( edge == NULL )
+        if ( !edge )
           continue;
 
         first = seg->first;
diff --git a/src/autofit/afhints.h b/src/autofit/afhints.h
index 4fdf732..16638b1 100644
--- a/src/autofit/afhints.h
+++ b/src/autofit/afhints.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines (specification).                        */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afindic.c b/src/autofit/afindic.c
index 097a2b2..03c611b 100644
--- a/src/autofit/afindic.c
+++ b/src/autofit/afindic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for Indic writing system (body).        */
 /*                                                                         */
-/*  Copyright 2007-2016 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.    */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -121,13 +121,13 @@
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init,
-    (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths,
+    (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init,        /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale,       /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                         /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_indic_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_indic_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_indic_hints_init,          /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_indic_hints_apply          /* style_hints_apply     */
   )
 
 
@@ -141,13 +141,13 @@
 
     sizeof ( AF_CJKMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) NULL,
-    (AF_WritingSystem_ScaleMetricsFunc)NULL,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)NULL,
+    (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   NULL,
-    (AF_WritingSystem_ApplyHintsFunc)  NULL
+    (AF_WritingSystem_InitHintsFunc)   NULL, /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  NULL  /* style_hints_apply     */
   )
 
 
diff --git a/src/autofit/afindic.h b/src/autofit/afindic.h
index 0772e07..ec9e263 100644
--- a/src/autofit/afindic.h
+++ b/src/autofit/afindic.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter hinting routines for Indic writing system                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2007-2016 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.    */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index db7aaff..7e6e8ea 100644
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for latin writing system (body).        */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -265,6 +265,45 @@
   }
 
 
+  void
+  af_latin_sort_blue( FT_UInt        count,
+                      AF_LatinBlue*  table )
+  {
+    FT_UInt       i, j;
+    AF_LatinBlue  swap;
+
+
+    /* we sort from bottom to top */
+    for ( i = 1; i < count; i++ )
+    {
+      for ( j = i; j > 0; j-- )
+      {
+        FT_Pos  a, b;
+
+
+        if ( table[j - 1]->flags & ( AF_LATIN_BLUE_TOP     |
+                                     AF_LATIN_BLUE_SUB_TOP ) )
+          a = table[j - 1]->ref.org;
+        else
+          a = table[j - 1]->shoot.org;
+
+        if ( table[j]->flags & ( AF_LATIN_BLUE_TOP     |
+                                 AF_LATIN_BLUE_SUB_TOP ) )
+          b = table[j]->ref.org;
+        else
+          b = table[j]->shoot.org;
+
+        if ( b >= a )
+          break;
+
+        swap         = table[j];
+        table[j]     = table[j - 1];
+        table[j - 1] = swap;
+      }
+    }
+  }
+
+
   /* Find all blue zones.  Flat segments give the reference points, */
   /* round segments the overshoot positions.                        */
 
@@ -928,6 +967,60 @@
 
     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 )
+    {
+      FT_UInt       i;
+      AF_LatinBlue  blue_sorted[AF_BLUE_STRINGSET_MAX_LEN + 2];
+
+
+      for ( i = 0; i < axis->blue_count; i++ )
+        blue_sorted[i] = &axis->blues[i];
+
+      /* sort bottoms of blue zones... */
+      af_latin_sort_blue( axis->blue_count, blue_sorted );
+
+      /* ...and adjust top values if necessary */
+      for ( i = 0; i < axis->blue_count - 1; i++ )
+      {
+        FT_Pos*  a;
+        FT_Pos*  b;
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+        FT_Bool  a_is_top = 0;
+#endif
+
+
+        if ( blue_sorted[i]->flags & ( AF_LATIN_BLUE_TOP     |
+                                       AF_LATIN_BLUE_SUB_TOP ) )
+        {
+          a = &blue_sorted[i]->shoot.org;
+#ifdef FT_DEBUG_LEVEL_TRACE
+          a_is_top = 1;
+#endif
+        }
+        else
+          a = &blue_sorted[i]->ref.org;
+
+        if ( blue_sorted[i + 1]->flags & ( AF_LATIN_BLUE_TOP     |
+                                           AF_LATIN_BLUE_SUB_TOP ) )
+          b = &blue_sorted[i + 1]->shoot.org;
+        else
+          b = &blue_sorted[i + 1]->ref.org;
+
+        if ( *a > *b )
+        {
+          *a = *b;
+          FT_TRACE5(( "blue zone overlap:"
+                      " adjusting %s %d to %ld\n",
+                      a_is_top ? "overshoot" : "reference",
+                      blue_sorted[i] - axis->blues,
+                      *a ));
+        }
+      }
+    }
+
     FT_TRACE5(( "\n" ));
 
     return;
@@ -941,7 +1034,7 @@
                                  FT_Face          face )
   {
     FT_Bool   started = 0, same_width = 1;
-    FT_Fixed  advance, old_advance = 0;
+    FT_Fixed  advance = 0, old_advance = 0;
 
     void*  shaper_buf;
 
@@ -1127,7 +1220,7 @@
                 "af_latin_metrics_scale_dim:"
                 " x height alignment (style `%s'):\n"
                 "                           "
-                " vertical scaling changed from %.4f to %.4f (by %d%%)\n"
+                " vertical scaling changed from %.5f to %.5f (by %d%%)\n"
                 "\n",
                 af_style_names[metrics->root.style_class->style],
                 scale / 65536.0,
@@ -1951,6 +2044,10 @@
     FT_Memory     memory = hints->memory;
     AF_LatinAxis  laxis  = &((AF_LatinMetrics)hints->metrics)->axis[dim];
 
+#ifdef FT_CONFIG_OPTION_PIC
+    AF_FaceGlobals  globals = hints->metrics->globals;
+#endif
+
     AF_StyleClass   style_class  = hints->metrics->style_class;
     AF_ScriptClass  script_class = AF_SCRIPT_CLASSES_GET
                                      [style_class->script];
@@ -2211,7 +2308,7 @@
                                 seg->serif->edge         &&
                                 seg->serif->edge != edge );
 
-          if ( ( seg->link && seg->link->edge != NULL ) || is_serif )
+          if ( ( seg->link && seg->link->edge ) || is_serif )
           {
             AF_Edge     edge2;
             AF_Segment  seg2;
@@ -2834,6 +2931,10 @@
     AF_Edge       anchor     = NULL;
     FT_Int        has_serifs = 0;
 
+#ifdef FT_CONFIG_OPTION_PIC
+    AF_FaceGlobals  globals = hints->metrics->globals;
+#endif
+
     AF_StyleClass   style_class  = hints->metrics->style_class;
     AF_ScriptClass  script_class = AF_SCRIPT_CLASSES_GET
                                      [style_class->script];
@@ -3477,13 +3578,13 @@
 
     sizeof ( AF_LatinMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init,
-    (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths,
+    (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init,        /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale,       /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                         /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_latin_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_latin_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_latin_hints_init,          /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_latin_hints_apply          /* style_hints_apply     */
   )
 
 
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index fe6bbd8..d80e125 100644
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -5,7 +5,7 @@
 /*    Auto-fitter hinting routines for latin writing system                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c
index 5db4a41..7048756 100644
--- a/src/autofit/aflatin2.c
+++ b/src/autofit/aflatin2.c
@@ -9,7 +9,7 @@
 /*                                                                         */
 /*    Auto-fitter hinting routines for latin writing system (body).        */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -1303,7 +1303,7 @@
                                 seg->serif->edge         &&
                                 seg->serif->edge != edge );
 
-          if ( ( seg->link && seg->link->edge != NULL ) || is_serif )
+          if ( ( seg->link && seg->link->edge ) || is_serif )
           {
             AF_Edge     edge2;
             AF_Segment  seg2;
@@ -2410,13 +2410,13 @@
 
     sizeof ( AF_LatinMetricsRec ),
 
-    (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init,
-    (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale,
-    (AF_WritingSystem_DoneMetricsFunc) NULL,
-    (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths,
+    (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init,        /* style_metrics_init    */
+    (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale,       /* style_metrics_scale   */
+    (AF_WritingSystem_DoneMetricsFunc) NULL,                          /* style_metrics_done    */
+    (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths, /* style_metrics_getstdw */
 
-    (AF_WritingSystem_InitHintsFunc)   af_latin2_hints_init,
-    (AF_WritingSystem_ApplyHintsFunc)  af_latin2_hints_apply
+    (AF_WritingSystem_InitHintsFunc)   af_latin2_hints_init,          /* style_hints_init      */
+    (AF_WritingSystem_ApplyHintsFunc)  af_latin2_hints_apply          /* style_hints_apply     */
   )
 
 
diff --git a/src/autofit/aflatin2.h b/src/autofit/aflatin2.h
index f83f704..2d0b154 100644
--- a/src/autofit/aflatin2.h
+++ b/src/autofit/aflatin2.h
@@ -10,7 +10,7 @@
 /*    Auto-fitter hinting routines for latin writing system                */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c
index 26bba06..1dd9462 100644
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter glyph loading routines (body).                           */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -51,7 +51,7 @@
     loader->face    = face;
     loader->globals = (AF_FaceGlobals)face->autohint.data;
 
-    if ( loader->globals == NULL )
+    if ( !loader->globals )
     {
       error = af_face_globals_new( face, &loader->globals, module );
       if ( !error )
@@ -86,161 +86,260 @@
           ( (FT_Fixed)( (f) * 65536.0 + 0.5 ) )
 
 
-  /* Do the main work of `af_loader_load_glyph'.  Note that we never   */
-  /* have to deal with composite glyphs as those get loaded into       */
-  /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */
-  /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies     */
-  /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called.     */
-
   static FT_Error
-  af_loader_load_g( AF_Loader  loader,
-                    AF_Scaler  scaler,
-                    FT_UInt    glyph_index,
-                    FT_Int32   load_flags )
+  af_loader_embolden_glyph_in_slot( AF_Loader        loader,
+                                    FT_Face          face,
+                                    AF_StyleMetrics  style_metrics )
   {
-    AF_Module  module = loader->globals->module;
+    FT_Error  error = FT_Err_Ok;
 
-    FT_Error          error;
-    FT_Face           face     = loader->face;
-    AF_StyleMetrics   metrics  = loader->metrics;
-    AF_GlyphHints     hints    = loader->hints;
+    FT_GlyphSlot           slot    = face->glyph;
+    AF_FaceGlobals         globals = loader->globals;
+    AF_WritingSystemClass  writing_system_class;
+
+    FT_Pos  stdVW = 0;
+    FT_Pos  stdHW = 0;
+
+    FT_Bool  size_changed = face->size->metrics.x_ppem
+                              != globals->stem_darkening_for_ppem;
+
+    FT_Fixed  em_size  = af_intToFixed( face->units_per_EM );
+    FT_Fixed  em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size );
+
+    FT_Matrix  scale_down_matrix = { 0x10000L, 0, 0, 0x10000L };
+
+
+    /* Skip stem darkening for broken fonts. */
+    if ( !face->units_per_EM )
+    {
+      error = FT_ERR( Corrupted_Font_Header );
+      goto Exit;
+    }
+
+    /*
+     *  We depend on the writing system (script analyzers) to supply
+     *  standard widths for the script of the glyph we are looking at.  If
+     *  it can't deliver, stem darkening is disabled.
+     */
+    writing_system_class =
+      AF_WRITING_SYSTEM_CLASSES_GET[style_metrics->style_class->writing_system];
+
+    if ( writing_system_class->style_metrics_getstdw )
+      writing_system_class->style_metrics_getstdw( style_metrics,
+                                                   &stdHW,
+                                                   &stdVW );
+    else
+    {
+      error = FT_ERR( Unimplemented_Feature );
+      goto Exit;
+    }
+
+    if ( size_changed                                               ||
+         ( stdVW > 0 && stdVW != globals->standard_vertical_width ) )
+    {
+      FT_Fixed  darken_by_font_units_x, darken_x;
+
+
+      darken_by_font_units_x =
+        af_intToFixed( af_loader_compute_darkening( loader,
+                                                    face,
+                                                    stdVW ) );
+      darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x,
+                                       face->size->metrics.x_scale ),
+                            em_ratio );
+
+      globals->standard_vertical_width = stdVW;
+      globals->stem_darkening_for_ppem = face->size->metrics.x_ppem;
+      globals->darken_x                = af_fixedToInt( darken_x );
+    }
+
+    if ( size_changed                                                 ||
+         ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) )
+    {
+      FT_Fixed  darken_by_font_units_y, darken_y;
+
+
+      darken_by_font_units_y =
+        af_intToFixed( af_loader_compute_darkening( loader,
+                                                    face,
+                                                    stdHW ) );
+      darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y,
+                                       face->size->metrics.y_scale ),
+                            em_ratio );
+
+      globals->standard_horizontal_width = stdHW;
+      globals->stem_darkening_for_ppem   = face->size->metrics.x_ppem;
+      globals->darken_y                  = af_fixedToInt( darken_y );
+
+      /*
+       *  Scale outlines down on the Y-axis to keep them inside their blue
+       *  zones.  The stronger the emboldening, the stronger the downscaling
+       *  (plus heuristical padding to prevent outlines still falling out
+       *  their zones due to rounding).
+       *
+       *  Reason: `FT_Outline_Embolden' works by shifting the rightmost
+       *  points of stems farther to the right, and topmost points farther
+       *  up.  This positions points on the Y-axis outside their
+       *  pre-computed blue zones and leads to distortion when applying the
+       *  hints in the code further below.  Code outside this emboldening
+       *  block doesn't know we are presenting it with modified outlines the
+       *  analyzer didn't see!
+       *
+       *  An unfortunate side effect of downscaling is that the emboldening
+       *  effect is slightly decreased.  The loss becomes more pronounced
+       *  versus the CFF driver at smaller sizes, e.g., at 9ppem and below.
+       */
+      globals->scale_down_factor =
+        FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ),
+                   em_size );
+    }
+
+    FT_Outline_EmboldenXY( &slot->outline,
+                           globals->darken_x,
+                           globals->darken_y );
+
+    scale_down_matrix.yy = globals->scale_down_factor;
+    FT_Outline_Transform( &slot->outline, &scale_down_matrix );
+
+  Exit:
+    return error;
+  }
+
+
+  /* Load the glyph at index into the current slot of a face and hint it. */
+
+  FT_LOCAL_DEF( FT_Error )
+  af_loader_load_glyph( AF_Loader  loader,
+                        AF_Module  module,
+                        FT_Face    face,
+                        FT_UInt    glyph_index,
+                        FT_Int32   load_flags )
+  {
+    FT_Error  error;
+
+    FT_Size           size     = face->size;
     FT_GlyphSlot      slot     = face->glyph;
     FT_Slot_Internal  internal = slot->internal;
     FT_GlyphLoader    gloader  = internal->loader;
-    FT_Int32          flags;
+
+    AF_GlyphHints          hints         = loader->hints;
+    AF_ScalerRec           scaler;
+    AF_StyleMetrics        style_metrics;
+    FT_UInt                style_options = AF_STYLE_NONE_DFLT;
+    AF_StyleClass          style_class;
+    AF_WritingSystemClass  writing_system_class;
+
+#ifdef FT_CONFIG_OPTION_PIC
+    AF_FaceGlobals  globals = loader->globals;
+#endif
 
 
-    flags = load_flags | FT_LOAD_LINEAR_DESIGN;
-    error = FT_Load_Glyph( face, glyph_index, flags );
+    if ( !size )
+      return FT_THROW( Invalid_Size_Handle );
+
+    FT_ZERO( &scaler );
+
+    /*
+     *  TODO: This code currently doesn't support fractional advance widths,
+     *  i.e., placing hinted glyphs at anything other than integer
+     *  x-positions.  This is only relevant for the warper code, which
+     *  scales and shifts glyphs to optimize blackness of stems (hinting on
+     *  the x-axis by nature places things on pixel integers, hinting on the
+     *  y-axis only, i.e., LIGHT mode, doesn't touch the x-axis).  The delta
+     *  values of the scaler would need to be adjusted.
+     */
+    scaler.face    = face;
+    scaler.x_scale = size->metrics.x_scale;
+    scaler.x_delta = 0;
+    scaler.y_scale = size->metrics.y_scale;
+    scaler.y_delta = 0;
+
+    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
+    scaler.flags       = 0;
+
+    /* note that the fallback style can't be changed anymore */
+    /* after the first call of `ta_loader_load_glyph'        */
+    error = af_loader_reset( loader, module, face );
+    if ( error )
+      goto Exit;
+
+#ifdef FT_OPTION_AUTOFIT2
+    /* XXX: undocumented hook to activate the latin2 writing system. */
+    if ( load_flags & ( 1UL << 20 ) )
+      style_options = AF_STYLE_LTN2_DFLT;
+#endif
+
+    /*
+     *  Glyphs (really code points) are assigned to scripts.  Script
+     *  analysis is done lazily: For each glyph that passes through here,
+     *  the corresponding script analyzer is called, but returns immediately
+     *  if it has been run already.
+     */
+    error = af_face_globals_get_metrics( loader->globals, glyph_index,
+                                         style_options, &style_metrics );
+    if ( error )
+      goto Exit;
+
+    style_class          = style_metrics->style_class;
+    writing_system_class =
+      AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
+
+    loader->metrics = style_metrics;
+
+    if ( writing_system_class->style_metrics_scale )
+      writing_system_class->style_metrics_scale( style_metrics, &scaler );
+    else
+      style_metrics->scaler = scaler;
+
+    if ( writing_system_class->style_hints_init )
+    {
+      error = writing_system_class->style_hints_init( hints,
+                                                      style_metrics );
+      if ( error )
+        goto Exit;
+    }
+
+    /*
+     *  Do the main work of `af_loader_load_glyph'.  Note that we never have
+     *  to deal with composite glyphs as those get loaded into
+     *  FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function.
+     *  In the rare cases where FT_LOAD_NO_RECURSE is set, it implies
+     *  FT_LOAD_NO_SCALE and as such the auto-hinter is never called.
+     */
+    load_flags |=  FT_LOAD_NO_SCALE         |
+                   FT_LOAD_IGNORE_TRANSFORM |
+                   FT_LOAD_LINEAR_DESIGN;
+    load_flags &= ~FT_LOAD_RENDER;
+
+    error = FT_Load_Glyph( face, glyph_index, load_flags );
     if ( error )
       goto Exit;
 
     /*
-     * Apply stem darkening (emboldening) here before hints are applied to
-     * the outline.  Glyphs are scaled down proportionally to the
-     * emboldening so that curve points don't fall outside their precomputed
-     * blue zones.
+     *  Apply stem darkening (emboldening) here before hints are applied to
+     *  the outline.  Glyphs are scaled down proportionally to the
+     *  emboldening so that curve points don't fall outside their
+     *  precomputed blue zones.
      *
-     * Any emboldening done by the font driver (e.g., the CFF driver)
-     * doesn't reach here because the autohinter loads the unprocessed
-     * glyphs in font units for analysis (functions `af_*_metrics_init_*')
-     * and then above to prepare it for the rasterizers by itself,
-     * independently of the font driver.  So emboldening must be done here,
-     * within the autohinter.
+     *  Any emboldening done by the font driver (e.g., the CFF driver)
+     *  doesn't reach here because the autohinter loads the unprocessed
+     *  glyphs in font units for analysis (functions `af_*_metrics_init_*')
+     *  and then above to prepare it for the rasterizers by itself,
+     *  independently of the font driver.  So emboldening must be done here,
+     *  within the autohinter.
      *
-     * All glyphs to be autohinted pass through here one by one.  The
-     * standard widths can therefore change from one glyph to the next,
-     * depending on what script a glyph is assigned to (each script has its
-     * own set of standard widths and other metrics).  The darkening amount
-     * must therefore be recomputed for each size and
-     * `standard_{vertical,horizontal}_width' change.
+     *  All glyphs to be autohinted pass through here one by one.  The
+     *  standard widths can therefore change from one glyph to the next,
+     *  depending on what script a glyph is assigned to (each script has its
+     *  own set of standard widths and other metrics).  The darkening amount
+     *  must therefore be recomputed for each size and
+     *  `standard_{vertical,horizontal}_width' change.
+     *
+     *  Ignore errors and carry on without emboldening.
      */
     if ( !module->no_stem_darkening )
-    {
-      AF_FaceGlobals         globals = loader->globals;
-      AF_WritingSystemClass  writing_system_class;
+      af_loader_embolden_glyph_in_slot( loader, face, style_metrics );
 
-      FT_Pos  stdVW = 0;
-      FT_Pos  stdHW = 0;
-
-      FT_Bool  size_changed = face->size->metrics.x_ppem
-                                != globals->stem_darkening_for_ppem;
-
-      FT_Fixed  em_size  = af_intToFixed( face->units_per_EM );
-      FT_Fixed  em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size );
-
-      FT_Matrix  scale_down_matrix = { 0x10000L, 0, 0, 0x10000L };
-
-
-      /* Skip stem darkening for broken fonts. */
-      if ( !face->units_per_EM )
-        goto After_Emboldening;
-
-      /*
-       * We depend on the writing system (script analyzers) to supply
-       * standard widths for the script of the glyph we are looking at.  If
-       * it can't deliver, stem darkening is effectively disabled.
-       */
-      writing_system_class =
-        AF_WRITING_SYSTEM_CLASSES_GET[metrics->style_class->writing_system];
-
-      if ( writing_system_class->style_metrics_getstdw )
-        writing_system_class->style_metrics_getstdw( metrics,
-                                                     &stdHW,
-                                                     &stdVW );
-      else
-        goto After_Emboldening;
-
-
-      if ( size_changed                                               ||
-           ( stdVW > 0 && stdVW != globals->standard_vertical_width ) )
-      {
-        FT_Fixed  darken_by_font_units_x, darken_x;
-
-
-        darken_by_font_units_x =
-          af_intToFixed( af_loader_compute_darkening( loader,
-                                                      face,
-                                                      stdVW ) );
-        darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x,
-                                         face->size->metrics.x_scale ),
-                              em_ratio );
-
-        globals->standard_vertical_width = stdVW;
-        globals->stem_darkening_for_ppem = face->size->metrics.x_ppem;
-        globals->darken_x                = af_fixedToInt( darken_x );
-      }
-
-      if ( size_changed                                                 ||
-           ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) )
-      {
-        FT_Fixed  darken_by_font_units_y, darken_y;
-
-
-        darken_by_font_units_y =
-          af_intToFixed( af_loader_compute_darkening( loader,
-                                                      face,
-                                                      stdHW ) );
-        darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y,
-                                         face->size->metrics.y_scale ),
-                              em_ratio );
-
-        globals->standard_horizontal_width = stdHW;
-        globals->stem_darkening_for_ppem   = face->size->metrics.x_ppem;
-        globals->darken_y                  = af_fixedToInt( darken_y );
-
-        /*
-         * Scale outlines down on the Y-axis to keep them inside their blue
-         * zones.  The stronger the emboldening, the stronger the
-         * downscaling (plus heuristical padding to prevent outlines still
-         * falling out their zones due to rounding).
-         *
-         * Reason: `FT_Outline_Embolden' works by shifting the rightmost
-         * points of stems farther to the right, and topmost points farther
-         * up.  This positions points on the Y-axis outside their
-         * pre-computed blue zones and leads to distortion when applying the
-         * hints in the code further below.  Code outside this emboldening
-         * block doesn't know we are presenting it with modified outlines
-         * the analyzer didn't see!
-         *
-         * An unfortunate side effect of downscaling is that the emboldening
-         * effect is slightly decreased.  The loss becomes more pronounced
-         * versus the CFF driver at smaller sizes, e.g., at 9ppem and below.
-         */
-        globals->scale_down_factor =
-          FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ),
-                     em_size );
-      }
-
-      FT_Outline_EmboldenXY( &slot->outline,
-                             globals->darken_x,
-                             globals->darken_y );
-
-      scale_down_matrix.yy = globals->scale_down_factor;
-      FT_Outline_Transform( &slot->outline, &scale_down_matrix );
-    }
-
-  After_Emboldening:
     loader->transformed = internal->glyph_transformed;
     if ( loader->transformed )
     {
@@ -264,8 +363,8 @@
                               loader->trans_delta.x,
                               loader->trans_delta.y );
 
-      /* compute original horizontal phantom points (and ignore */
-      /* vertical ones)                                         */
+      /* compute original horizontal phantom points */
+      /* (and ignore vertical ones)                 */
       loader->pp1.x = hints->x_delta;
       loader->pp1.y = hints->y_delta;
       loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
@@ -276,30 +375,21 @@
       if ( slot->outline.n_points == 0 )
         goto Hint_Metrics;
 
-      /* now load the slot image into the auto-outline and run the */
-      /* automatic hinting process                                 */
-      {
-#ifdef FT_CONFIG_OPTION_PIC
-        AF_FaceGlobals         globals = loader->globals;
-#endif
-        AF_StyleClass          style_class = metrics->style_class;
-        AF_WritingSystemClass  writing_system_class =
-          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
-
-
-        if ( writing_system_class->style_hints_apply )
-          writing_system_class->style_hints_apply( glyph_index,
-                                                   hints,
-                                                   &gloader->base.outline,
-                                                   metrics );
-      }
+      /* now load the slot image into the auto-outline */
+      /* and run the automatic hinting process         */
+      if ( writing_system_class->style_hints_apply )
+        writing_system_class->style_hints_apply( glyph_index,
+                                                 hints,
+                                                 &gloader->base.outline,
+                                                 style_metrics );
 
       /* we now need to adjust the metrics according to the change in */
       /* width/positioning that occurred during the hinting process   */
-      if ( scaler->render_mode != FT_RENDER_MODE_LIGHT )
+      if ( scaler.render_mode != FT_RENDER_MODE_LIGHT )
       {
-        FT_Pos        old_rsb, old_lsb, new_lsb;
-        FT_Pos        pp1x_uh, pp2x_uh;
+        FT_Pos  old_rsb, old_lsb, new_lsb;
+        FT_Pos  pp1x_uh, pp2x_uh;
+
         AF_AxisHints  axis  = &hints->axis[AF_DIMENSION_HORZ];
         AF_Edge       edge1 = axis->edges;         /* leftmost edge  */
         AF_Edge       edge2 = edge1 +
@@ -309,12 +399,12 @@
         if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )
         {
           old_rsb = loader->pp2.x - edge2->opos;
-          old_lsb = edge1->opos;
+          /* loader->pp1.x is always zero at this point of time */
+          old_lsb = edge1->opos /* - loader->pp1.x */;
           new_lsb = edge1->pos;
 
           /* remember unhinted values to later account */
           /* for rounding errors                       */
-
           pp1x_uh = new_lsb    - old_lsb;
           pp2x_uh = edge2->pos + old_rsb;
 
@@ -380,8 +470,8 @@
 
       vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX;
       vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY;
-      vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale );
-      vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale );
+      vvector.x = FT_MulFix( vvector.x, style_metrics->scaler.x_scale );
+      vvector.y = FT_MulFix( vvector.y, style_metrics->scaler.y_scale );
 
       /* transform the hinted outline if needed */
       if ( loader->transformed )
@@ -389,12 +479,12 @@
         FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
         FT_Vector_Transform( &vvector, &loader->trans_matrix );
       }
-#if 1
+
       /* we must translate our final outline by -pp1.x and compute */
       /* the new metrics                                           */
       if ( loader->pp1.x )
         FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
-#endif
+
       FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
 
       bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
@@ -413,20 +503,14 @@
       /* for mono-width fonts (like Andale, Courier, etc.) we need */
       /* to keep the original rounded advance width; ditto for     */
       /* digits if all have the same advance width                 */
-#if 0
-      if ( !FT_IS_FIXED_WIDTH( slot->face ) )
-        slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
-      else
-        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
-                                               x_scale );
-#else
-      if ( scaler->render_mode != FT_RENDER_MODE_LIGHT                      &&
+      if ( scaler.render_mode != FT_RENDER_MODE_LIGHT                       &&
            ( FT_IS_FIXED_WIDTH( slot->face )                              ||
              ( af_face_globals_is_digit( loader->globals, glyph_index ) &&
-               metrics->digits_have_same_width                          ) ) )
+               style_metrics->digits_have_same_width                    ) ) )
       {
-        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
-                                               metrics->scaler.x_scale );
+        slot->metrics.horiAdvance =
+          FT_MulFix( slot->metrics.horiAdvance,
+                     style_metrics->scaler.x_scale );
 
         /* Set delta values to 0.  Otherwise code that uses them is */
         /* going to ruin the fixed advance width.                   */
@@ -439,23 +523,13 @@
         if ( slot->metrics.horiAdvance )
           slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
       }
-#endif
 
       slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
-                                             metrics->scaler.y_scale );
+                                             style_metrics->scaler.y_scale );
 
       slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
       slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
 
-#if 0
-      /* reassign all outline fields except flags to protect them */
-      slot->outline.n_contours = internal->loader->base.outline.n_contours;
-      slot->outline.n_points   = internal->loader->base.outline.n_points;
-      slot->outline.points     = internal->loader->base.outline.points;
-      slot->outline.tags       = internal->loader->base.outline.tags;
-      slot->outline.contours   = internal->loader->base.outline.contours;
-#endif
-
       slot->format  = FT_GLYPH_FORMAT_OUTLINE;
     }
 
@@ -464,85 +538,6 @@
   }
 
 
-  /* Load a glyph. */
-
-  FT_LOCAL_DEF( FT_Error )
-  af_loader_load_glyph( AF_Loader  loader,
-                        AF_Module  module,
-                        FT_Face    face,
-                        FT_UInt    gindex,
-                        FT_Int32   load_flags )
-  {
-    FT_Error      error;
-    FT_Size       size   = face->size;
-    AF_ScalerRec  scaler;
-
-
-    if ( !size )
-      return FT_THROW( Invalid_Size_Handle );
-
-    FT_ZERO( &scaler );
-
-    scaler.face    = face;
-    scaler.x_scale = size->metrics.x_scale;
-    scaler.x_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
-    scaler.y_scale = size->metrics.y_scale;
-    scaler.y_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
-
-    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
-    scaler.flags       = 0;  /* XXX: fix this */
-
-    error = af_loader_reset( loader, module, face );
-    if ( !error )
-    {
-      AF_StyleMetrics  metrics;
-      FT_UInt          options = AF_STYLE_NONE_DFLT;
-
-
-#ifdef FT_OPTION_AUTOFIT2
-      /* XXX: undocumented hook to activate the latin2 writing system */
-      if ( load_flags & ( 1UL << 20 ) )
-        options = AF_STYLE_LTN2_DFLT;
-#endif
-
-      error = af_face_globals_get_metrics( loader->globals, gindex,
-                                           options, &metrics );
-      if ( !error )
-      {
-#ifdef FT_CONFIG_OPTION_PIC
-        AF_FaceGlobals         globals = loader->globals;
-#endif
-        AF_StyleClass          style_class = metrics->style_class;
-        AF_WritingSystemClass  writing_system_class =
-          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
-
-
-        loader->metrics = metrics;
-
-        if ( writing_system_class->style_metrics_scale )
-          writing_system_class->style_metrics_scale( metrics, &scaler );
-        else
-          metrics->scaler = scaler;
-
-        load_flags |=  FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
-        load_flags &= ~FT_LOAD_RENDER;
-
-        if ( writing_system_class->style_hints_init )
-        {
-          error = writing_system_class->style_hints_init( loader->hints,
-                                                          metrics );
-          if ( error )
-            goto Exit;
-        }
-
-        error = af_loader_load_g( loader, &scaler, gindex, load_flags );
-      }
-    }
-  Exit:
-    return error;
-  }
-
-
   /*
    * Compute amount of font units the face should be emboldened by, in
    * analogy to the CFF driver's `cf2_computeDarkening' function.  See there
diff --git a/src/autofit/afloader.h b/src/autofit/afloader.h
index 0062eb9..2578abe 100644
--- a/src/autofit/afloader.h
+++ b/src/autofit/afloader.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter glyph loading routines (specification).                  */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c
index e8f8ff4..1566baf 100644
--- a/src/autofit/afmodule.c
+++ b/src/autofit/afmodule.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter module implementation (body).                            */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -104,6 +104,19 @@
   }
 
 
+#ifdef FT_CONFIG_OPTION_PIC
+
+#undef  AF_SCRIPT_CLASSES_GET
+#define AF_SCRIPT_CLASSES_GET  \
+          ( GET_PIC( ft_module->library )->af_script_classes )
+
+#undef  AF_STYLE_CLASSES_GET
+#define AF_STYLE_CLASSES_GET  \
+          ( GET_PIC( ft_module->library )->af_style_classes )
+
+#endif
+
+
   static FT_Error
   af_property_set( FT_Module    ft_module,
                    const char*  property_name,
@@ -421,12 +434,14 @@
 
   FT_DEFINE_SERVICE_PROPERTIESREC(
     af_service_properties,
+
     (FT_Properties_SetFunc)af_property_set,        /* set_property */
     (FT_Properties_GetFunc)af_property_get )       /* get_property */
 
 
   FT_DEFINE_SERVICEDESCREC1(
     af_services,
+
     FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET )
 
 
@@ -519,9 +534,16 @@
     error = af_loader_load_glyph( loader, module, slot->face,
                                   glyph_index, load_flags );
 
-    af_glyph_hints_dump_points( hints, 0 );
-    af_glyph_hints_dump_segments( hints, 0 );
-    af_glyph_hints_dump_edges( hints, 0 );
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( ft_trace_levels[FT_COMPONENT] )
+    {
+#endif
+      af_glyph_hints_dump_points( hints, 0 );
+      af_glyph_hints_dump_segments( hints, 0 );
+      af_glyph_hints_dump_edges( hints, 0 );
+#ifdef FT_DEBUG_LEVEL_TRACE
+    }
+#endif
 
     af_loader_done( loader );
 
@@ -552,6 +574,7 @@
 
   FT_DEFINE_AUTOHINTER_INTERFACE(
     af_autofitter_interface,
+
     NULL,                                                    /* reset_face */
     NULL,                                              /* get_global_hints */
     NULL,                                             /* done_global_hints */
@@ -570,9 +593,10 @@
 
     (const void*)&AF_INTERFACE_GET,
 
-    (FT_Module_Constructor)af_autofitter_init,
-    (FT_Module_Destructor) af_autofitter_done,
-    (FT_Module_Requester)  af_get_interface )
+    (FT_Module_Constructor)af_autofitter_init,  /* module_init   */
+    (FT_Module_Destructor) af_autofitter_done,  /* module_done   */
+    (FT_Module_Requester)  af_get_interface     /* get_interface */
+  )
 
 
 /* END */
diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h
index e65db5f..0571d14 100644
--- a/src/autofit/afmodule.h
+++ b/src/autofit/afmodule.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter module implementation (specification).                   */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afpic.c b/src/autofit/afpic.c
index 3cbd916..3125e03 100644
--- a/src/autofit/afpic.c
+++ b/src/autofit/afpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for autofit module.  */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afpic.h b/src/autofit/afpic.h
index 98a45a2..8cd3392 100644
--- a/src/autofit/afpic.h
+++ b/src/autofit/afpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for autofit module.  */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -69,7 +69,7 @@
 
 
 #define GET_PIC( lib )  \
-          ( (AFModulePIC*)((lib)->pic_container.autofit) )
+          ( (AFModulePIC*)( (lib)->pic_container.autofit ) )
 
 #define AF_SERVICES_GET  \
           ( GET_PIC( library )->af_services )
diff --git a/src/autofit/afranges.c b/src/autofit/afranges.c
index 732f3d1..fdd2800 100644
--- a/src/autofit/afranges.c
+++ b/src/autofit/afranges.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter Unicode script ranges (body).                            */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afranges.h b/src/autofit/afranges.h
index 1a0e4b1..72d9eaa 100644
--- a/src/autofit/afranges.h
+++ b/src/autofit/afranges.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter Unicode script ranges (specification).                   */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afscript.h b/src/autofit/afscript.h
index cffe591..c656c78 100644
--- a/src/autofit/afscript.h
+++ b/src/autofit/afscript.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter scripts (specification only).                            */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afshaper.c b/src/autofit/afshaper.c
index 6d13b65..da92fad 100644
--- a/src/autofit/afshaper.c
+++ b/src/autofit/afshaper.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    HarfBuzz interface for accessing OpenType features (body).           */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afshaper.h b/src/autofit/afshaper.h
index 0d41f78..9185d19 100644
--- a/src/autofit/afshaper.h
+++ b/src/autofit/afshaper.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    HarfBuzz interface for accessing OpenType features (specification).  */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afstyles.h b/src/autofit/afstyles.h
index e83a95b..3afa839 100644
--- a/src/autofit/afstyles.h
+++ b/src/autofit/afstyles.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter styles (specification only).                             */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/aftypes.h b/src/autofit/aftypes.h
index ef62043..718dab7 100644
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter types (specification only).                              */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -221,7 +221,7 @@
   (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints    hints,
                                      AF_StyleMetrics  metrics );
 
-  typedef void
+  typedef FT_Error
   (*AF_WritingSystem_ApplyHintsFunc)( FT_UInt          glyph_index,
                                       AF_GlyphHints    hints,
                                       FT_Outline*      outline,
@@ -575,6 +575,7 @@
           m_init,                                                         \
           m_scale,                                                        \
           m_done,                                                         \
+          m_stdw,                                                         \
           h_init,                                                         \
           h_apply )                                                       \
   FT_LOCAL_DEF( void )                                                    \
diff --git a/src/autofit/afwarp.c b/src/autofit/afwarp.c
index ce1806c..44dd49b 100644
--- a/src/autofit/afwarp.c
+++ b/src/autofit/afwarp.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter warping algorithm (body).                                */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afwarp.h b/src/autofit/afwarp.h
index 6d96f86..2e85cbd 100644
--- a/src/autofit/afwarp.h
+++ b/src/autofit/afwarp.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter warping algorithm (specification).                       */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/afwrtsys.h b/src/autofit/afwrtsys.h
index 842f492..86749a2 100644
--- a/src/autofit/afwrtsys.h
+++ b/src/autofit/afwrtsys.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter writing systems (specification only).                    */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/autofit/autofit.c b/src/autofit/autofit.c
index dda9aeb..60060c9 100644
--- a/src/autofit/autofit.c
+++ b/src/autofit/autofit.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auto-fitter module (body).                                           */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/basepic.c b/src/base/basepic.c
index f2cea90..57fb816 100644
--- a/src/base/basepic.c
+++ b/src/base/basepic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for base.            */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/basepic.h b/src/base/basepic.h
index a1a75a0..258d4ce 100644
--- a/src/base/basepic.h
+++ b/src/base/basepic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for base.            */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c
index 9e2ab89..1557607 100644
--- a/src/base/ftadvanc.c
+++ b/src/base/ftadvanc.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Quick computation of advance widths (body).                          */
 /*                                                                         */
-/*  Copyright 2008-2016 by                                                 */
+/*  Copyright 2008-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -36,7 +36,7 @@
     if ( flags & FT_LOAD_NO_SCALE )
       return FT_Err_Ok;
 
-    if ( face->size == NULL )
+    if ( !face->size )
       return FT_THROW( Invalid_Size_Handle );
 
     if ( flags & FT_LOAD_VERTICAL_LAYOUT )
@@ -60,12 +60,13 @@
    /*  - unscaled load                                             */
    /*  - unhinted load                                             */
    /*  - light-hinted load                                         */
-   /*  - neither a MM nor a GX font                                */
+   /*  - if a variations font, it must have an `HVAR' or `VVAR'    */
+   /*    table (thus the old MM or GX fonts don't qualify; this    */
+   /*    gets checked by the driver-specific functions)            */
 
-#define LOAD_ADVANCE_FAST_CHECK( face, flags )                          \
-          ( ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    ||   \
-              FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) && \
-            !FT_HAS_MULTIPLE_MASTERS( face )                         )
+#define LOAD_ADVANCE_FAST_CHECK( face, flags )                      \
+          ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    || \
+            FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
 
 
   /* documentation is in ftadvanc.h */
diff --git a/src/base/ftapi.c b/src/base/ftapi.c
index b94c3eb..1e6c718 100644
--- a/src/base/ftapi.c
+++ b/src/base/ftapi.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType compatibility functions (body).                         */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftbase.c b/src/base/ftbase.c
index ab1af6f..993ac72 100644
--- a/src/base/ftbase.c
+++ b/src/base/ftbase.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Single object library component (body only).                         */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftbase.h b/src/base/ftbase.h
index 717fdaa..2072284 100644
--- a/src/base/ftbase.h
+++ b/src/base/ftbase.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private functions used in base module (specification).  */
 /*                                                                         */
-/*  Copyright 2008-2016 by                                                 */
+/*  Copyright 2008-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya.      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c
index d3e45ff..6e19da6 100644
--- a/src/base/ftbbox.c
+++ b/src/base/ftbbox.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType bbox computation (body).                                    */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
@@ -423,12 +423,15 @@
   }
 
 
-  FT_DEFINE_OUTLINE_FUNCS(bbox_interface,
-    (FT_Outline_MoveTo_Func) BBox_Move_To,
-    (FT_Outline_LineTo_Func) BBox_Line_To,
-    (FT_Outline_ConicTo_Func)BBox_Conic_To,
-    (FT_Outline_CubicTo_Func)BBox_Cubic_To,
-    0, 0
+  FT_DEFINE_OUTLINE_FUNCS(
+    bbox_interface,
+
+    (FT_Outline_MoveTo_Func) BBox_Move_To,   /* move_to  */
+    (FT_Outline_LineTo_Func) BBox_Line_To,   /* line_to  */
+    (FT_Outline_ConicTo_Func)BBox_Conic_To,  /* conic_to */
+    (FT_Outline_CubicTo_Func)BBox_Cubic_To,  /* cubic_to */
+    0,                                       /* shift    */
+    0                                        /* delta    */
   )
 
 
@@ -457,6 +460,7 @@
     {
       abbox->xMin = abbox->xMax = 0;
       abbox->yMin = abbox->yMax = 0;
+
       return 0;
     }
 
@@ -468,10 +472,10 @@
 
     for ( n = 0; n < outline->n_points; n++ )
     {
-      FT_UPDATE_BBOX( vec, cbox);
+      FT_UPDATE_BBOX( vec, cbox );
 
       if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON )
-        FT_UPDATE_BBOX( vec, bbox);
+        FT_UPDATE_BBOX( vec, bbox );
 
       vec++;
     }
@@ -487,8 +491,10 @@
       TBBox_Rec  user;
 
 #ifdef FT_CONFIG_OPTION_PIC
-      FT_Outline_Funcs bbox_interface;
-      Init_Class_bbox_interface(&bbox_interface);
+      FT_Outline_Funcs  bbox_interface;
+
+
+      Init_Class_bbox_interface( &bbox_interface );
 #endif
 
       user.bbox = bbox;
diff --git a/src/base/ftbdf.c b/src/base/ftbdf.c
new file mode 100644
index 0000000..40f0ca2
--- /dev/null
+++ b/src/base/ftbdf.c
@@ -0,0 +1,91 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftbdf.c                                                                */
+/*                                                                         */
+/*    FreeType API for accessing BDF-specific strings (body).              */
+/*                                                                         */
+/*  Copyright 2002-2017 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 FT_INTERNAL_DEBUG_H
+
+#include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_BDF_H
+
+
+  /* documentation is in ftbdf.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_BDF_Charset_ID( FT_Face       face,
+                         const char*  *acharset_encoding,
+                         const char*  *acharset_registry )
+  {
+    FT_Error     error;
+    const char*  encoding = NULL;
+    const char*  registry = NULL;
+
+    FT_Service_BDF  service;
+
+
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    FT_FACE_FIND_SERVICE( face, service, BDF );
+
+    if ( service && service->get_charset_id )
+      error = service->get_charset_id( face, &encoding, &registry );
+    else
+      error = FT_THROW( Invalid_Argument );
+
+    if ( acharset_encoding )
+      *acharset_encoding = encoding;
+
+    if ( acharset_registry )
+      *acharset_registry = registry;
+
+    return error;
+  }
+
+
+  /* documentation is in ftbdf.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_BDF_Property( FT_Face           face,
+                       const char*       prop_name,
+                       BDF_PropertyRec  *aproperty )
+  {
+    FT_Error  error;
+
+    FT_Service_BDF  service;
+
+
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    if ( !aproperty )
+      return FT_THROW( Invalid_Argument );
+
+    aproperty->type = BDF_PROPERTY_TYPE_NONE;
+
+    FT_FACE_FIND_SERVICE( face, service, BDF );
+
+    if ( service && service->get_property )
+      error = service->get_property( face, prop_name, aproperty );
+    else
+      error = FT_THROW( Invalid_Argument );
+
+    return error;
+  }
+
+
+/* END */
diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c
index 24fead3..88c88c4 100644
--- a/src/base/ftbitmap.c
+++ b/src/base/ftbitmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility functions for bitmaps (body).                       */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -76,7 +76,7 @@
     source_pitch_sign = source->pitch < 0 ? -1 : 1;
     target_pitch_sign = target->pitch < 0 ? -1 : 1;
 
-    if ( source->buffer == NULL )
+    if ( !source->buffer )
     {
       *target = *source;
       if ( source_pitch_sign != target_pitch_sign )
diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c
index 67549d0..f052550 100644
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Arithmetic computations (body).                                      */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -449,8 +449,8 @@
       FT_Add64( &temp, &temp2, &temp );
 
       /* last attempt to ditch long division */
-      a = temp.hi == 0 ? temp.lo / c
-                       : ft_div64by32( temp.hi, temp.lo, c );
+      a = ( temp.hi == 0 ) ? temp.lo / c
+                           : ft_div64by32( temp.hi, temp.lo, c );
     }
 
     a_ = (FT_Long)a;
@@ -492,8 +492,8 @@
       ft_multo64( a, b, &temp );
 
       /* last attempt to ditch long division */
-      a = temp.hi == 0 ? temp.lo / c
-                       : ft_div64by32( temp.hi, temp.lo, c );
+      a = ( temp.hi == 0 ) ? temp.lo / c
+                           : ft_div64by32( temp.hi, temp.lo, c );
     }
 
     a_ = (FT_Long)a;
diff --git a/src/base/ftcid.c b/src/base/ftcid.c
new file mode 100644
index 0000000..398396b
--- /dev/null
+++ b/src/base/ftcid.c
@@ -0,0 +1,118 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftcid.c                                                                */
+/*                                                                         */
+/*    FreeType API for accessing CID font information.                     */
+/*                                                                         */
+/*  Copyright 2007-2017 by                                                 */
+/*  Derek Clegg and Michael Toftdal.                                       */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_CID_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_CID_H
+
+
+  /* documentation is in ftcid.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_CID_Registry_Ordering_Supplement( FT_Face       face,
+                                           const char*  *registry,
+                                           const char*  *ordering,
+                                           FT_Int       *supplement)
+  {
+    FT_Error     error;
+    const char*  r = NULL;
+    const char*  o = NULL;
+    FT_Int       s = 0;
+
+
+    error = FT_ERR( Invalid_Argument );
+
+    if ( face )
+    {
+      FT_Service_CID  service;
+
+
+      FT_FACE_FIND_SERVICE( face, service, CID );
+
+      if ( service && service->get_ros )
+        error = service->get_ros( face, &r, &o, &s );
+    }
+
+    if ( registry )
+      *registry = r;
+
+    if ( ordering )
+      *ordering = o;
+
+    if ( supplement )
+      *supplement = s;
+
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_CID_Is_Internally_CID_Keyed( FT_Face   face,
+                                      FT_Bool  *is_cid )
+  {
+    FT_Error  error = FT_ERR( Invalid_Argument );
+    FT_Bool   ic = 0;
+
+
+    if ( face )
+    {
+      FT_Service_CID  service;
+
+
+      FT_FACE_FIND_SERVICE( face, service, CID );
+
+      if ( service && service->get_is_cid )
+        error = service->get_is_cid( face, &ic);
+    }
+
+    if ( is_cid )
+      *is_cid = ic;
+
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_CID_From_Glyph_Index( FT_Face   face,
+                               FT_UInt   glyph_index,
+                               FT_UInt  *cid )
+  {
+    FT_Error  error = FT_ERR( Invalid_Argument );
+    FT_UInt   c = 0;
+
+
+    if ( face )
+    {
+      FT_Service_CID  service;
+
+
+      FT_FACE_FIND_SERVICE( face, service, CID );
+
+      if ( service && service->get_cid_from_glyph_index )
+        error = service->get_cid_from_glyph_index( face, glyph_index, &c);
+    }
+
+    if ( cid )
+      *cid = c;
+
+    return error;
+  }
+
+
+/* END */
diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c
index 38d1a80..242246b 100644
--- a/src/base/ftdbgmem.c
+++ b/src/base/ftdbgmem.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Memory debugger (body).                                              */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -268,7 +268,7 @@
                       ft_mem_table_alloc(
                         table,
                         new_size * (FT_Long)sizeof ( FT_MemNode ) );
-      if ( new_buckets == NULL )
+      if ( !new_buckets )
         return;
 
       FT_ARRAY_ZERO( new_buckets, new_size );
@@ -309,7 +309,7 @@
 
 
     table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) );
-    if ( table == NULL )
+    if ( !table )
       goto Exit;
 
     FT_ZERO( table );
@@ -466,7 +466,7 @@
     for (;;)
     {
       node = *pnode;
-      if ( node == NULL )
+      if ( !node )
         break;
 
       if ( node->file_name == _ft_debug_file   &&
@@ -477,7 +477,7 @@
     }
 
     node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) );
-    if ( node == NULL )
+    if ( !node )
       ft_mem_debug_panic(
         "not enough memory to perform memory debugging\n" );
 
@@ -545,7 +545,7 @@
 
       /* we need to create a new node in this table */
       node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) );
-      if ( node == NULL )
+      if ( !node )
         ft_mem_debug_panic( "not enough memory to run memory tests" );
 
       node->address = address;
@@ -717,7 +717,7 @@
     FT_MemTable  table = (FT_MemTable)memory->user;
 
 
-    if ( block == NULL )
+    if ( !block )
       ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
                           FT_FILENAME( _ft_debug_file ),
                           _ft_debug_lineno );
@@ -755,7 +755,7 @@
 
     /* the following is valid according to ANSI C */
 #if 0
-    if ( block == NULL || cur_size == 0 )
+    if ( !block || !cur_size )
       ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)",
                           file_name, line_no );
 #endif
@@ -799,7 +799,7 @@
       return NULL;
 
     new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size );
-    if ( new_block == NULL )
+    if ( !new_block )
       return NULL;
 
     ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta );
@@ -840,7 +840,7 @@
         memory->free    = ft_mem_debug_free;
 
         p = getenv( "FT2_ALLOC_TOTAL_MAX" );
-        if ( p != NULL )
+        if ( p )
         {
           FT_Long  total_max = ft_strtol( p, NULL, 10 );
 
@@ -853,7 +853,7 @@
         }
 
         p = getenv( "FT2_ALLOC_COUNT_MAX" );
-        if ( p != NULL )
+        if ( p )
         {
           FT_Long  total_count = ft_strtol( p, NULL, 10 );
 
@@ -866,7 +866,7 @@
         }
 
         p = getenv( "FT2_KEEP_ALIVE" );
-        if ( p != NULL )
+        if ( p )
         {
           FT_Long  keep_alive = ft_strtol( p, NULL, 10 );
 
diff --git a/src/base/ftdebug.c b/src/base/ftdebug.c
index 40925d1..20c6170 100644
--- a/src/base/ftdebug.c
+++ b/src/base/ftdebug.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Debugging and logging component (body).                              */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftfntfmt.c b/src/base/ftfntfmt.c
index c6eb319..dcbeba0 100644
--- a/src/base/ftfntfmt.c
+++ b/src/base/ftfntfmt.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file for font formats (body).                       */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftfstype.c b/src/base/ftfstype.c
index ae56c8f..cec4fb3 100644
--- a/src/base/ftfstype.c
+++ b/src/base/ftfstype.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file to access FSType data (body).                  */
 /*                                                                         */
-/*  Copyright 2008-2016 by                                                 */
+/*  Copyright 2008-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftgasp.c b/src/base/ftgasp.c
index e38e55b..477b725 100644
--- a/src/base/ftgasp.c
+++ b/src/base/ftgasp.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Access of TrueType's `gasp' table (body).                            */
 /*                                                                         */
-/*  Copyright 2007-2016 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c
index c4f0ff7..8134003 100644
--- a/src/base/ftgloadr.c
+++ b/src/base/ftgloadr.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph loader (body).                                    */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c
index c2376dd..9bfb330 100644
--- a/src/base/ftglyph.c
+++ b/src/base/ftglyph.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType convenience functions to handle glyphs (body).              */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -132,16 +132,18 @@
   }
 
 
-  FT_DEFINE_GLYPH(ft_bitmap_glyph_class,
+  FT_DEFINE_GLYPH(
+    ft_bitmap_glyph_class,
+
     sizeof ( FT_BitmapGlyphRec ),
     FT_GLYPH_FORMAT_BITMAP,
 
-    ft_bitmap_glyph_init,
-    ft_bitmap_glyph_done,
-    ft_bitmap_glyph_copy,
-    0,                          /* FT_Glyph_TransformFunc */
-    ft_bitmap_glyph_bbox,
-    0                           /* FT_Glyph_PrepareFunc   */
+    ft_bitmap_glyph_init,    /* FT_Glyph_InitFunc       glyph_init      */
+    ft_bitmap_glyph_done,    /* FT_Glyph_DoneFunc       glyph_done      */
+    ft_bitmap_glyph_copy,    /* FT_Glyph_CopyFunc       glyph_copy      */
+    NULL,                    /* FT_Glyph_TransformFunc  glyph_transform */
+    ft_bitmap_glyph_bbox,    /* FT_Glyph_GetBBoxFunc    glyph_bbox      */
+    NULL                     /* FT_Glyph_PrepareFunc    glyph_prepare   */
   )
 
 
@@ -260,16 +262,18 @@
   }
 
 
-  FT_DEFINE_GLYPH( ft_outline_glyph_class,
+  FT_DEFINE_GLYPH(
+    ft_outline_glyph_class,
+
     sizeof ( FT_OutlineGlyphRec ),
     FT_GLYPH_FORMAT_OUTLINE,
 
-    ft_outline_glyph_init,
-    ft_outline_glyph_done,
-    ft_outline_glyph_copy,
-    ft_outline_glyph_transform,
-    ft_outline_glyph_bbox,
-    ft_outline_glyph_prepare
+    ft_outline_glyph_init,      /* FT_Glyph_InitFunc       glyph_init      */
+    ft_outline_glyph_done,      /* FT_Glyph_DoneFunc       glyph_done      */
+    ft_outline_glyph_copy,      /* FT_Glyph_CopyFunc       glyph_copy      */
+    ft_outline_glyph_transform, /* FT_Glyph_TransformFunc  glyph_transform */
+    ft_outline_glyph_bbox,      /* FT_Glyph_GetBBoxFunc    glyph_bbox      */
+    ft_outline_glyph_prepare    /* FT_Glyph_PrepareFunc    glyph_prepare   */
   )
 
 
@@ -542,8 +546,8 @@
     /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */
     /* then calling FT_Render_Glyph_Internal()                            */
 
-    FT_MEM_ZERO( &dummy, sizeof ( dummy ) );
-    FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) );
+    FT_ZERO( &dummy );
+    FT_ZERO( &dummy_internal );
     dummy.internal = &dummy_internal;
     dummy.library  = library;
     dummy.format   = clazz->glyph_format;
diff --git a/src/base/ftgxval.c b/src/base/ftgxval.c
new file mode 100644
index 0000000..ff24d33
--- /dev/null
+++ b/src/base/ftgxval.c
@@ -0,0 +1,142 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftgxval.c                                                              */
+/*                                                                         */
+/*    FreeType API for validating TrueTypeGX/AAT tables (body).            */
+/*                                                                         */
+/*  Copyright 2004-2017 by                                                 */
+/*  Masatake YAMATO, Redhat K.K,                                           */
+/*  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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+/***************************************************************************/
+/*                                                                         */
+/* gxvalid is derived from both gxlayout module and otvalid module.        */
+/* Development of gxlayout is supported by the Information-technology      */
+/* Promotion Agency(IPA), Japan.                                           */
+/*                                                                         */
+/***************************************************************************/
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DEBUG_H
+
+#include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_GX_VALIDATE_H
+
+
+  /* documentation is in ftgxval.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_TrueTypeGX_Validate( FT_Face   face,
+                          FT_UInt   validation_flags,
+                          FT_Bytes  tables[FT_VALIDATE_GX_LENGTH],
+                          FT_UInt   table_length )
+  {
+    FT_Service_GXvalidate  service;
+    FT_Error               error;
+
+
+    if ( !face )
+    {
+      error = FT_THROW( Invalid_Face_Handle );
+      goto Exit;
+    }
+
+    if ( !tables )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    FT_FACE_FIND_GLOBAL_SERVICE( face, service, GX_VALIDATE );
+
+    if ( service )
+      error = service->validate( face,
+                                 validation_flags,
+                                 tables,
+                                 table_length );
+    else
+      error = FT_THROW( Unimplemented_Feature );
+
+  Exit:
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_TrueTypeGX_Free( FT_Face   face,
+                      FT_Bytes  table )
+  {
+    FT_Memory  memory;
+
+
+    if ( !face )
+      return;
+
+    memory = FT_FACE_MEMORY( face );
+
+    FT_FREE( table );
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_ClassicKern_Validate( FT_Face    face,
+                           FT_UInt    validation_flags,
+                           FT_Bytes  *ckern_table )
+  {
+    FT_Service_CKERNvalidate  service;
+    FT_Error                  error;
+
+
+    if ( !face )
+    {
+      error = FT_THROW( Invalid_Face_Handle );
+      goto Exit;
+    }
+
+    if ( !ckern_table )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    FT_FACE_FIND_GLOBAL_SERVICE( face, service, CLASSICKERN_VALIDATE );
+
+    if ( service )
+      error = service->validate( face,
+                                 validation_flags,
+                                 ckern_table );
+    else
+      error = FT_THROW( Unimplemented_Feature );
+
+  Exit:
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_ClassicKern_Free( FT_Face   face,
+                       FT_Bytes  table )
+  {
+    FT_Memory  memory;
+
+
+    if ( !face )
+      return;
+
+    memory = FT_FACE_MEMORY( face );
+
+
+    FT_FREE( table );
+  }
+
+
+/* END */
diff --git a/src/base/ftinit.c b/src/base/ftinit.c
index 02ef938..b3b08fa 100644
--- a/src/base/ftinit.c
+++ b/src/base/ftinit.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType initialization layer (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -230,31 +230,10 @@
 
 #define MAX_LENGTH  128
 
-  /*
-   * Set default properties derived from the `FREETYPE_PROPERTIES'
-   * environment variable.
-   *
-   * `FREETYPE_PROPERTIES' has the following syntax form (broken here into
-   * multiple lines for better readability)
-   *
-   *   <optional whitespace>
-   *   <module-name1> ':'
-   *   <property-name1> '=' <property-value1>
-   *   <whitespace>
-   *   <module-name2> ':'
-   *   <property-name2> '=' <property-value2>
-   *   ...
-   *
-   * Example:
-   *
-   *   FREETYPE_PROPERTIES=truetype:interpreter-version=35 \
-   *                       cff:no-stem-darkening=1 \
-   *                       autofitter:warping=1
-   *
-   */
+  /* documentation is in ftmodapi.h */
 
-  static void
-  ft_set_default_properties( FT_Library  library )
+  FT_EXPORT_DEF( void )
+  FT_Set_Default_Properties( FT_Library  library )
   {
     const char*  env;
     const char*  p;
@@ -326,8 +305,8 @@
 
 #else
 
-  static void
-  ft_set_default_properties( FT_Library  library )
+  FT_EXPORT_DEF( void )
+  FT_Set_Default_Properties( FT_Library  library )
   {
     FT_UNUSED( library );
   }
@@ -365,7 +344,7 @@
     else
       FT_Add_Default_Modules( *alibrary );
 
-    ft_set_default_properties( *alibrary );
+    FT_Set_Default_Properties( *alibrary );
 
     return error;
   }
diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
index 8bcbed7..f8e1709 100644
--- a/src/base/ftlcdfil.c
+++ b/src/base/ftlcdfil.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for color filtering of subpixel bitmap glyphs (body).   */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftmac.c b/src/base/ftmac.c
new file mode 100644
index 0000000..fb70606
--- /dev/null
+++ b/src/base/ftmac.c
@@ -0,0 +1,1082 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftmac.c                                                                */
+/*                                                                         */
+/*    Mac FOND support.  Written by just@letterror.com.                    */
+/*  Heavily modified by mpsuzuki, George Williams, and Sean McBride.       */
+/*                                                                         */
+/*  This file is for Mac OS X only; see builds/mac/ftoldmac.c for          */
+/*  classic platforms built by MPW.                                        */
+/*                                                                         */
+/*  Copyright 1996-2017 by                                                 */
+/*  Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.     */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*
+    Notes
+
+    Mac suitcase files can (and often do!) contain multiple fonts.  To
+    support this I use the face_index argument of FT_(Open|New)_Face()
+    functions, and pretend the suitcase file is a collection.
+
+    Warning: fbit and NFNT bitmap resources are not supported yet.  In old
+    sfnt fonts, bitmap glyph data for each size is stored in each `NFNT'
+    resources instead of the `bdat' table in the sfnt resource.  Therefore,
+    face->num_fixed_sizes is set to 0, because bitmap data in `NFNT'
+    resource is unavailable at present.
+
+    The Mac FOND support works roughly like this:
+
+    - Check whether the offered stream points to a Mac suitcase file.  This
+      is done by checking the file type: it has to be 'FFIL' or 'tfil'.  The
+      stream that gets passed to our init_face() routine is a stdio stream,
+      which isn't usable for us, since the FOND resources live in the
+      resource fork.  So we just grab the stream->pathname field.
+
+    - Read the FOND resource into memory, then check whether there is a
+      TrueType font and/or(!) a Type 1 font available.
+
+    - If there is a Type 1 font available (as a separate `LWFN' file), read
+      its data into memory, massage it slightly so it becomes PFB data, wrap
+      it into a memory stream, load the Type 1 driver and delegate the rest
+      of the work to it by calling FT_Open_Face().  (XXX TODO: after this
+      has been done, the kerning data from the FOND resource should be
+      appended to the face: On the Mac there are usually no AFM files
+      available.  However, this is tricky since we need to map Mac char
+      codes to ps glyph names to glyph ID's...)
+
+    - If there is a TrueType font (an `sfnt' resource), read it into memory,
+      wrap it into a memory stream, load the TrueType driver and delegate
+      the rest of the work to it, by calling FT_Open_Face().
+
+    - Some suitcase fonts (notably Onyx) might point the `LWFN' file to
+      itself, even though it doesn't contains `POST' resources.  To handle
+      this special case without opening the file an extra time, we just
+      ignore errors from the `LWFN' and fallback to the `sfnt' if both are
+      available.
+  */
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_INTERNAL_STREAM_H
+#include "ftbase.h"
+
+  /* This is for Mac OS X.  Without redefinition, OS_INLINE */
+  /* expands to `static inline' which doesn't survive the   */
+  /* -ansi compilation flag of GCC.                         */
+#if !HAVE_ANSI_OS_INLINE
+#undef  OS_INLINE
+#define OS_INLINE  static __inline__
+#endif
+
+  /* `configure' checks the availability of `ResourceIndex' strictly */
+  /* and sets HAVE_TYPE_RESOURCE_INDEX 1 or 0 always.  If it is      */
+  /* not set (e.g., a build without `configure'), the availability   */
+  /* is guessed from the SDK version.                                */
+#ifndef HAVE_TYPE_RESOURCE_INDEX
+#if !defined( MAC_OS_X_VERSION_10_5 ) || \
+    ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 )
+#define HAVE_TYPE_RESOURCE_INDEX 0
+#else
+#define HAVE_TYPE_RESOURCE_INDEX 1
+#endif
+#endif /* !HAVE_TYPE_RESOURCE_INDEX */
+
+#if ( HAVE_TYPE_RESOURCE_INDEX == 0 )
+  typedef short  ResourceIndex;
+#endif
+
+#include <CoreServices/CoreServices.h>
+#include <ApplicationServices/ApplicationServices.h>
+#include <sys/syslimits.h> /* PATH_MAX */
+
+  /* Don't want warnings about our own use of deprecated functions. */
+#define FT_DEPRECATED_ATTRIBUTE
+
+#include FT_MAC_H
+
+#ifndef kATSOptionFlagsUnRestrictedScope /* since Mac OS X 10.1 */
+#define kATSOptionFlagsUnRestrictedScope kATSOptionFlagsDefault
+#endif
+
+
+  /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over
+     TrueType in case *both* are available (this is not common,
+     but it *is* possible). */
+#ifndef PREFER_LWFN
+#define PREFER_LWFN  1
+#endif
+
+
+#ifdef FT_MACINTOSH
+
+  /* This function is deprecated because FSSpec is deprecated in Mac OS X  */
+  FT_EXPORT_DEF( FT_Error )
+  FT_GetFile_From_Mac_Name( const char*  fontName,
+                            FSSpec*      pathSpec,
+                            FT_Long*     face_index )
+  {
+    FT_UNUSED( fontName );
+    FT_UNUSED( pathSpec );
+    FT_UNUSED( face_index );
+
+    return FT_THROW( Unimplemented_Feature );
+  }
+
+
+  /* Private function.                                         */
+  /* The FSSpec type has been discouraged for a long time,     */
+  /* unfortunately an FSRef replacement API for                */
+  /* ATSFontGetFileSpecification() is only available in        */
+  /* Mac OS X 10.5 and later.                                  */
+  static OSStatus
+  FT_ATSFontGetFileReference( ATSFontRef  ats_font_id,
+                              FSRef*      ats_font_ref )
+  {
+#if defined( MAC_OS_X_VERSION_10_5 ) && \
+    ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
+
+    OSStatus  err;
+
+    err = ATSFontGetFileReference( ats_font_id, ats_font_ref );
+
+    return err;
+#elif __LP64__ /* No 64bit Carbon API on legacy platforms */
+    FT_UNUSED( ats_font_id );
+    FT_UNUSED( ats_font_ref );
+
+
+    return fnfErr;
+#else /* 32bit Carbon API on legacy platforms */
+    OSStatus  err;
+    FSSpec    spec;
+
+
+    err = ATSFontGetFileSpecification( ats_font_id, &spec );
+    if ( noErr == err )
+      err = FSpMakeFSRef( &spec, ats_font_ref );
+
+    return err;
+#endif
+  }
+
+
+  static FT_Error
+  FT_GetFileRef_From_Mac_ATS_Name( const char*  fontName,
+                                   FSRef*       ats_font_ref,
+                                   FT_Long*     face_index )
+  {
+    CFStringRef  cf_fontName;
+    ATSFontRef   ats_font_id;
+
+
+    *face_index = 0;
+
+    cf_fontName = CFStringCreateWithCString( NULL, fontName,
+                                             kCFStringEncodingMacRoman );
+    ats_font_id = ATSFontFindFromName( cf_fontName,
+                                       kATSOptionFlagsUnRestrictedScope );
+    CFRelease( cf_fontName );
+
+    if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL )
+      return FT_THROW( Unknown_File_Format );
+
+    if ( noErr != FT_ATSFontGetFileReference( ats_font_id, ats_font_ref ) )
+      return FT_THROW( Unknown_File_Format );
+
+    /* face_index calculation by searching preceding fontIDs */
+    /* with same FSRef                                       */
+    {
+      ATSFontRef  id2 = ats_font_id - 1;
+      FSRef       ref2;
+
+
+      while ( id2 > 0 )
+      {
+        if ( noErr != FT_ATSFontGetFileReference( id2, &ref2 ) )
+          break;
+        if ( noErr != FSCompareFSRefs( ats_font_ref, &ref2 ) )
+          break;
+
+        id2 --;
+      }
+      *face_index = ats_font_id - ( id2 + 1 );
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_GetFilePath_From_Mac_ATS_Name( const char*  fontName,
+                                    UInt8*       path,
+                                    UInt32       maxPathSize,
+                                    FT_Long*     face_index )
+  {
+    FSRef     ref;
+    FT_Error  err;
+
+
+    if ( !fontName || !face_index )
+      return FT_THROW( Invalid_Argument);
+
+    err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );
+    if ( err )
+      return err;
+
+    if ( noErr != FSRefMakePath( &ref, path, maxPathSize ) )
+      return FT_THROW( Unknown_File_Format );
+
+    return FT_Err_Ok;
+  }
+
+
+  /* This function is deprecated because FSSpec is deprecated in Mac OS X  */
+  FT_EXPORT_DEF( FT_Error )
+  FT_GetFile_From_Mac_ATS_Name( const char*  fontName,
+                                FSSpec*      pathSpec,
+                                FT_Long*     face_index )
+  {
+#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \
+      ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )
+    FT_UNUSED( fontName );
+    FT_UNUSED( pathSpec );
+    FT_UNUSED( face_index );
+
+    return FT_THROW( Unimplemented_Feature );
+#else
+    FSRef     ref;
+    FT_Error  err;
+
+
+    if ( !fontName || !face_index )
+      return FT_THROW( Invalid_Argument );
+
+    err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index );
+    if ( err )
+      return err;
+
+    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone, NULL, NULL,
+                                    pathSpec, NULL ) )
+      return FT_THROW( Unknown_File_Format );
+
+    return FT_Err_Ok;
+#endif
+  }
+
+
+  static OSErr
+  FT_FSPathMakeRes( const UInt8*    pathname,
+                    ResFileRefNum*  res )
+  {
+    OSErr  err;
+    FSRef  ref;
+
+
+    if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )
+      return FT_THROW( Cannot_Open_Resource );
+
+    /* at present, no support for dfont format */
+    err = FSOpenResourceFile( &ref, 0, NULL, fsRdPerm, res );
+    if ( noErr == err )
+      return err;
+
+    /* fallback to original resource-fork font */
+    *res = FSOpenResFile( &ref, fsRdPerm );
+    err  = ResError();
+
+    return err;
+  }
+
+
+  /* Return the file type for given pathname */
+  static OSType
+  get_file_type_from_path( const UInt8*  pathname )
+  {
+    FSRef          ref;
+    FSCatalogInfo  info;
+
+
+    if ( noErr != FSPathMakeRef( pathname, &ref, FALSE ) )
+      return ( OSType ) 0;
+
+    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoFinderInfo, &info,
+                                    NULL, NULL, NULL ) )
+      return ( OSType ) 0;
+
+    return ((FInfo *)(info.finderInfo))->fdType;
+  }
+
+
+  /* Given a PostScript font name, create the Macintosh LWFN file name. */
+  static void
+  create_lwfn_name( char*   ps_name,
+                    Str255  lwfn_file_name )
+  {
+    int       max = 5, count = 0;
+    FT_Byte*  p = lwfn_file_name;
+    FT_Byte*  q = (FT_Byte*)ps_name;
+
+
+    lwfn_file_name[0] = 0;
+
+    while ( *q )
+    {
+      if ( ft_isupper( *q ) )
+      {
+        if ( count )
+          max = 3;
+        count = 0;
+      }
+      if ( count < max && ( ft_isalnum( *q ) || *q == '_' ) )
+      {
+        *++p = *q;
+        lwfn_file_name[0]++;
+        count++;
+      }
+      q++;
+    }
+  }
+
+
+  static short
+  count_faces_sfnt( char*  fond_data )
+  {
+    /* The count is 1 greater than the value in the FOND.  */
+    /* Isn't that cute? :-)                                */
+
+    return EndianS16_BtoN( *( (short*)( fond_data +
+                                        sizeof ( FamRec ) ) ) ) + 1;
+  }
+
+
+  static short
+  count_faces_scalable( char*  fond_data )
+  {
+    AsscEntry*  assoc;
+    short       i, face, face_all;
+
+
+    face_all = EndianS16_BtoN( *( (short *)( fond_data +
+                                             sizeof ( FamRec ) ) ) ) + 1;
+    assoc    = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
+    face     = 0;
+
+    for ( i = 0; i < face_all; i++ )
+    {
+      if ( 0 == EndianS16_BtoN( assoc[i].fontSize ) )
+        face++;
+    }
+    return face;
+  }
+
+
+  /* Look inside the FOND data, answer whether there should be an SFNT
+     resource, and answer the name of a possible LWFN Type 1 file.
+
+     Thanks to Paul Miller (paulm@profoundeffects.com) for the fix
+     to load a face OTHER than the first one in the FOND!
+  */
+
+
+  static void
+  parse_fond( char*   fond_data,
+              short*  have_sfnt,
+              ResID*  sfnt_id,
+              Str255  lwfn_file_name,
+              short   face_index )
+  {
+    AsscEntry*  assoc;
+    AsscEntry*  base_assoc;
+    FamRec*     fond;
+
+
+    *sfnt_id          = 0;
+    *have_sfnt        = 0;
+    lwfn_file_name[0] = 0;
+
+    fond       = (FamRec*)fond_data;
+    assoc      = (AsscEntry*)( fond_data + sizeof ( FamRec ) + 2 );
+    base_assoc = assoc;
+
+    /* the maximum faces in a FOND is 48, size of StyleTable.indexes[] */
+    if ( 47 < face_index )
+      return;
+
+    /* Let's do a little range checking before we get too excited here */
+    if ( face_index < count_faces_sfnt( fond_data ) )
+    {
+      assoc += face_index;        /* add on the face_index! */
+
+      /* if the face at this index is not scalable,
+         fall back to the first one (old behavior) */
+      if ( EndianS16_BtoN( assoc->fontSize ) == 0 )
+      {
+        *have_sfnt = 1;
+        *sfnt_id   = EndianS16_BtoN( assoc->fontID );
+      }
+      else if ( base_assoc->fontSize == 0 )
+      {
+        *have_sfnt = 1;
+        *sfnt_id   = EndianS16_BtoN( base_assoc->fontID );
+      }
+    }
+
+    if ( EndianS32_BtoN( fond->ffStylOff ) )
+    {
+      unsigned char*  p = (unsigned char*)fond_data;
+      StyleTable*     style;
+      unsigned short  string_count;
+      char            ps_name[256];
+      unsigned char*  names[64];
+      int             i;
+
+
+      p += EndianS32_BtoN( fond->ffStylOff );
+      style = (StyleTable*)p;
+      p += sizeof ( StyleTable );
+      string_count = EndianS16_BtoN( *(short*)(p) );
+      string_count = FT_MIN( 64, string_count );
+      p += sizeof ( short );
+
+      for ( i = 0; i < string_count; i++ )
+      {
+        names[i] = p;
+        p       += names[i][0];
+        p++;
+      }
+
+      {
+        size_t  ps_name_len = (size_t)names[0][0];
+
+
+        if ( ps_name_len != 0 )
+        {
+          ft_memcpy(ps_name, names[0] + 1, ps_name_len);
+          ps_name[ps_name_len] = 0;
+        }
+        if ( style->indexes[face_index] > 1 &&
+             style->indexes[face_index] <= string_count )
+        {
+          unsigned char*  suffixes = names[style->indexes[face_index] - 1];
+
+
+          for ( i = 1; i <= suffixes[0]; i++ )
+          {
+            unsigned char*  s;
+            size_t          j = suffixes[i] - 1;
+
+
+            if ( j < string_count && ( s = names[j] ) != NULL )
+            {
+              size_t  s_len = (size_t)s[0];
+
+
+              if ( s_len != 0 && ps_name_len + s_len < sizeof ( ps_name ) )
+              {
+                ft_memcpy( ps_name + ps_name_len, s + 1, s_len );
+                ps_name_len += s_len;
+                ps_name[ps_name_len] = 0;
+              }
+            }
+          }
+        }
+      }
+
+      create_lwfn_name( ps_name, lwfn_file_name );
+    }
+  }
+
+
+  static  FT_Error
+  lookup_lwfn_by_fond( const UInt8*      path_fond,
+                       ConstStr255Param  base_lwfn,
+                       UInt8*            path_lwfn,
+                       size_t            path_size )
+  {
+    FSRef   ref, par_ref;
+    size_t  dirname_len;
+
+
+    /* Pathname for FSRef can be in various formats: HFS, HFS+, and POSIX. */
+    /* We should not extract parent directory by string manipulation.      */
+
+    if ( noErr != FSPathMakeRef( path_fond, &ref, FALSE ) )
+      return FT_THROW( Invalid_Argument );
+
+    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone,
+                                    NULL, NULL, NULL, &par_ref ) )
+      return FT_THROW( Invalid_Argument );
+
+    if ( noErr != FSRefMakePath( &par_ref, path_lwfn, path_size ) )
+      return FT_THROW( Invalid_Argument );
+
+    if ( ft_strlen( (char *)path_lwfn ) + 1 + base_lwfn[0] > path_size )
+      return FT_THROW( Invalid_Argument );
+
+    /* now we have absolute dirname in path_lwfn */
+    ft_strcat( (char *)path_lwfn, "/" );
+    dirname_len = ft_strlen( (char *)path_lwfn );
+    ft_strcat( (char *)path_lwfn, (char *)base_lwfn + 1 );
+    path_lwfn[dirname_len + base_lwfn[0]] = '\0';
+
+    if ( noErr != FSPathMakeRef( path_lwfn, &ref, FALSE ) )
+      return FT_THROW( Cannot_Open_Resource );
+
+    if ( noErr != FSGetCatalogInfo( &ref, kFSCatInfoNone,
+                                    NULL, NULL, NULL, NULL ) )
+      return FT_THROW( Cannot_Open_Resource );
+
+    return FT_Err_Ok;
+  }
+
+
+  static short
+  count_faces( Handle        fond,
+               const UInt8*  pathname )
+  {
+    ResID     sfnt_id;
+    short     have_sfnt, have_lwfn;
+    Str255    lwfn_file_name;
+    UInt8     buff[PATH_MAX];
+    FT_Error  err;
+    short     num_faces;
+
+
+    have_sfnt = have_lwfn = 0;
+
+    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, 0 );
+
+    if ( lwfn_file_name[0] )
+    {
+      err = lookup_lwfn_by_fond( pathname, lwfn_file_name,
+                                 buff, sizeof ( buff )  );
+      if ( !err )
+        have_lwfn = 1;
+    }
+
+    if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
+      num_faces = 1;
+    else
+      num_faces = count_faces_scalable( *fond );
+
+    return num_faces;
+  }
+
+
+  /* Read Type 1 data from the POST resources inside the LWFN file,
+     return a PFB buffer.  This is somewhat convoluted because the FT2
+     PFB parser wants the ASCII header as one chunk, and the LWFN
+     chunks are often not organized that way, so we glue chunks
+     of the same type together. */
+  static FT_Error
+  read_lwfn( FT_Memory      memory,
+             ResFileRefNum  res,
+             FT_Byte**      pfb_data,
+             FT_ULong*      size )
+  {
+    FT_Error       error = FT_Err_Ok;
+    ResID          res_id;
+    unsigned char  *buffer, *p, *size_p = NULL;
+    FT_ULong       total_size = 0;
+    FT_ULong       old_total_size = 0;
+    FT_ULong       post_size, pfb_chunk_size;
+    Handle         post_data;
+    char           code, last_code;
+
+
+    UseResFile( res );
+
+    /* First pass: load all POST resources, and determine the size of */
+    /* the output buffer.                                             */
+    res_id    = 501;
+    last_code = -1;
+
+    for (;;)
+    {
+      post_data = Get1Resource( TTAG_POST, res_id++ );
+      if ( !post_data )
+        break;  /* we are done */
+
+      code = (*post_data)[0];
+
+      if ( code != last_code )
+      {
+        if ( code == 5 )
+          total_size += 2; /* just the end code */
+        else
+          total_size += 6; /* code + 4 bytes chunk length */
+      }
+
+      total_size += (FT_ULong)GetHandleSize( post_data ) - 2;
+      last_code = code;
+
+      /* detect resource fork overflow */
+      if ( FT_MAC_RFORK_MAX_LEN < total_size )
+      {
+        error = FT_THROW( Array_Too_Large );
+        goto Error;
+      }
+
+      old_total_size = total_size;
+    }
+
+    if ( FT_ALLOC( buffer, (FT_Long)total_size ) )
+      goto Error;
+
+    /* Second pass: append all POST data to the buffer, add PFB fields. */
+    /* Glue all consecutive chunks of the same type together.           */
+    p              = buffer;
+    res_id         = 501;
+    last_code      = -1;
+    pfb_chunk_size = 0;
+
+    for (;;)
+    {
+      post_data = Get1Resource( TTAG_POST, res_id++ );
+      if ( !post_data )
+        break;  /* we are done */
+
+      post_size = (FT_ULong)GetHandleSize( post_data ) - 2;
+      code = (*post_data)[0];
+
+      if ( code != last_code )
+      {
+        if ( last_code != -1 )
+        {
+          /* we are done adding a chunk, fill in the size field */
+          if ( size_p )
+          {
+            *size_p++ = (FT_Byte)(   pfb_chunk_size         & 0xFF );
+            *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8  ) & 0xFF );
+            *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 16 ) & 0xFF );
+            *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 24 ) & 0xFF );
+          }
+          pfb_chunk_size = 0;
+        }
+
+        *p++ = 0x80;
+        if ( code == 5 )
+          *p++ = 0x03;  /* the end */
+        else if ( code == 2 )
+          *p++ = 0x02;  /* binary segment */
+        else
+          *p++ = 0x01;  /* ASCII segment */
+
+        if ( code != 5 )
+        {
+          size_p = p;   /* save for later */
+          p += 4;       /* make space for size field */
+        }
+      }
+
+      ft_memcpy( p, *post_data + 2, post_size );
+      pfb_chunk_size += post_size;
+      p += post_size;
+      last_code = code;
+    }
+
+    *pfb_data = buffer;
+    *size = total_size;
+
+  Error:
+    CloseResFile( res );
+    return error;
+  }
+
+
+  /* Create a new FT_Face from a file path to an LWFN file. */
+  static FT_Error
+  FT_New_Face_From_LWFN( FT_Library    library,
+                         const UInt8*  pathname,
+                         FT_Long       face_index,
+                         FT_Face*      aface )
+  {
+    FT_Byte*       pfb_data;
+    FT_ULong       pfb_size;
+    FT_Error       error;
+    ResFileRefNum  res;
+
+
+    if ( noErr != FT_FSPathMakeRes( pathname, &res ) )
+      return FT_THROW( Cannot_Open_Resource );
+
+    pfb_data = NULL;
+    pfb_size = 0;
+    error = read_lwfn( library->memory, res, &pfb_data, &pfb_size );
+    CloseResFile( res ); /* PFB is already loaded, useless anymore */
+    if ( error )
+      return error;
+
+    return open_face_from_buffer( library,
+                                  pfb_data,
+                                  pfb_size,
+                                  face_index,
+                                  "type1",
+                                  aface );
+  }
+
+
+  /* Create a new FT_Face from an SFNT resource, specified by res ID. */
+  static FT_Error
+  FT_New_Face_From_SFNT( FT_Library  library,
+                         ResID       sfnt_id,
+                         FT_Long     face_index,
+                         FT_Face*    aface )
+  {
+    Handle     sfnt = NULL;
+    FT_Byte*   sfnt_data;
+    size_t     sfnt_size;
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = library->memory;
+    int        is_cff, is_sfnt_ps;
+
+
+    sfnt = GetResource( TTAG_sfnt, sfnt_id );
+    if ( !sfnt )
+      return FT_THROW( Invalid_Handle );
+
+    sfnt_size = (FT_ULong)GetHandleSize( sfnt );
+
+    /* detect resource fork overflow */
+    if ( FT_MAC_RFORK_MAX_LEN < sfnt_size )
+      return FT_THROW( Array_Too_Large );
+
+    if ( FT_ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
+    {
+      ReleaseResource( sfnt );
+      return error;
+    }
+
+    ft_memcpy( sfnt_data, *sfnt, sfnt_size );
+    ReleaseResource( sfnt );
+
+    is_cff     = sfnt_size > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
+    is_sfnt_ps = sfnt_size > 4 && !ft_memcmp( sfnt_data, "typ1", 4 );
+
+    if ( is_sfnt_ps )
+    {
+      FT_Stream  stream;
+
+
+      if ( FT_NEW( stream ) )
+        goto Try_OpenType;
+
+      FT_Stream_OpenMemory( stream, sfnt_data, sfnt_size );
+      if ( !open_face_PS_from_sfnt_stream( library,
+                                           stream,
+                                           face_index,
+                                           0, NULL,
+                                           aface ) )
+      {
+        FT_Stream_Close( stream );
+        FT_FREE( stream );
+        FT_FREE( sfnt_data );
+        goto Exit;
+      }
+
+      FT_FREE( stream );
+    }
+  Try_OpenType:
+    error = open_face_from_buffer( library,
+                                   sfnt_data,
+                                   sfnt_size,
+                                   face_index,
+                                   is_cff ? "cff" : "truetype",
+                                   aface );
+  Exit:
+    return error;
+  }
+
+
+  /* Create a new FT_Face from a file path to a suitcase file. */
+  static FT_Error
+  FT_New_Face_From_Suitcase( FT_Library    library,
+                             const UInt8*  pathname,
+                             FT_Long       face_index,
+                             FT_Face*      aface )
+  {
+    FT_Error       error = FT_ERR( Cannot_Open_Resource );
+    ResFileRefNum  res_ref;
+    ResourceIndex  res_index;
+    Handle         fond;
+    short          num_faces_in_res;
+
+
+    if ( noErr != FT_FSPathMakeRes( pathname, &res_ref ) )
+      return FT_THROW( Cannot_Open_Resource );
+
+    UseResFile( res_ref );
+    if ( ResError() )
+      return FT_THROW( Cannot_Open_Resource );
+
+    num_faces_in_res = 0;
+    for ( res_index = 1; ; res_index++ )
+    {
+      short  num_faces_in_fond;
+
+
+      fond = Get1IndResource( TTAG_FOND, res_index );
+      if ( ResError() )
+        break;
+
+      num_faces_in_fond  = count_faces( fond, pathname );
+      num_faces_in_res  += num_faces_in_fond;
+
+      if ( 0 <= face_index && face_index < num_faces_in_fond && error )
+        error = FT_New_Face_From_FOND( library, fond, face_index, aface );
+
+      face_index -= num_faces_in_fond;
+    }
+
+    CloseResFile( res_ref );
+    if ( !error && aface && *aface )
+      (*aface)->num_faces = num_faces_in_res;
+    return error;
+  }
+
+
+  /* documentation is in ftmac.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_New_Face_From_FOND( FT_Library  library,
+                         Handle      fond,
+                         FT_Long     face_index,
+                         FT_Face*    aface )
+  {
+    short     have_sfnt, have_lwfn = 0;
+    ResID     sfnt_id, fond_id;
+    OSType    fond_type;
+    Str255    fond_name;
+    Str255    lwfn_file_name;
+    UInt8     path_lwfn[PATH_MAX];
+    OSErr     err;
+    FT_Error  error = FT_Err_Ok;
+
+
+    /* check of `library' and `aface' delayed to `FT_New_Face_From_XXX' */
+
+    GetResInfo( fond, &fond_id, &fond_type, fond_name );
+    if ( ResError() != noErr || fond_type != TTAG_FOND )
+      return FT_THROW( Invalid_File_Format );
+
+    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index );
+
+    if ( lwfn_file_name[0] )
+    {
+      ResFileRefNum  res;
+
+
+      res = HomeResFile( fond );
+      if ( noErr != ResError() )
+        goto found_no_lwfn_file;
+
+      {
+        UInt8  path_fond[PATH_MAX];
+        FSRef  ref;
+
+
+        err = FSGetForkCBInfo( res, kFSInvalidVolumeRefNum,
+                               NULL, NULL, NULL, &ref, NULL );
+        if ( noErr != err )
+          goto found_no_lwfn_file;
+
+        err = FSRefMakePath( &ref, path_fond, sizeof ( path_fond ) );
+        if ( noErr != err )
+          goto found_no_lwfn_file;
+
+        error = lookup_lwfn_by_fond( path_fond, lwfn_file_name,
+                                     path_lwfn, sizeof ( path_lwfn ) );
+        if ( !error )
+          have_lwfn = 1;
+      }
+    }
+
+    if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
+      error = FT_New_Face_From_LWFN( library,
+                                     path_lwfn,
+                                     face_index,
+                                     aface );
+    else
+      error = FT_THROW( Unknown_File_Format );
+
+  found_no_lwfn_file:
+    if ( have_sfnt && error )
+      error = FT_New_Face_From_SFNT( library,
+                                     sfnt_id,
+                                     face_index,
+                                     aface );
+
+    return error;
+  }
+
+
+  /* Common function to load a new FT_Face from a resource file. */
+  static FT_Error
+  FT_New_Face_From_Resource( FT_Library    library,
+                             const UInt8*  pathname,
+                             FT_Long       face_index,
+                             FT_Face*      aface )
+  {
+    OSType    file_type;
+    FT_Error  error;
+
+
+    /* LWFN is a (very) specific file format, check for it explicitly */
+    file_type = get_file_type_from_path( pathname );
+    if ( file_type == TTAG_LWFN )
+      return FT_New_Face_From_LWFN( library, pathname, face_index, aface );
+
+    /* Otherwise the file type doesn't matter (there are more than  */
+    /* `FFIL' and `tfil').  Just try opening it as a font suitcase; */
+    /* if it works, fine.                                           */
+
+    error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface );
+    if ( error )
+    {
+      /* let it fall through to normal loader (.ttf, .otf, etc.); */
+      /* we signal this by returning no error and no FT_Face      */
+      *aface = NULL;
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Face                                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This is the Mac-specific implementation of FT_New_Face.  In        */
+  /*    addition to the standard FT_New_Face() functionality, it also      */
+  /*    accepts pathnames to Mac suitcase files.  For further              */
+  /*    documentation see the original FT_New_Face() in freetype.h.        */
+  /*                                                                       */
+  FT_EXPORT_DEF( FT_Error )
+  FT_New_Face( FT_Library   library,
+               const char*  pathname,
+               FT_Long      face_index,
+               FT_Face*     aface )
+  {
+    FT_Open_Args  args;
+    FT_Error      error;
+
+
+    /* test for valid `library' and `aface' delayed to FT_Open_Face() */
+    if ( !pathname )
+      return FT_THROW( Invalid_Argument );
+
+    *aface = NULL;
+
+    /* try resourcefork based font: LWFN, FFIL */
+    error = FT_New_Face_From_Resource( library, (UInt8 *)pathname,
+                                       face_index, aface );
+    if ( error || *aface )
+      return error;
+
+    /* let it fall through to normal loader (.ttf, .otf, etc.) */
+    args.flags    = FT_OPEN_PATHNAME;
+    args.pathname = (char*)pathname;
+
+    return FT_Open_Face( library, &args, face_index, aface );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Face_From_FSRef                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    FT_New_Face_From_FSRef is identical to FT_New_Face except it       */
+  /*    accepts an FSRef instead of a path.                                */
+  /*                                                                       */
+  /* This function is deprecated because Carbon data types (FSRef)         */
+  /* are not cross-platform, and thus not suitable for the freetype API.   */
+  FT_EXPORT_DEF( FT_Error )
+  FT_New_Face_From_FSRef( FT_Library    library,
+                          const FSRef*  ref,
+                          FT_Long       face_index,
+                          FT_Face*      aface )
+  {
+    FT_Error      error;
+    FT_Open_Args  args;
+
+    OSErr  err;
+    UInt8  pathname[PATH_MAX];
+
+
+    /* check of `library' and `aface' delayed to */
+    /* `FT_New_Face_From_Resource'               */
+
+    if ( !ref )
+      return FT_THROW( Invalid_Argument );
+
+    err = FSRefMakePath( ref, pathname, sizeof ( pathname ) );
+    if ( err )
+      error = FT_THROW( Cannot_Open_Resource );
+
+    error = FT_New_Face_From_Resource( library, pathname, face_index, aface );
+    if ( error || *aface )
+      return error;
+
+    /* fallback to datafork font */
+    args.flags    = FT_OPEN_PATHNAME;
+    args.pathname = (char*)pathname;
+    return FT_Open_Face( library, &args, face_index, aface );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_New_Face_From_FSSpec                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    FT_New_Face_From_FSSpec is identical to FT_New_Face except it      */
+  /*    accepts an FSSpec instead of a path.                               */
+  /*                                                                       */
+  /* This function is deprecated because FSSpec is deprecated in Mac OS X  */
+  FT_EXPORT_DEF( FT_Error )
+  FT_New_Face_From_FSSpec( FT_Library     library,
+                           const FSSpec*  spec,
+                           FT_Long        face_index,
+                           FT_Face*       aface )
+  {
+#if ( __LP64__ ) || ( defined( MAC_OS_X_VERSION_10_5 ) && \
+      ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) )
+    FT_UNUSED( library );
+    FT_UNUSED( spec );
+    FT_UNUSED( face_index );
+    FT_UNUSED( aface );
+
+    return FT_THROW( Unimplemented_Feature );
+#else
+    FSRef  ref;
+
+
+    /* check of `library' and `aface' delayed to `FT_New_Face_From_FSRef' */
+
+    if ( !spec || FSpMakeFSRef( spec, &ref ) != noErr )
+      return FT_THROW( Invalid_Argument );
+    else
+      return FT_New_Face_From_FSRef( library, &ref, face_index, aface );
+#endif
+  }
+
+#endif /* FT_MACINTOSH */
+
+
+/* END */
diff --git a/src/base/ftmm.c b/src/base/ftmm.c
index 6b759ca..5705f21 100644
--- a/src/base/ftmm.c
+++ b/src/base/ftmm.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Multiple Master font support (body).                                 */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -22,6 +22,7 @@
 #include FT_MULTIPLE_MASTERS_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_SERVICE_MULTIPLE_MASTERS_H
+#include FT_SERVICE_METRICS_VARIATIONS_H
 
 
   /*************************************************************************/
@@ -62,6 +63,34 @@
   }
 
 
+  static FT_Error
+  ft_face_get_mvar_service( FT_Face                        face,
+                            FT_Service_MetricsVariations  *aservice )
+  {
+    FT_Error  error;
+
+
+    *aservice = NULL;
+
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    error = FT_ERR( Invalid_Argument );
+
+    if ( FT_HAS_MULTIPLE_MASTERS( face ) )
+    {
+      FT_FACE_LOOKUP_SERVICE( face,
+                              *aservice,
+                              METRICS_VARIATIONS );
+
+      if ( *aservice )
+        error = FT_Err_Ok;
+    }
+
+    return error;
+  }
+
+
   /* documentation is in ftmm.h */
 
   FT_EXPORT_DEF( FT_Error )
@@ -140,6 +169,13 @@
         error = service->set_mm_design( face, num_coords, coords );
     }
 
+    /* enforce recomputation of auto-hinting data */
+    if ( !error && face->autohint.finalizer )
+    {
+      face->autohint.finalizer( face->autohint.data );
+      face->autohint.data = NULL;
+    }
+
     return error;
   }
 
@@ -151,6 +187,51 @@
                                  FT_UInt    num_coords,
                                  FT_Fixed*  coords )
   {
+    FT_Error                      error;
+    FT_Service_MultiMasters       service_mm;
+    FT_Service_MetricsVariations  service_mvar;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( !coords )
+      return FT_THROW( Invalid_Argument );
+
+    error = ft_face_get_mm_service( face, &service_mm );
+    if ( !error )
+    {
+      error = FT_ERR( Invalid_Argument );
+      if ( service_mm->set_var_design )
+        error = service_mm->set_var_design( face, num_coords, coords );
+    }
+
+    if ( !error )
+      error = ft_face_get_mvar_service( face, &service_mvar );
+
+    if ( !error )
+    {
+      if ( service_mvar->metrics_adjust )
+        service_mvar->metrics_adjust( face );
+    }
+
+    /* enforce recomputation of auto-hinting data */
+    if ( !error && face->autohint.finalizer )
+    {
+      face->autohint.finalizer( face->autohint.data );
+      face->autohint.data = NULL;
+    }
+
+    return error;
+  }
+
+
+  /* documentation is in ftmm.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_Var_Design_Coordinates( FT_Face    face,
+                                 FT_UInt    num_coords,
+                                 FT_Fixed*  coords )
+  {
     FT_Error                 error;
     FT_Service_MultiMasters  service;
 
@@ -164,8 +245,8 @@
     if ( !error )
     {
       error = FT_ERR( Invalid_Argument );
-      if ( service->set_var_design )
-        error = service->set_var_design( face, num_coords, coords );
+      if ( service->get_var_design )
+        error = service->get_var_design( face, num_coords, coords );
     }
 
     return error;
@@ -179,8 +260,9 @@
                                FT_UInt    num_coords,
                                FT_Fixed*  coords )
   {
-    FT_Error                 error;
-    FT_Service_MultiMasters  service;
+    FT_Error                      error;
+    FT_Service_MultiMasters       service_mm;
+    FT_Service_MetricsVariations  service_mvar;
 
 
     /* check of `face' delayed to `ft_face_get_mm_service' */
@@ -188,12 +270,28 @@
     if ( !coords )
       return FT_THROW( Invalid_Argument );
 
-    error = ft_face_get_mm_service( face, &service );
+    error = ft_face_get_mm_service( face, &service_mm );
     if ( !error )
     {
       error = FT_ERR( Invalid_Argument );
-      if ( service->set_mm_blend )
-         error = service->set_mm_blend( face, num_coords, coords );
+      if ( service_mm->set_mm_blend )
+        error = service_mm->set_mm_blend( face, num_coords, coords );
+    }
+
+    if ( !error )
+      error = ft_face_get_mvar_service( face, &service_mvar );
+
+    if ( !error )
+    {
+      if ( service_mvar->metrics_adjust )
+        service_mvar->metrics_adjust( face );
+    }
+
+    /* enforce recomputation of auto-hinting data */
+    if ( !error && face->autohint.finalizer )
+    {
+      face->autohint.finalizer( face->autohint.data );
+      face->autohint.data = NULL;
     }
 
     return error;
@@ -210,6 +308,51 @@
                                 FT_UInt    num_coords,
                                 FT_Fixed*  coords )
   {
+    FT_Error                      error;
+    FT_Service_MultiMasters       service_mm;
+    FT_Service_MetricsVariations  service_mvar;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( !coords )
+      return FT_THROW( Invalid_Argument );
+
+    error = ft_face_get_mm_service( face, &service_mm );
+    if ( !error )
+    {
+      error = FT_ERR( Invalid_Argument );
+      if ( service_mm->set_mm_blend )
+        error = service_mm->set_mm_blend( face, num_coords, coords );
+    }
+
+    if ( !error )
+      error = ft_face_get_mvar_service( face, &service_mvar );
+
+    if ( !error )
+    {
+      if ( service_mvar->metrics_adjust )
+        service_mvar->metrics_adjust( face );
+    }
+
+    /* enforce recomputation of auto-hinting data */
+    if ( !error && face->autohint.finalizer )
+    {
+      face->autohint.finalizer( face->autohint.data );
+      face->autohint.data = NULL;
+    }
+
+    return error;
+  }
+
+
+  /* documentation is in ftmm.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_MM_Blend_Coordinates( FT_Face    face,
+                               FT_UInt    num_coords,
+                               FT_Fixed*  coords )
+  {
     FT_Error                 error;
     FT_Service_MultiMasters  service;
 
@@ -223,8 +366,39 @@
     if ( !error )
     {
       error = FT_ERR( Invalid_Argument );
-      if ( service->set_mm_blend )
-         error = service->set_mm_blend( face, num_coords, coords );
+      if ( service->get_mm_blend )
+        error = service->get_mm_blend( face, num_coords, coords );
+    }
+
+    return error;
+  }
+
+
+  /* documentation is in ftmm.h */
+
+  /* This is exactly the same as the previous function.  It exists for */
+  /* orthogonality.                                                    */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_Var_Blend_Coordinates( FT_Face    face,
+                                FT_UInt    num_coords,
+                                FT_Fixed*  coords )
+  {
+    FT_Error                 error;
+    FT_Service_MultiMasters  service;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    if ( !coords )
+      return FT_THROW( Invalid_Argument );
+
+    error = ft_face_get_mm_service( face, &service );
+    if ( !error )
+    {
+      error = FT_ERR( Invalid_Argument );
+      if ( service->get_mm_blend )
+        error = service->get_mm_blend( face, num_coords, coords );
     }
 
     return error;
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 060d78e..59d65e2 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType private base classes (body).                            */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -79,6 +79,15 @@
 #define GRID_FIT_METRICS
 
 
+  /* forward declaration */
+  static FT_Error
+  ft_open_face_internal( FT_Library           library,
+                         const FT_Open_Args*  args,
+                         FT_Long              face_index,
+                         FT_Face             *aface,
+                         FT_Bool              test_mac_fonts );
+
+
   FT_BASE_DEF( FT_Pointer )
   ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
                           const char*     service_id )
@@ -453,7 +462,8 @@
 
 
   Exit:
-    FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
+    FT_TRACE4(( "FT_New_GlyphSlot: Return 0x%x\n", error ));
+
     return error;
   }
 
@@ -1105,7 +1115,7 @@
 
     end = first + face->num_charmaps;  /* points after the last one */
 
-    for ( cur = first; cur < end; ++cur )
+    for ( cur = first; cur < end; cur++ )
     {
       if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE    &&
            cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
@@ -1240,7 +1250,7 @@
     args.pathname = (char*)pathname;
     args.stream   = NULL;
 
-    return FT_Open_Face( library, &args, face_index, aface );
+    return ft_open_face_internal( library, &args, face_index, aface, 1 );
   }
 
 #endif
@@ -1267,7 +1277,7 @@
     args.memory_size = file_size;
     args.stream      = NULL;
 
-    return FT_Open_Face( library, &args, face_index, aface );
+    return ft_open_face_internal( library, &args, face_index, aface, 1 );
   }
 
 
@@ -1302,7 +1312,7 @@
 
   /* Finalizer for a memory stream; gets called by FT_Done_Face(). */
   /* It frees the memory it uses.                                  */
-  /* From ftmac.c.                                                 */
+  /* From `ftmac.c'.                                               */
   static void
   memory_stream_close( FT_Stream  stream )
   {
@@ -1318,7 +1328,7 @@
 
 
   /* Create a new memory stream from a buffer and a size. */
-  /* From ftmac.c.                                        */
+  /* From `ftmac.c'.                                      */
   static FT_Error
   new_memory_stream( FT_Library           library,
                      FT_Byte*             base,
@@ -1338,7 +1348,7 @@
       return FT_THROW( Invalid_Argument );
 
     *astream = NULL;
-    memory = library->memory;
+    memory   = library->memory;
     if ( FT_NEW( stream ) )
       goto Exit;
 
@@ -1354,7 +1364,7 @@
 
 
   /* Create a new FT_Face given a buffer and a driver name. */
-  /* from ftmac.c */
+  /* From `ftmac.c'.                                        */
   FT_LOCAL_DEF( FT_Error )
   open_face_from_buffer( FT_Library   library,
                          FT_Byte*     base,
@@ -1380,11 +1390,11 @@
       return error;
     }
 
-    args.flags = FT_OPEN_STREAM;
+    args.flags  = FT_OPEN_STREAM;
     args.stream = stream;
     if ( driver_name )
     {
-      args.flags = args.flags | FT_OPEN_DRIVER;
+      args.flags  = args.flags | FT_OPEN_DRIVER;
       args.driver = FT_Get_Module( library, driver_name );
     }
 
@@ -1398,9 +1408,9 @@
       face_index &= 0x7FFF0000L; /* retain GX data */
 #endif
 
-    error = FT_Open_Face( library, &args, face_index, aface );
+    error = ft_open_face_internal( library, &args, face_index, aface, 0 );
 
-    if ( error == FT_Err_Ok )
+    if ( !error )
       (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
     else
 #ifdef FT_MACINTOSH
@@ -1592,6 +1602,7 @@
   {
     FT_Error   error  = FT_ERR( Cannot_Open_Resource );
     FT_Memory  memory = library->memory;
+
     FT_Byte*   pfb_data = NULL;
     int        i, type, flags;
     FT_ULong   len;
@@ -1607,12 +1618,12 @@
     /* Find the length of all the POST resources, concatenated.  Assume */
     /* worst case (each resource in its own section).                   */
     pfb_len = 0;
-    for ( i = 0; i < resource_cnt; ++i )
+    for ( i = 0; i < resource_cnt; i++ )
     {
       error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] );
       if ( error )
         goto Exit;
-      if ( FT_READ_ULONG( temp ) )
+      if ( FT_READ_ULONG( temp ) )  /* actually LONG */
         goto Exit;
 
       /* FT2 allocator takes signed long buffer length,
@@ -1620,12 +1631,15 @@
        */
       FT_TRACE4(( "                 POST fragment #%d: length=0x%08x"
                   " total pfb_len=0x%08x\n",
-                  i, temp, pfb_len + temp + 6));
+                  i, temp, pfb_len + temp + 6 ));
+
       if ( FT_MAC_RFORK_MAX_LEN < temp               ||
            FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 )
       {
         FT_TRACE2(( "             MacOS resource length cannot exceed"
-                    " 0x%08x\n", FT_MAC_RFORK_MAX_LEN ));
+                    " 0x%08x\n",
+                    FT_MAC_RFORK_MAX_LEN ));
+
         error = FT_THROW( Invalid_Offset );
         goto Exit;
       }
@@ -1633,15 +1647,20 @@
       pfb_len += temp + 6;
     }
 
-    FT_TRACE2(( "             total buffer size to concatenate %d"
-                " POST fragments: 0x%08x\n",
-                 resource_cnt, pfb_len + 2));
-    if ( pfb_len + 2 < 6 ) {
+    FT_TRACE2(( "             total buffer size to concatenate"
+                " %d POST fragments: 0x%08x\n",
+                 resource_cnt, pfb_len + 2 ));
+
+    if ( pfb_len + 2 < 6 )
+    {
       FT_TRACE2(( "             too long fragment length makes"
-                  " pfb_len confused: pfb_len=0x%08x\n", pfb_len ));
+                  " pfb_len confused: pfb_len=0x%08x\n",
+                  pfb_len ));
+
       error = FT_THROW( Array_Too_Large );
       goto Exit;
     }
+
     if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
       goto Exit;
 
@@ -1654,9 +1673,10 @@
     pfb_pos     = 6;
     pfb_lenpos  = 2;
 
-    len = 0;
+    len  = 0;
     type = 1;
-    for ( i = 0; i < resource_cnt; ++i )
+
+    for ( i = 0; i < resource_cnt; i++ )
     {
       error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] );
       if ( error )
@@ -1675,18 +1695,24 @@
 
       if ( FT_READ_USHORT( flags ) )
         goto Exit2;
-      FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
-                   i, offsets[i], rlen, flags ));
+
+      FT_TRACE3(( "POST fragment[%d]:"
+                  " offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
+                  i, offsets[i], rlen, flags ));
 
       error = FT_ERR( Array_Too_Large );
-      /* postpone the check of rlen longer than buffer until FT_Stream_Read() */
+
+      /* postpone the check of `rlen longer than buffer' */
+      /* until `FT_Stream_Read'                          */
+
       if ( ( flags >> 8 ) == 0 )        /* Comment, should not be loaded */
       {
-        FT_TRACE3(( "    Skip POST fragment #%d because it is a comment\n", i ));
+        FT_TRACE3(( "    Skip POST fragment #%d because it is a comment\n",
+                    i ));
         continue;
       }
 
-      /* the flags are part of the resource, so rlen >= 2.  */
+      /* the flags are part of the resource, so rlen >= 2,  */
       /* but some fonts declare rlen = 0 for empty fragment */
       if ( rlen > 2 )
         rlen -= 2;
@@ -1698,9 +1724,12 @@
       else
       {
         FT_TRACE3(( "    Write POST fragment #%d header (4-byte) to buffer"
-                    " %p + 0x%08x\n", i, pfb_data, pfb_lenpos ));
+                    " %p + 0x%08x\n",
+                    i, pfb_data, pfb_lenpos ));
+
         if ( pfb_lenpos + 3 > pfb_len + 2 )
           goto Exit2;
+
         pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
         pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
         pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
@@ -1710,13 +1739,16 @@
           break;
 
         FT_TRACE3(( "    Write POST fragment #%d header (6-byte) to buffer"
-                    " %p + 0x%08x\n", i, pfb_data, pfb_pos ));
+                    " %p + 0x%08x\n",
+                    i, pfb_data, pfb_pos ));
+
         if ( pfb_pos + 6 > pfb_len + 2 )
           goto Exit2;
+
         pfb_data[pfb_pos++] = 0x80;
 
         type = flags >> 8;
-        len = rlen;
+        len  = rlen;
 
         pfb_data[pfb_pos++] = (FT_Byte)type;
         pfb_lenpos          = pfb_pos;
@@ -1730,14 +1762,18 @@
         goto Exit2;
 
       FT_TRACE3(( "    Load POST fragment #%d (%d byte) to buffer"
-                  " %p + 0x%08x\n", i, rlen, pfb_data, pfb_pos ));
+                  " %p + 0x%08x\n",
+                  i, rlen, pfb_data, pfb_pos ));
+
       error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
       if ( error )
         goto Exit2;
+
       pfb_pos += rlen;
     }
 
     error = FT_ERR( Array_Too_Large );
+
     if ( pfb_pos + 2 > pfb_len + 2 )
       goto Exit2;
     pfb_data[pfb_pos++] = 0x80;
@@ -1758,11 +1794,12 @@
                                   aface );
 
   Exit2:
-    if ( error == FT_ERR( Array_Too_Large ) )
+    if ( FT_ERR_EQ( error, Array_Too_Large ) )
       FT_TRACE2(( "  Abort due to too-short buffer to store"
                   " all POST fragments\n" ));
-    else if ( error == FT_ERR( Invalid_Offset ) )
+    else if ( FT_ERR_EQ( error, Invalid_Offset ) )
       FT_TRACE2(( "  Abort due to invalid offset in a POST fragment\n" ));
+
     if ( error )
       error = FT_ERR( Cannot_Open_Resource );
     FT_FREE( pfb_data );
@@ -1806,7 +1843,7 @@
 
     if ( FT_READ_LONG( rlen ) )
       goto Exit;
-    if ( rlen == -1 )
+    if ( rlen < 1 )
       return FT_THROW( Cannot_Open_Resource );
     if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN )
       return FT_THROW( Invalid_Offset );
@@ -1859,19 +1896,19 @@
   {
     FT_Memory  memory = library->memory;
     FT_Error   error;
-    FT_Long    map_offset, rdara_pos;
+    FT_Long    map_offset, rdata_pos;
     FT_Long    *data_offsets;
     FT_Long    count;
 
 
     error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,
-                                       &map_offset, &rdara_pos );
+                                       &map_offset, &rdata_pos );
     if ( error )
       return error;
 
     /* POST resources must be sorted to concatenate properly */
     error = FT_Raccess_Get_DataOffsets( library, stream,
-                                        map_offset, rdara_pos,
+                                        map_offset, rdata_pos,
                                         TTAG_POST, TRUE,
                                         &data_offsets, &count );
     if ( !error )
@@ -1888,7 +1925,7 @@
     /* sfnt resources should not be sorted to preserve the face order by
        QuickDraw API */
     error = FT_Raccess_Get_DataOffsets( library, stream,
-                                        map_offset, rdara_pos,
+                                        map_offset, rdata_pos,
                                         TTAG_sfnt, FALSE,
                                         &data_offsets, &count );
     if ( !error )
@@ -1921,7 +1958,7 @@
     FT_Long        dlen, offset;
 
 
-    if ( NULL == stream )
+    if ( !stream )
       return FT_THROW( Invalid_Stream_Operation );
 
     error = FT_Stream_Seek( stream, 0 );
@@ -1995,13 +2032,15 @@
       {
         FT_TRACE3(( "Skip rule %d: darwin vfs resource fork"
                     " is already checked and"
-                    " no font is found\n", i ));
+                    " no font is found\n",
+                    i ));
         continue;
       }
 
       if ( errors[i] )
       {
-        FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));
+        FT_TRACE3(( "Error 0x%x has occurred in rule %d\n",
+                    errors[i], i ));
         continue;
       }
 
@@ -2111,6 +2150,17 @@
                 FT_Long              face_index,
                 FT_Face             *aface )
   {
+    return ft_open_face_internal( library, args, face_index, aface, 1 );
+  }
+
+
+  static FT_Error
+  ft_open_face_internal( FT_Library           library,
+                         const FT_Open_Args*  args,
+                         FT_Long              face_index,
+                         FT_Face             *aface,
+                         FT_Bool              test_mac_fonts )
+  {
     FT_Error     error;
     FT_Driver    driver = NULL;
     FT_Memory    memory = NULL;
@@ -2121,6 +2171,23 @@
     FT_Module*   cur;
     FT_Module*   limit;
 
+#ifndef FT_CONFIG_OPTION_MAC_FONTS
+    FT_UNUSED( test_mac_fonts );
+#endif
+
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+    FT_TRACE3(( "FT_Open_Face: " ));
+    if ( face_index < 0 )
+      FT_TRACE3(( "Requesting number of faces and named instances\n"));
+    else
+    {
+      FT_TRACE3(( "Requesting face %ld", face_index & 0xFFFFL ));
+      if ( face_index & 0x7FFF0000L )
+        FT_TRACE3(( ", named instance %ld", face_index >> 16 ));
+      FT_TRACE3(( "\n" ));
+    }
+#endif
 
     /* test for valid `library' delayed to `FT_Stream_New' */
 
@@ -2198,7 +2265,8 @@
             goto Success;
 
 #ifdef FT_CONFIG_OPTION_MAC_FONTS
-          if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
+          if ( test_mac_fonts                                           &&
+               ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
                FT_ERR_EQ( error, Table_Missing )                        )
           {
             /* TrueType but essential tables are missing */
@@ -2235,16 +2303,20 @@
         goto Fail2;
 
 #if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
-      error = load_mac_face( library, stream, face_index, aface, args );
-      if ( !error )
+      if ( test_mac_fonts )
       {
-        /* We don't want to go to Success here.  We've already done that. */
-        /* On the other hand, if we succeeded we still need to close this */
-        /* stream (we opened a different stream which extracted the       */
-        /* interesting information out of this stream here.  That stream  */
-        /* will still be open and the face will point to it).             */
-        FT_Stream_Free( stream, external_stream );
-        return error;
+        error = load_mac_face( library, stream, face_index, aface, args );
+        if ( !error )
+        {
+          /* We don't want to go to Success here.  We've already done   */
+          /* that.  On the other hand, if we succeeded we still need to */
+          /* close this stream (we opened a different stream which      */
+          /* extracted the interesting information out of this stream   */
+          /* here.  That stream will still be open and the face will    */
+          /* point to it).                                              */
+          FT_Stream_Free( stream, external_stream );
+          return error;
+        }
       }
 
       if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
@@ -2368,7 +2440,20 @@
       destroy_face( memory, face, driver );
 
   Exit:
-    FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( !error && face_index < 0 )
+    {
+      FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n"
+                  "              and %ld named instance%s for face %ld\n",
+                  face->num_faces,
+                  face->num_faces == 1 ? "" : "s",
+                  face->style_flags >> 16,
+                  ( face->style_flags >> 16 ) == 1 ? "" : "s",
+                  -face_index - 1 ));
+    }
+#endif
+
+    FT_TRACE4(( "FT_Open_Face: Return 0x%x\n", error ));
 
     return error;
   }
@@ -3377,7 +3462,7 @@
     FT_CMap    cmap = NULL;
 
 
-    if ( clazz == NULL || charmap == NULL || charmap->face == NULL )
+    if ( !clazz || !charmap || !charmap->face )
       return FT_THROW( Invalid_Argument );
 
     face   = charmap->face;
@@ -3522,7 +3607,7 @@
       FT_CMap     ucmap = FT_CMAP( face->charmap );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap  vcmap = FT_CMAP( charmap );
 
@@ -3563,7 +3648,7 @@
       FT_CharMap  charmap = find_variant_selector_charmap( face );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap  vcmap = FT_CMAP( charmap );
 
@@ -3602,7 +3687,7 @@
       FT_CharMap  charmap = find_variant_selector_charmap( face );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap    vcmap  = FT_CMAP( charmap );
         FT_Memory  memory = FT_FACE_MEMORY( face );
@@ -3630,7 +3715,7 @@
       FT_CharMap  charmap = find_variant_selector_charmap( face );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap    vcmap  = FT_CMAP( charmap );
         FT_Memory  memory = FT_FACE_MEMORY( face );
@@ -3664,7 +3749,7 @@
       FT_CharMap  charmap = find_variant_selector_charmap( face );
 
 
-      if ( charmap != NULL )
+      if ( charmap )
       {
         FT_CMap    vcmap  = FT_CMAP( charmap );
         FT_Memory  memory = FT_FACE_MEMORY( face );
@@ -3792,7 +3877,7 @@
     if ( face && FT_IS_SFNT( face ) )
     {
       FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
-      if ( service != NULL )
+      if ( service )
         table = service->get_table( face, tag );
     }
 
@@ -3816,7 +3901,7 @@
       return FT_THROW( Invalid_Face_Handle );
 
     FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
-    if ( service == NULL )
+    if ( !service )
       return FT_THROW( Unimplemented_Feature );
 
     return service->load_table( face, tag, offset, buffer, length );
@@ -3841,7 +3926,7 @@
       return FT_THROW( Invalid_Face_Handle );
 
     FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
-    if ( service == NULL )
+    if ( !service )
       return FT_THROW( Unimplemented_Feature );
 
     return service->table_info( face, table_index, tag, &offset, length );
@@ -3863,7 +3948,7 @@
 
     face = charmap->face;
     FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
-    if ( service == NULL )
+    if ( !service )
       return 0;
     if ( service->get_cmap_info( charmap, &cmap_info ))
       return 0;
@@ -3887,7 +3972,7 @@
 
     face = charmap->face;
     FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
-    if ( service == NULL )
+    if ( !service )
       return -1;
     if ( service->get_cmap_info( charmap, &cmap_info ))
       return -1;
@@ -4217,7 +4302,7 @@
     if ( ft_trace_levels[trace_bitmap] >= 3 )
     {
       /* we convert to a single bitmap format for computing the checksum */
-      if ( !error )
+      if ( !error && slot->bitmap.buffer )
       {
         FT_Bitmap  bitmap;
         FT_Error   err;
@@ -4496,7 +4581,8 @@
 
   FT_BASE_DEF( FT_Pointer )
   ft_module_get_service( FT_Module    module,
-                         const char*  service_id )
+                         const char*  service_id,
+                         FT_Bool      global )
   {
     FT_Pointer  result = NULL;
 
@@ -4509,7 +4595,7 @@
       if ( module->clazz->get_interface )
         result = module->clazz->get_interface( module, service_id );
 
-      if ( result == NULL )
+      if ( global && !result )
       {
         /* we didn't find it, look in all other modules then */
         FT_Library  library = module->library;
@@ -4526,7 +4612,7 @@
             if ( cur[0]->clazz->get_interface )
             {
               result = cur[0]->clazz->get_interface( cur[0], service_id );
-              if ( result != NULL )
+              if ( result )
                 break;
             }
           }
@@ -4977,7 +5063,8 @@
 
         service = (FT_Service_TrueTypeEngine)
                     ft_module_get_service( module,
-                                           FT_SERVICE_ID_TRUETYPE_ENGINE );
+                                           FT_SERVICE_ID_TRUETYPE_ENGINE,
+                                           0 );
         if ( service )
           result = service->engine_type;
       }
diff --git a/src/base/ftotval.c b/src/base/ftotval.c
new file mode 100644
index 0000000..5fa0986
--- /dev/null
+++ b/src/base/ftotval.c
@@ -0,0 +1,91 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftotval.c                                                              */
+/*                                                                         */
+/*    FreeType API for validating OpenType tables (body).                  */
+/*                                                                         */
+/*  Copyright 2004-2017 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 FT_INTERNAL_DEBUG_H
+
+#include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_OPENTYPE_VALIDATE_H
+#include FT_OPENTYPE_VALIDATE_H
+
+
+  /* documentation is in ftotval.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_OpenType_Validate( FT_Face    face,
+                        FT_UInt    validation_flags,
+                        FT_Bytes  *BASE_table,
+                        FT_Bytes  *GDEF_table,
+                        FT_Bytes  *GPOS_table,
+                        FT_Bytes  *GSUB_table,
+                        FT_Bytes  *JSTF_table )
+  {
+    FT_Service_OTvalidate  service;
+    FT_Error               error;
+
+
+    if ( !face )
+    {
+      error = FT_THROW( Invalid_Face_Handle );
+      goto Exit;
+    }
+
+    if ( !( BASE_table &&
+            GDEF_table &&
+            GPOS_table &&
+            GSUB_table &&
+            JSTF_table ) )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
+
+    FT_FACE_FIND_GLOBAL_SERVICE( face, service, OPENTYPE_VALIDATE );
+
+    if ( service )
+      error = service->validate( face,
+                                 validation_flags,
+                                 BASE_table,
+                                 GDEF_table,
+                                 GPOS_table,
+                                 GSUB_table,
+                                 JSTF_table );
+    else
+      error = FT_THROW( Unimplemented_Feature );
+
+  Exit:
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_OpenType_Free( FT_Face   face,
+                    FT_Bytes  table )
+  {
+    FT_Memory  memory;
+
+
+    if ( !face )
+      return;
+
+    memory = FT_FACE_MEMORY( face );
+
+    FT_FREE( table );
+  }
+
+
+/* END */
diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c
index fc28225..464a066 100644
--- a/src/base/ftoutln.c
+++ b/src/base/ftoutln.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType outline management (body).                                  */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -287,7 +287,7 @@
     return FT_Err_Ok;
 
   Exit:
-    FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));
+    FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error ));
     return error;
 
   Invalid_Outline:
diff --git a/src/base/ftpatent.c b/src/base/ftpatent.c
index 4861be1..0925a62 100644
--- a/src/base/ftpatent.c
+++ b/src/base/ftpatent.c
@@ -5,7 +5,7 @@
 /*    FreeType API for checking patented TrueType bytecode instructions    */
 /*    (body).  Obsolete, retained for backwards compatibility.             */
 /*                                                                         */
-/*  Copyright 2007-2016 by                                                 */
+/*  Copyright 2007-2017 by                                                 */
 /*  David Turner.                                                          */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftpfr.c b/src/base/ftpfr.c
new file mode 100644
index 0000000..5cc0b70
--- /dev/null
+++ b/src/base/ftpfr.c
@@ -0,0 +1,153 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftpfr.c                                                                */
+/*                                                                         */
+/*    FreeType API for accessing PFR-specific data (body).                 */
+/*                                                                         */
+/*  Copyright 2002-2017 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 FT_INTERNAL_DEBUG_H
+
+#include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_PFR_H
+
+
+  /* check the format */
+  static FT_Service_PfrMetrics
+  ft_pfr_check( FT_Face  face )
+  {
+    FT_Service_PfrMetrics  service = NULL;
+
+
+    if ( face )
+      FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS );
+
+    return service;
+  }
+
+
+  /* documentation is in ftpfr.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_PFR_Metrics( FT_Face    face,
+                      FT_UInt   *aoutline_resolution,
+                      FT_UInt   *ametrics_resolution,
+                      FT_Fixed  *ametrics_x_scale,
+                      FT_Fixed  *ametrics_y_scale )
+  {
+    FT_Error               error = FT_Err_Ok;
+    FT_Service_PfrMetrics  service;
+
+
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    service = ft_pfr_check( face );
+    if ( service )
+    {
+      error = service->get_metrics( face,
+                                    aoutline_resolution,
+                                    ametrics_resolution,
+                                    ametrics_x_scale,
+                                    ametrics_y_scale );
+    }
+    else
+    {
+      FT_Fixed  x_scale, y_scale;
+
+
+      /* this is not a PFR font */
+      if ( aoutline_resolution )
+        *aoutline_resolution = face->units_per_EM;
+
+      if ( ametrics_resolution )
+        *ametrics_resolution = face->units_per_EM;
+
+      x_scale = y_scale = 0x10000L;
+      if ( face->size )
+      {
+        x_scale = face->size->metrics.x_scale;
+        y_scale = face->size->metrics.y_scale;
+      }
+
+      if ( ametrics_x_scale )
+        *ametrics_x_scale = x_scale;
+
+      if ( ametrics_y_scale )
+        *ametrics_y_scale = y_scale;
+
+      error = FT_THROW( Unknown_File_Format );
+    }
+
+    return error;
+  }
+
+
+  /* documentation is in ftpfr.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_PFR_Kerning( FT_Face     face,
+                      FT_UInt     left,
+                      FT_UInt     right,
+                      FT_Vector  *avector )
+  {
+    FT_Error               error;
+    FT_Service_PfrMetrics  service;
+
+
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    if ( !avector )
+      return FT_THROW( Invalid_Argument );
+
+    service = ft_pfr_check( face );
+    if ( service )
+      error = service->get_kerning( face, left, right, avector );
+    else
+      error = FT_Get_Kerning( face, left, right,
+                              FT_KERNING_UNSCALED, avector );
+
+    return error;
+  }
+
+
+  /* documentation is in ftpfr.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_PFR_Advance( FT_Face   face,
+                      FT_UInt   gindex,
+                      FT_Pos   *aadvance )
+  {
+    FT_Error               error;
+    FT_Service_PfrMetrics  service;
+
+
+    if ( !face )
+      return FT_THROW( Invalid_Face_Handle );
+
+    if ( !aadvance )
+      return FT_THROW( Invalid_Argument );
+
+    service = ft_pfr_check( face );
+    if ( service )
+      error = service->get_advance( face, gindex, aadvance );
+    else
+      /* XXX: TODO: PROVIDE ADVANCE-LOADING METHOD TO ALL FONT DRIVERS */
+      error = FT_THROW( Invalid_Argument );
+
+    return error;
+  }
+
+
+/* END */
diff --git a/src/base/ftpic.c b/src/base/ftpic.c
index 03769db..0f84fdd 100644
--- a/src/base/ftpic.c
+++ b/src/base/ftpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services (body).              */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c
index 4660c97..f7b8137 100644
--- a/src/base/ftrfork.c
+++ b/src/base/ftrfork.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Embedded resource forks accessor (body).                             */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  Masatake YAMATO and Redhat K.K.                                        */
 /*                                                                         */
 /*  FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are     */
@@ -56,7 +56,7 @@
   {
     FT_Error       error;
     unsigned char  head[16], head2[16];
-    FT_Long        map_pos, rdata_len;
+    FT_Long        map_pos, map_len, rdata_len;
     int            allzeros, allmatch, i;
     FT_Long        type_list;
 
@@ -67,12 +67,15 @@
     if ( error )
       return error;
 
-    error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );
+    error = FT_Stream_Read( stream, (FT_Byte*)head, 16 );
     if ( error )
       return error;
 
     /* ensure positive values */
-    if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 )
+    if ( head[0]  >= 0x80 ||
+         head[4]  >= 0x80 ||
+         head[8]  >= 0x80 ||
+         head[12] >= 0x80 )
       return FT_THROW( Unknown_File_Format );
 
     *rdata_pos = ( head[ 0] << 24 ) |
@@ -87,14 +90,36 @@
                  ( head[ 9] << 16 ) |
                  ( head[10] <<  8 ) |
                    head[11];
+    map_len    = ( head[12] << 24 ) |
+                 ( head[13] << 16 ) |
+                 ( head[14] <<  8 ) |
+                   head[15];
 
-    /* map_len = head[12] .. head[15] */
-
-    if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 )
+    /* the map must not be empty */
+    if ( !map_pos )
       return FT_THROW( Unknown_File_Format );
 
-    if ( FT_LONG_MAX - rfork_offset < *rdata_pos ||
-         FT_LONG_MAX - rfork_offset < map_pos    )
+    /* check whether rdata and map overlap */
+    if ( *rdata_pos < map_pos )
+    {
+      if ( *rdata_pos > map_pos - rdata_len )
+        return FT_THROW( Unknown_File_Format );
+    }
+    else
+    {
+      if ( map_pos > *rdata_pos - map_len )
+        return FT_THROW( Unknown_File_Format );
+    }
+
+    /* check whether end of rdata or map exceeds stream size */
+    if ( FT_LONG_MAX - rdata_len < *rdata_pos                               ||
+         FT_LONG_MAX - map_len < map_pos                                    ||
+
+         FT_LONG_MAX - ( *rdata_pos + rdata_len ) < rfork_offset            ||
+         FT_LONG_MAX - ( map_pos + map_len ) < rfork_offset                 ||
+
+         (FT_ULong)( rfork_offset + *rdata_pos + rdata_len ) > stream->size ||
+         (FT_ULong)( rfork_offset + map_pos + map_len ) > stream->size      )
       return FT_THROW( Unknown_File_Format );
 
     *rdata_pos += rfork_offset;
@@ -112,7 +137,7 @@
 
     allzeros = 1;
     allmatch = 1;
-    for ( i = 0; i < 16; ++i )
+    for ( i = 0; i < 16; i++ )
     {
       if ( head2[i] != 0 )
         allzeros = 0;
@@ -124,15 +149,14 @@
 
     /* If we have reached this point then it is probably a mac resource */
     /* file.  Now, does it contain any interesting resources?           */
-    /* Skip handle to next resource map, the file resource number, and  */
-    /* attributes.                                                      */
+
     (void)FT_STREAM_SKIP( 4        /* skip handle to next resource map */
                           + 2      /* skip file resource number */
                           + 2 );   /* skip attributes */
 
-    if ( FT_READ_USHORT( type_list ) )
+    if ( FT_READ_SHORT( type_list ) )
       return error;
-    if ( type_list == -1 )
+    if ( type_list < 0 )
       return FT_THROW( Unknown_File_Format );
 
     error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) );
@@ -181,15 +205,34 @@
     if ( error )
       return error;
 
-    if ( FT_READ_USHORT( cnt ) )
+    if ( FT_READ_SHORT( cnt ) )
       return error;
     cnt++;
 
-    for ( i = 0; i < cnt; ++i )
+    /* `rpos' is a signed 16bit integer offset to resource records; the    */
+    /* size of a resource record is 12 bytes.  The map header is 28 bytes, */
+    /* and a type list needs 10 bytes or more.  If we assume that the name */
+    /* list is empty and we have only a single entry in the type list,     */
+    /* there can be at most                                                */
+    /*                                                                     */
+    /*   (32768 - 28 - 10) / 12 = 2727                                     */
+    /*                                                                     */
+    /* resources.                                                          */
+    /*                                                                     */
+    /* A type list starts with a two-byte counter, followed by 10-byte     */
+    /* type records.  Assuming that there are no resources, the number of  */
+    /* type records can be at most                                         */
+    /*                                                                     */
+    /*   (32768 - 28 - 2) / 8 = 4079                                       */
+    /*                                                                     */
+    if ( cnt > 4079 )
+      return FT_THROW( Invalid_Table );
+
+    for ( i = 0; i < cnt; i++ )
     {
       if ( FT_READ_LONG( tag_internal ) ||
-           FT_READ_USHORT( subcnt )     ||
-           FT_READ_USHORT( rpos )       )
+           FT_READ_SHORT( subcnt )      ||
+           FT_READ_SHORT( rpos )        )
         return error;
 
       FT_TRACE2(( "Resource tags: %c%c%c%c\n",
@@ -205,6 +248,11 @@
         *count = subcnt + 1;
         rpos  += map_offset;
 
+        /* a zero count might be valid in the resource specification, */
+        /* however, it is completely useless to us                    */
+        if ( *count < 1 || *count > 2727 )
+          return FT_THROW( Invalid_Table );
+
         error = FT_Stream_Seek( stream, (FT_ULong)rpos );
         if ( error )
           return error;
@@ -212,35 +260,44 @@
         if ( FT_NEW_ARRAY( ref, *count ) )
           return error;
 
-        for ( j = 0; j < *count; ++j )
+        for ( j = 0; j < *count; j++ )
         {
-          if ( FT_READ_USHORT( ref[j].res_id ) )
+          if ( FT_READ_SHORT( ref[j].res_id ) )
             goto Exit;
-          if ( FT_STREAM_SKIP( 2 ) ) /* resource name */
+          if ( FT_STREAM_SKIP( 2 ) )  /* resource name offset */
             goto Exit;
-          if ( FT_READ_LONG( temp ) )
+          if ( FT_READ_LONG( temp ) ) /* attributes (8bit), offset (24bit) */
             goto Exit;
-          if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
+          if ( FT_STREAM_SKIP( 4 ) )  /* mbz */
             goto Exit;
 
+          if ( ref[j].res_id < 0 || temp < 0 )
+          {
+            error = FT_THROW( Invalid_Table );
+            goto Exit;
+          }
+
           ref[j].offset = temp & 0xFFFFFFL;
+
           FT_TRACE3(( "             [%d]:"
                       " resource_id=0x%04x, offset=0x%08x\n",
                       j, ref[j].res_id, ref[j].offset ));
         }
 
-        if (sort_by_res_id)
+        if ( sort_by_res_id )
         {
-          ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ),
-                    ( int(*)(const void*, const void*) )
-                    ft_raccess_sort_ref_by_id );
+          ft_qsort( ref,
+                    (size_t)*count,
+                    sizeof ( FT_RFork_Ref ),
+                    ( int(*)(const void*,
+                             const void*) )ft_raccess_sort_ref_by_id );
 
           FT_TRACE3(( "             -- sort resources by their ids --\n" ));
-          for ( j = 0; j < *count; ++ j ) {
+
+          for ( j = 0; j < *count; j++ )
             FT_TRACE3(( "             [%d]:"
                         " resource_id=0x%04x, offset=0x%08x\n",
                         j, ref[j].res_id, ref[j].offset ));
-          }
         }
 
         if ( FT_NEW_ARRAY( offsets_internal, *count ) )
@@ -250,7 +307,7 @@
          *      gap between reference IDs are acceptable?
          *      further investigation on Apple implementation is needed.
          */
-        for ( j = 0; j < *count; ++j )
+        for ( j = 0; j < *count; j++ )
           offsets_internal[j] = rdata_pos + ref[j].offset;
 
         *offsets = offsets_internal;
diff --git a/src/base/ftsnames.c b/src/base/ftsnames.c
index ce79641..868b429 100644
--- a/src/base/ftsnames.c
+++ b/src/base/ftsnames.c
@@ -7,7 +7,7 @@
 /*                                                                         */
 /*    This is _not_ used to retrieve glyph names!                          */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -54,11 +54,11 @@
 
       if ( idx < (FT_UInt)ttface->num_names )
       {
-        TT_NameEntryRec*  entry = ttface->name_table.names + idx;
+        TT_Name  entry = ttface->name_table.names + idx;
 
 
         /* load name on demand */
-        if ( entry->stringLength > 0 && entry->string == NULL )
+        if ( entry->stringLength > 0 && !entry->string )
         {
           FT_Memory  memory = face->memory;
           FT_Stream  stream = face->stream;
@@ -88,6 +88,58 @@
   }
 
 
+  /* documentation is in ftsnames.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_Sfnt_LangTag( FT_Face          face,
+                       FT_UInt          langID,
+                       FT_SfntLangTag  *alangTag )
+  {
+    FT_Error  error = FT_ERR( Invalid_Argument );
+
+
+    if ( alangTag && face && FT_IS_SFNT( face ) )
+    {
+      TT_Face  ttface = (TT_Face)face;
+
+
+      if ( ttface->name_table.format != 1 )
+        return FT_THROW( Invalid_Table );
+
+      if ( langID > 0x8000U                                        &&
+           langID - 0x8000U < ttface->name_table.numLangTagRecords )
+      {
+        TT_LangTag  entry = ttface->name_table.langTags +
+                            ( langID - 0x8000U );
+
+
+        /* load name on demand */
+        if ( entry->stringLength > 0 && !entry->string )
+        {
+          FT_Memory  memory = face->memory;
+          FT_Stream  stream = face->stream;
+
+
+          if ( FT_NEW_ARRAY  ( entry->string, entry->stringLength ) ||
+               FT_STREAM_SEEK( entry->stringOffset )                ||
+               FT_STREAM_READ( entry->string, entry->stringLength ) )
+          {
+            FT_FREE( entry->string );
+            entry->stringLength = 0;
+          }
+        }
+
+        alangTag->string     = (FT_Byte*)entry->string;
+        alangTag->string_len = entry->stringLength;
+
+        error = FT_Err_Ok;
+      }
+    }
+
+    return error;
+  }
+
+
 #endif /* TT_CONFIG_OPTION_SFNT_NAMES */
 
 
diff --git a/src/base/ftstream.c b/src/base/ftstream.c
index bb512a7..a3f8c8b 100644
--- a/src/base/ftstream.c
+++ b/src/base/ftstream.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    I/O stream support (body).                                           */
 /*                                                                         */
-/*  Copyright 2000-2016 by                                                 */
+/*  Copyright 2000-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c
index 4f3c493..d32de0d 100644
--- a/src/base/ftstroke.c
+++ b/src/base/ftstroke.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType path stroker (body).                                        */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index 4b66a33..66dae60 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType synthesizing code for emboldening and slanting (body).      */
 /*                                                                         */
-/*  Copyright 2000-2016 by                                                 */
+/*  Copyright 2000-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -130,7 +130,7 @@
       if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN )
       {
         FT_TRACE1(( "FT_GlyphSlot_Embolden:" ));
-        FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr ));
+        FT_TRACE1(( "too strong emboldening parameter ystr=%d\n", ystr ));
         return;
       }
       error = FT_GlyphSlot_Own_Bitmap( slot );
diff --git a/src/base/ftsystem.c b/src/base/ftsystem.c
index ac1f01c..324f949 100644
--- a/src/base/ftsystem.c
+++ b/src/base/ftsystem.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    ANSI-specific FreeType low-level system interface (body).            */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c
index 7b582c8..7a4d17c 100644
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType trigonometric functions (body).                             */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/fttype1.c b/src/base/fttype1.c
index 5c0fce8..4d16a63 100644
--- a/src/base/fttype1.c
+++ b/src/base/fttype1.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file for PS names support (body).                   */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/base/ftutil.c b/src/base/ftutil.c
index fad7d1a..dccc209 100644
--- a/src/base/ftutil.c
+++ b/src/base/ftutil.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file for memory and list management (body).         */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -74,7 +74,7 @@
     if ( size > 0 )
     {
       block = memory->alloc( memory, size );
-      if ( block == NULL )
+      if ( !block )
         error = FT_THROW( Out_Of_Memory );
     }
     else if ( size < 0 )
@@ -141,7 +141,7 @@
     }
     else if ( cur_count == 0 )
     {
-      FT_ASSERT( block == NULL );
+      FT_ASSERT( !block );
 
       block = ft_mem_alloc( memory, new_count*item_size, &error );
     }
@@ -153,7 +153,7 @@
 
 
       block2 = memory->realloc( memory, cur_size, new_size, block );
-      if ( block2 == NULL )
+      if ( !block2 )
         error = FT_THROW( Out_Of_Memory );
       else
         block = block2;
diff --git a/src/base/ftwinfnt.c b/src/base/ftwinfnt.c
index 89e9155..05baa02 100644
--- a/src/base/ftwinfnt.c
+++ b/src/base/ftwinfnt.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType API for accessing Windows FNT specific info (body).         */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cf2arrst.c b/src/cff/cf2arrst.c
index 89f3e9f..6796450 100644
--- a/src/cff/cf2arrst.c
+++ b/src/cff/cf2arrst.c
@@ -58,7 +58,7 @@
                      FT_Error*     error,
                      size_t        sizeItem )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     /* initialize the structure */
     arrstack->memory    = memory;
@@ -78,7 +78,7 @@
     FT_Memory  memory = arrstack->memory;     /* for FT_FREE */
 
 
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     arrstack->allocated = 0;
     arrstack->count     = 0;
@@ -95,7 +95,7 @@
   cf2_arrstack_setNumElements( CF2_ArrStack  arrstack,
                                size_t        numElements )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     {
       FT_Error   error  = FT_Err_Ok;        /* for FT_REALLOC */
@@ -140,7 +140,7 @@
   cf2_arrstack_setCount( CF2_ArrStack  arrstack,
                          size_t        numElements )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     if ( numElements > arrstack->allocated )
     {
@@ -157,7 +157,7 @@
   FT_LOCAL_DEF( void )
   cf2_arrstack_clear( CF2_ArrStack  arrstack )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     arrstack->count = 0;
   }
@@ -167,7 +167,7 @@
   FT_LOCAL_DEF( size_t )
   cf2_arrstack_size( const CF2_ArrStack  arrstack )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     return arrstack->count;
   }
@@ -176,7 +176,7 @@
   FT_LOCAL_DEF( void* )
   cf2_arrstack_getBuffer( const CF2_ArrStack  arrstack )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     return arrstack->ptr;
   }
@@ -190,7 +190,7 @@
     void*  newPtr;
 
 
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     if ( idx >= arrstack->count )
     {
@@ -212,7 +212,7 @@
   cf2_arrstack_push( CF2_ArrStack  arrstack,
                      const void*   ptr )
   {
-    FT_ASSERT( arrstack != NULL );
+    FT_ASSERT( arrstack );
 
     if ( arrstack->count == arrstack->allocated )
     {
@@ -225,7 +225,7 @@
       }
     }
 
-    FT_ASSERT( ptr != NULL );
+    FT_ASSERT( ptr );
 
     {
       size_t  offset = arrstack->count * arrstack->sizeItem;
diff --git a/src/cff/cf2error.c b/src/cff/cf2error.c
index b5595a3..e3dd69f 100644
--- a/src/cff/cf2error.c
+++ b/src/cff/cf2error.c
@@ -44,7 +44,7 @@
   cf2_setError( FT_Error*  error,
                 FT_Error   value )
   {
-    if ( error && *error == 0 )
+    if ( error && !*error )
       *error = value;
   }
 
diff --git a/src/cff/cf2error.h b/src/cff/cf2error.h
index 512edd1..d2c770d 100644
--- a/src/cff/cf2error.h
+++ b/src/cff/cf2error.h
@@ -66,7 +66,7 @@
    * model our error mechanism on a Java-like exception mechanism.
    * When we assign an error code we are thus `throwing' an error.
    *
-   * The perservation of an error code is done by coding convention.
+   * The preservation of an error code is done by coding convention.
    * Upon a function call if the error code is anything other than
    * `FT_Err_Ok', which is guaranteed to be zero, we
    * will return without altering that error.  This will allow the
diff --git a/src/cff/cf2fixed.h b/src/cff/cf2fixed.h
index 74af377..2e4b503 100644
--- a/src/cff/cf2fixed.h
+++ b/src/cff/cf2fixed.h
@@ -51,8 +51,8 @@
 
 #define CF2_FIXED_MAX      ( (CF2_Fixed)0x7FFFFFFFL )
 #define CF2_FIXED_MIN      ( (CF2_Fixed)0x80000000L )
-#define CF2_FIXED_ONE      0x10000L
-#define CF2_FIXED_EPSILON  0x0001
+#define CF2_FIXED_ONE      ( (CF2_Fixed)0x10000L )
+#define CF2_FIXED_EPSILON  ( (CF2_Fixed)0x0001 )
 
   /* in C 89, left and right shift of negative numbers is  */
   /* implementation specific behaviour in the general case */
diff --git a/src/cff/cf2font.c b/src/cff/cf2font.c
index 83fd348..a86e361 100644
--- a/src/cff/cf2font.c
+++ b/src/cff/cf2font.c
@@ -234,7 +234,8 @@
   }
 
 
-  /* set up values for the current FontDict and matrix */
+  /* set up values for the current FontDict and matrix; */
+  /* called for each glyph to be rendered               */
 
   /* caller's transform is adjusted for subpixel positioning */
   static void
@@ -246,6 +247,9 @@
 
     FT_Bool  needExtraSetup = FALSE;
 
+    CFF_VStoreRec*  vstore;
+    FT_Bool         hasVariations = FALSE;
+
     /* character space units */
     CF2_Fixed  boldenX = font->syntheticEmboldeningAmountX;
     CF2_Fixed  boldenY = font->syntheticEmboldeningAmountY;
@@ -253,6 +257,9 @@
     CFF_SubFont  subFont;
     CF2_Fixed    ppem;
 
+    CF2_UInt   lenNormalizedV = 0;
+    FT_Fixed*  normalizedV    = NULL;
+
 
     /* clear previous error */
     font->error = FT_Err_Ok;
@@ -266,6 +273,48 @@
       needExtraSetup    = TRUE;
     }
 
+    /* check for variation vectors */
+    vstore        = cf2_getVStore( decoder );
+    hasVariations = ( vstore->dataCount != 0 );
+
+    if ( hasVariations )
+    {
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      /* check whether Private DICT in this subfont needs to be reparsed */
+      font->error = cf2_getNormalizedVector( decoder,
+                                             &lenNormalizedV,
+                                             &normalizedV );
+      if ( font->error )
+        return;
+
+      if ( cff_blend_check_vector( &subFont->blend,
+                                   subFont->private_dict.vsindex,
+                                   lenNormalizedV,
+                                   normalizedV ) )
+      {
+        /* blend has changed, reparse */
+        cff_load_private_dict( decoder->cff,
+                               subFont,
+                               lenNormalizedV,
+                               normalizedV );
+        needExtraSetup = TRUE;
+      }
+#endif
+
+      /* copy from subfont */
+      font->blend.font = subFont->blend.font;
+
+      /* clear state of charstring blend */
+      font->blend.usedBV = FALSE;
+
+      /* initialize value for charstring */
+      font->vsindex = subFont->private_dict.vsindex;
+
+      /* store vector inputs for blends in charstring */
+      font->lenNDV = lenNormalizedV;
+      font->NDV    = normalizedV;
+    }
+
     /* if ppem has changed, we need to recompute some cached data         */
     /* note: because of CID font matrix concatenation, ppem and transform */
     /*       do not necessarily track.                                    */
@@ -423,7 +472,8 @@
 
       /* compute blue zones for this instance */
       cf2_blues_init( &font->blues, font );
-    }
+
+    } /* needExtraSetup */
   }
 
 
diff --git a/src/cff/cf2font.h b/src/cff/cf2font.h
index bd05e69..17ecd17 100644
--- a/src/cff/cf2font.h
+++ b/src/cff/cf2font.h
@@ -42,6 +42,7 @@
 
 #include "cf2ft.h"
 #include "cf2blues.h"
+#include "cffload.h"
 
 
 FT_BEGIN_HEADER
@@ -63,6 +64,7 @@
     FT_Memory  memory;
     FT_Error   error;     /* shared error for this instance */
 
+    FT_Bool             isCFF2;
     CF2_RenderingFlags  renderingFlags;
 
     /* variables that depend on Transform:  */
@@ -74,6 +76,12 @@
     CF2_Matrix  outerTransform;    /* post hinting; includes rotations */
     CF2_Fixed   ppem;              /* transform-dependent              */
 
+    /* variation data */
+    CFF_BlendRec  blend;            /* cached charstring blend vector  */
+    CF2_UInt      vsindex;          /* current vsindex                 */
+    CF2_UInt      lenNDV;           /* current length NDV or zero      */
+    FT_Fixed*     NDV;              /* ptr to current NDV or NULL      */
+
     CF2_Int  unitsPerEm;
 
     CF2_Fixed  syntheticEmboldeningAmountX;   /* character space units */
diff --git a/src/cff/cf2ft.c b/src/cff/cf2ft.c
index 55f3206..c0d067e 100644
--- a/src/cff/cf2ft.c
+++ b/src/cff/cf2ft.c
@@ -104,7 +104,8 @@
       FT_Memory  memory = font->memory;
 
 
-      (void)memory;
+      FT_FREE( font->blend.lastNDV );
+      FT_FREE( font->blend.BV );
     }
   }
 
@@ -239,7 +240,7 @@
                     FT_Memory    memory,
                     FT_Error*    error )
   {
-    FT_MEM_ZERO( outline, sizeof ( CF2_OutlineRec ) );
+    FT_ZERO( outline );
 
     outline->root.memory = memory;
     outline->root.error  = error;
@@ -311,7 +312,7 @@
     font = (CF2_Font)decoder->cff->cf2_instance.data;
 
     /* on first glyph, allocate instance structure */
-    if ( decoder->cff->cf2_instance.data == NULL )
+    if ( !decoder->cff->cf2_instance.data )
     {
       decoder->cff->cf2_instance.finalizer =
         (FT_Generic_Finalizer)cf2_free_instance;
@@ -366,6 +367,9 @@
                                &hinted,
                                &scaled );
 
+      /* copy isCFF2 boolean from TT_Face to CF2_Font */
+      font->isCFF2 = builder->face->isCFF2;
+
       font->renderingFlags = 0;
       if ( hinted )
         font->renderingFlags |= CF2_FlagsHinted;
@@ -413,6 +417,44 @@
   }
 
 
+  /* get pointer to VStore structure */
+  FT_LOCAL_DEF( CFF_VStore )
+  cf2_getVStore( CFF_Decoder*  decoder )
+  {
+    FT_ASSERT( decoder && decoder->cff );
+
+    return &decoder->cff->vstore;
+  }
+
+
+  /* get maxstack value from CFF2 Top DICT */
+  FT_LOCAL_DEF( FT_UInt )
+  cf2_getMaxstack( CFF_Decoder*  decoder )
+  {
+    FT_ASSERT( decoder && decoder->cff );
+
+    return decoder->cff->top_font.font_dict.maxstack;
+  }
+
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+  /* Get normalized design vector for current render request; */
+  /* return pointer and length.                               */
+  /*                                                          */
+  /* Note: Uses FT_Fixed not CF2_Fixed for the vector.        */
+  FT_LOCAL_DEF( FT_Error )
+  cf2_getNormalizedVector( CFF_Decoder*  decoder,
+                           CF2_UInt     *len,
+                           FT_Fixed*    *vec )
+  {
+    FT_ASSERT( decoder && decoder->builder.face );
+    FT_ASSERT( vec && len );
+
+    return cff_get_var_blend( decoder->builder.face, len, vec, NULL );
+  }
+#endif
+
+
   /* get `y_ppem' from `CFF_Size' */
   FT_LOCAL_DEF( CF2_Fixed )
   cf2_getPpemY( CFF_Decoder*  decoder )
diff --git a/src/cff/cf2ft.h b/src/cff/cf2ft.h
index 8e55e84..b054a6e 100644
--- a/src/cff/cf2ft.h
+++ b/src/cff/cf2ft.h
@@ -64,6 +64,18 @@
   FT_LOCAL( CFF_SubFont )
   cf2_getSubfont( CFF_Decoder*  decoder );
 
+  FT_LOCAL( CFF_VStore )
+  cf2_getVStore( CFF_Decoder*  decoder );
+
+  FT_LOCAL( FT_UInt )
+  cf2_getMaxstack( CFF_Decoder*  decoder );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+  FT_LOCAL( FT_Error )
+  cf2_getNormalizedVector( CFF_Decoder*  decoder,
+                           CF2_UInt     *len,
+                           FT_Fixed*    *vec );
+#endif
 
   FT_LOCAL( CF2_Fixed )
   cf2_getPpemY( CFF_Decoder*  decoder );
diff --git a/src/cff/cf2hints.c b/src/cff/cf2hints.c
index bbbe8e3..c8f7dfe 100644
--- a/src/cff/cf2hints.c
+++ b/src/cff/cf2hints.c
@@ -401,10 +401,10 @@
         /* calculate all four possibilities; moves down are negative */
         CF2_Fixed  downMoveDown = 0 - fracDown;
         CF2_Fixed  upMoveDown   = 0 - fracUp;
-        CF2_Fixed  downMoveUp   = fracDown == 0
+        CF2_Fixed  downMoveUp   = ( fracDown == 0 )
                                     ? 0
                                     : cf2_intToFixed( 1 ) - fracDown;
-        CF2_Fixed  upMoveUp     = fracUp == 0
+        CF2_Fixed  upMoveUp     = ( fracUp == 0 )
                                     ? 0
                                     : cf2_intToFixed( 1 ) - fracUp;
 
diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index 10e7b4b..6bf298a 100644
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -47,6 +47,8 @@
 
 #include "cf2error.h"
 
+#include "cffload.h"
+
 
   /*************************************************************************/
   /*                                                                       */
@@ -215,8 +217,8 @@
     cf2_cmdESC,          /* 12 */
     cf2_cmdRESERVED_13,  /* 13 */
     cf2_cmdENDCHAR,      /* 14 */
-    cf2_cmdRESERVED_15,  /* 15 */
-    cf2_cmdRESERVED_16,  /* 16 */
+    cf2_cmdVSINDEX,      /* 15 */
+    cf2_cmdBLEND,        /* 16 */
     cf2_cmdRESERVED_17,  /* 17 */
     cf2_cmdHSTEMHM,      /* 18 */
     cf2_cmdHINTMASK,     /* 19 */
@@ -273,7 +275,8 @@
     cf2_escHFLEX,        /* 34 */
     cf2_escFLEX,         /* 35 */
     cf2_escHFLEX1,       /* 36 */
-    cf2_escFLEX1         /* 37 */
+    cf2_escFLEX1,        /* 37 */
+    cf2_escRESERVED_38   /* 38     & all higher     */
   };
 
 
@@ -344,7 +347,7 @@
     vals[0] = *curX;
     vals[1] = *curY;
     index   = 0;
-    isHFlex = readFromStack[9] == FALSE;
+    isHFlex = FT_BOOL( readFromStack[9] == FALSE );
     top     = isHFlex ? 9 : 10;
 
     for ( i = 0; i < top; i++ )
@@ -403,6 +406,43 @@
   }
 
 
+  /* Blend numOperands on the stack,                */
+  /* store results into the first numBlends values, */
+  /* then pop remaining arguments.                  */
+  static void
+  cf2_doBlend( const CFF_Blend  blend,
+               CF2_Stack        opStack,
+               CF2_UInt         numBlends )
+  {
+    CF2_UInt  delta;
+    CF2_UInt  base;
+    CF2_UInt  i, j;
+    CF2_UInt  numOperands = (CF2_UInt)( numBlends * blend->lenBV );
+
+
+    base  = cf2_stack_count( opStack ) - numOperands;
+    delta = base + numBlends;
+
+    for ( i = 0; i < numBlends; i++ )
+    {
+      const CF2_Fixed*  weight = &blend->BV[1];
+
+      /* start with first term */
+      CF2_Fixed  sum = cf2_stack_getReal( opStack, i + base );
+
+
+      for ( j = 1; j < blend->lenBV; j++ )
+        sum += FT_MulFix( *weight++, cf2_stack_getReal( opStack, delta++ ) );
+
+      /* store blended result  */
+      cf2_stack_setReal( opStack, i + base, sum );
+    }
+
+    /* leave only `numBlends' results on stack */
+    cf2_stack_pop( opStack, numOperands - numBlends );
+  }
+
+
   /*
    * `error' is a shared error code used by many objects in this
    * routine.  Before the code continues from an error, it must check and
@@ -445,6 +485,7 @@
     CF2_Fixed  hintOriginY = curY;
 
     CF2_Stack  opStack = NULL;
+    FT_UInt    stackSize;
     FT_Byte    op1;                       /* first opcode byte */
 
     CF2_F16Dot16  storage[CF2_STORAGE_SIZE];    /* for `put' and `get' */
@@ -520,19 +561,24 @@
      * If one of the above operators occurs without explicitly specifying
      * a width, we assume the default width.
      *
+     * CFF2 charstrings always return the default width (0).
+     *
      */
-    haveWidth = FALSE;
+    haveWidth = font->isCFF2 ? TRUE : FALSE;
     *width    = cf2_getDefaultWidthX( decoder );
 
     /*
-     * Note: at this point, all pointers to resources must be NULL
-     * and all local objects must be initialized.
-     * There must be no branches to exit: above this point.
+     * Note: At this point, all pointers to resources must be NULL
+     *       and all local objects must be initialized.
+     *       There must be no branches to `exit:' above this point.
      *
      */
 
     /* allocate an operand stack */
-    opStack = cf2_stack_init( memory, error );
+    stackSize = font->isCFF2 ? cf2_getMaxstack( decoder )
+                             : CF2_OPERAND_STACK_SIZE;
+    opStack   = cf2_stack_init( memory, error, stackSize );
+
     if ( !opStack )
     {
       lastError = FT_THROW( Out_Of_Memory );
@@ -561,14 +607,23 @@
       {
         /* If we've reached the end of the charstring, simulate a */
         /* cf2_cmdRETURN or cf2_cmdENDCHAR.                       */
+        /* We do this for both CFF and CFF2.                      */
         if ( charstringIndex )
           op1 = cf2_cmdRETURN;  /* end of buffer for subroutine */
         else
           op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */
       }
       else
+      {
         op1 = (FT_Byte)cf2_buf_readByte( charstring );
 
+        /* Explicit RETURN and ENDCHAR in CFF2 should be ignored. */
+        /* Note: Trace message will report 0 instead of 11 or 14. */
+        if ( ( op1 == cf2_cmdRETURN || op1 == cf2_cmdENDCHAR ) &&
+             font->isCFF2                                      )
+          op1 = cf2_cmdRESERVED_0;
+      }
+
       /* check for errors once per loop */
       if ( *error )
         goto exit;
@@ -586,13 +641,78 @@
       case cf2_cmdRESERVED_2:
       case cf2_cmdRESERVED_9:
       case cf2_cmdRESERVED_13:
-      case cf2_cmdRESERVED_15:
-      case cf2_cmdRESERVED_16:
       case cf2_cmdRESERVED_17:
         /* we may get here if we have a prior error */
         FT_TRACE4(( " unknown op (%d)\n", op1 ));
         break;
 
+      case cf2_cmdVSINDEX:
+        FT_TRACE4(( " vsindex\n" ));
+
+        if ( !font->isCFF2 )
+          break;    /* clear stack & ignore */
+
+        if ( font->blend.usedBV )
+        {
+          /* vsindex not allowed after blend */
+          lastError = FT_THROW( Invalid_Glyph_Format );
+          goto exit;
+        }
+
+        {
+          FT_Int  temp = cf2_stack_popInt( opStack );
+
+
+          if ( temp >= 0 )
+            font->vsindex = (FT_UInt)temp;
+        }
+        break;
+
+      case cf2_cmdBLEND:
+        {
+          FT_UInt  numBlends;
+
+
+          FT_TRACE4(( " blend\n" ));
+
+          if ( !font->isCFF2 )
+            break;    /* clear stack & ignore */
+
+          /* do we have a `blend' op in a non-variant font? */
+          if ( !font->blend.font )
+          {
+            lastError = FT_THROW( Invalid_Glyph_Format );
+            goto exit;
+          }
+
+          /* check cached blend vector */
+          if ( cff_blend_check_vector( &font->blend,
+                                       font->vsindex,
+                                       font->lenNDV,
+                                       font->NDV ) )
+          {
+            lastError = cff_blend_build_vector( &font->blend,
+                                                font->vsindex,
+                                                font->lenNDV,
+                                                font->NDV );
+            if ( lastError )
+              goto exit;
+          }
+
+          /* do the blend */
+          numBlends = (FT_UInt)cf2_stack_popInt( opStack );
+          if ( numBlends > stackSize )
+          {
+            lastError = FT_THROW( Invalid_Glyph_Format );
+            goto exit;
+          }
+
+          cf2_doBlend( &font->blend, opStack, numBlends );
+
+          font->blend.usedBV = TRUE;
+        }
+        continue;     /* do not clear the stack */
+
       case cf2_cmdHSTEMHM:
       case cf2_cmdHSTEM:
         FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" ));
@@ -685,7 +805,7 @@
           CF2_UInt  index;
           CF2_UInt  count = cf2_stack_count( opStack );
 
-          FT_Bool  isX = op1 == cf2_cmdHLINETO;
+          FT_Bool  isX = FT_BOOL( op1 == cf2_cmdHLINETO );
 
 
           FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" ));
@@ -830,325 +950,10 @@
           FT_Byte  op2 = (FT_Byte)cf2_buf_readByte( charstring );
 
 
+          /* first switch for 2-byte operators handles CFF2      */
+          /* and opcodes that are reserved for both CFF and CFF2 */
           switch ( op2 )
           {
-          case cf2_escDOTSECTION:
-            /* something about `flip type of locking' -- ignore it */
-            FT_TRACE4(( " dotsection\n" ));
-
-            break;
-
-          case cf2_escAND:
-            {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
-
-
-              FT_TRACE4(( " and\n" ));
-
-              arg2 = cf2_stack_popFixed( opStack );
-              arg1 = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushInt( opStack, arg1 && arg2 );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escOR:
-            {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
-
-
-              FT_TRACE4(( " or\n" ));
-
-              arg2 = cf2_stack_popFixed( opStack );
-              arg1 = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushInt( opStack, arg1 || arg2 );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escNOT:
-            {
-              CF2_F16Dot16  arg;
-
-
-              FT_TRACE4(( " not\n" ));
-
-              arg = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushInt( opStack, !arg );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escABS:
-            {
-              CF2_F16Dot16  arg;
-
-
-              FT_TRACE4(( " abs\n" ));
-
-              arg = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escADD:
-            {
-              CF2_F16Dot16  summand1;
-              CF2_F16Dot16  summand2;
-
-
-              FT_TRACE4(( " add\n" ));
-
-              summand2 = cf2_stack_popFixed( opStack );
-              summand1 = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushFixed( opStack, summand1 + summand2 );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escSUB:
-            {
-              CF2_F16Dot16  minuend;
-              CF2_F16Dot16  subtrahend;
-
-
-              FT_TRACE4(( " sub\n" ));
-
-              subtrahend = cf2_stack_popFixed( opStack );
-              minuend    = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushFixed( opStack, minuend - subtrahend );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escDIV:
-            {
-              CF2_F16Dot16  dividend;
-              CF2_F16Dot16  divisor;
-
-
-              FT_TRACE4(( " div\n" ));
-
-              divisor  = cf2_stack_popFixed( opStack );
-              dividend = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escNEG:
-            {
-              CF2_F16Dot16  arg;
-
-
-              FT_TRACE4(( " neg\n" ));
-
-              arg = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushFixed( opStack, -arg );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escEQ:
-            {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
-
-
-              FT_TRACE4(( " eq\n" ));
-
-              arg2 = cf2_stack_popFixed( opStack );
-              arg1 = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushInt( opStack, arg1 == arg2 );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escDROP:
-            FT_TRACE4(( " drop\n" ));
-
-            (void)cf2_stack_popFixed( opStack );
-            continue; /* do not clear the stack */
-
-          case cf2_escPUT:
-            {
-              CF2_F16Dot16  val;
-              CF2_Int       idx;
-
-
-              FT_TRACE4(( " put\n" ));
-
-              idx = cf2_stack_popInt( opStack );
-              val = cf2_stack_popFixed( opStack );
-
-              if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
-                storage[idx] = val;
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escGET:
-            {
-              CF2_Int  idx;
-
-
-              FT_TRACE4(( " get\n" ));
-
-              idx = cf2_stack_popInt( opStack );
-
-              if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
-                cf2_stack_pushFixed( opStack, storage[idx] );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escIFELSE:
-            {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
-              CF2_F16Dot16  cond1;
-              CF2_F16Dot16  cond2;
-
-
-              FT_TRACE4(( " ifelse\n" ));
-
-              cond2 = cf2_stack_popFixed( opStack );
-              cond1 = cf2_stack_popFixed( opStack );
-              arg2  = cf2_stack_popFixed( opStack );
-              arg1  = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escRANDOM: /* in spec */
-            FT_TRACE4(( " random\n" ));
-
-            CF2_FIXME;
-            break;
-
-          case cf2_escMUL:
-            {
-              CF2_F16Dot16  factor1;
-              CF2_F16Dot16  factor2;
-
-
-              FT_TRACE4(( " mul\n" ));
-
-              factor2 = cf2_stack_popFixed( opStack );
-              factor1 = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escSQRT:
-            {
-              CF2_F16Dot16  arg;
-
-
-              FT_TRACE4(( " sqrt\n" ));
-
-              arg = cf2_stack_popFixed( opStack );
-              if ( arg > 0 )
-              {
-                FT_Fixed  root = arg;
-                FT_Fixed  new_root;
-
-
-                /* Babylonian method */
-                for (;;)
-                {
-                  new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1;
-                  if ( new_root == root )
-                    break;
-                  root = new_root;
-                }
-                arg = new_root;
-              }
-              else
-                arg = 0;
-
-              cf2_stack_pushFixed( opStack, arg );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escDUP:
-            {
-              CF2_F16Dot16  arg;
-
-
-              FT_TRACE4(( " dup\n" ));
-
-              arg = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushFixed( opStack, arg );
-              cf2_stack_pushFixed( opStack, arg );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escEXCH:
-            {
-              CF2_F16Dot16  arg1;
-              CF2_F16Dot16  arg2;
-
-
-              FT_TRACE4(( " exch\n" ));
-
-              arg2 = cf2_stack_popFixed( opStack );
-              arg1 = cf2_stack_popFixed( opStack );
-
-              cf2_stack_pushFixed( opStack, arg2 );
-              cf2_stack_pushFixed( opStack, arg1 );
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escINDEX:
-            {
-              CF2_Int   idx;
-              CF2_UInt  size;
-
-
-              FT_TRACE4(( " index\n" ));
-
-              idx  = cf2_stack_popInt( opStack );
-              size = cf2_stack_count( opStack );
-
-              if ( size > 0 )
-              {
-                /* for `cf2_stack_getReal', index 0 is bottom of stack */
-                CF2_UInt  gr_idx;
-
-
-                if ( idx < 0 )
-                  gr_idx = size - 1;
-                else if ( (CF2_UInt)idx >= size )
-                  gr_idx = 0;
-                else
-                  gr_idx = size - 1 - (CF2_UInt)idx;
-
-                cf2_stack_pushFixed( opStack,
-                                     cf2_stack_getReal( opStack, gr_idx ) );
-              }
-            }
-            continue; /* do not clear the stack */
-
-          case cf2_escROLL:
-            {
-              CF2_Int  idx;
-              CF2_Int  count;
-
-
-              FT_TRACE4(( " roll\n" ));
-
-              idx   = cf2_stack_popInt( opStack );
-              count = cf2_stack_popInt( opStack );
-
-              cf2_stack_roll( opStack, count, idx );
-            }
-            continue; /* do not clear the stack */
-
           case cf2_escHFLEX:
             {
               static const FT_Bool  readFromStack[12] =
@@ -1245,6 +1050,7 @@
             }
             continue;
 
+          /* these opcodes are reserved in both CFF & CFF2 */
           case cf2_escRESERVED_1:
           case cf2_escRESERVED_2:
           case cf2_escRESERVED_6:
@@ -1258,12 +1064,342 @@
           case cf2_escRESERVED_31:
           case cf2_escRESERVED_32:
           case cf2_escRESERVED_33:
-          default:
             FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
+            break;
 
-          }; /* end of switch statement checking `op2' */
+          default:
+            {
+              if ( font->isCFF2 || op2 >= cf2_escRESERVED_38 )
+                FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
+              else
+              {
+                /* second switch for 2-byte operators handles just CFF */
+                switch ( op2 )
+                {
 
+                case cf2_escDOTSECTION:
+                  /* something about `flip type of locking' -- ignore it */
+                  FT_TRACE4(( " dotsection\n" ));
+
+                  break;
+
+                case cf2_escAND:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
+
+
+                    FT_TRACE4(( " and\n" ));
+
+                    arg2 = cf2_stack_popFixed( opStack );
+                    arg1 = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushInt( opStack, arg1 && arg2 );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escOR:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
+
+
+                    FT_TRACE4(( " or\n" ));
+
+                    arg2 = cf2_stack_popFixed( opStack );
+                    arg1 = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushInt( opStack, arg1 || arg2 );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escNOT:
+                  {
+                    CF2_F16Dot16  arg;
+
+
+                    FT_TRACE4(( " not\n" ));
+
+                    arg = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushInt( opStack, !arg );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escABS:
+                  {
+                    CF2_F16Dot16  arg;
+
+
+                    FT_TRACE4(( " abs\n" ));
+
+                    arg = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escADD:
+                  {
+                    CF2_F16Dot16  summand1;
+                    CF2_F16Dot16  summand2;
+
+
+                    FT_TRACE4(( " add\n" ));
+
+                    summand2 = cf2_stack_popFixed( opStack );
+                    summand1 = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushFixed( opStack, summand1 + summand2 );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escSUB:
+                  {
+                    CF2_F16Dot16  minuend;
+                    CF2_F16Dot16  subtrahend;
+
+
+                    FT_TRACE4(( " sub\n" ));
+
+                    subtrahend = cf2_stack_popFixed( opStack );
+                    minuend    = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushFixed( opStack, minuend - subtrahend );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escDIV:
+                  {
+                    CF2_F16Dot16  dividend;
+                    CF2_F16Dot16  divisor;
+
+
+                    FT_TRACE4(( " div\n" ));
+
+                    divisor  = cf2_stack_popFixed( opStack );
+                    dividend = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushFixed( opStack, FT_DivFix( dividend, divisor ) );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escNEG:
+                  {
+                    CF2_F16Dot16  arg;
+
+
+                    FT_TRACE4(( " neg\n" ));
+
+                    arg = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushFixed( opStack, -arg );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escEQ:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
+
+
+                    FT_TRACE4(( " eq\n" ));
+
+                    arg2 = cf2_stack_popFixed( opStack );
+                    arg1 = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushInt( opStack, arg1 == arg2 );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escDROP:
+                  FT_TRACE4(( " drop\n" ));
+
+                  (void)cf2_stack_popFixed( opStack );
+                  continue; /* do not clear the stack */
+
+                case cf2_escPUT:
+                  {
+                    CF2_F16Dot16  val;
+                    CF2_Int       idx;
+
+
+                    FT_TRACE4(( " put\n" ));
+
+                    idx = cf2_stack_popInt( opStack );
+                    val = cf2_stack_popFixed( opStack );
+
+                    if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
+                      storage[idx] = val;
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escGET:
+                  {
+                    CF2_Int  idx;
+
+
+                    FT_TRACE4(( " get\n" ));
+
+                    idx = cf2_stack_popInt( opStack );
+
+                    if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
+                      cf2_stack_pushFixed( opStack, storage[idx] );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escIFELSE:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
+                    CF2_F16Dot16  cond1;
+                    CF2_F16Dot16  cond2;
+
+
+                    FT_TRACE4(( " ifelse\n" ));
+
+                    cond2 = cf2_stack_popFixed( opStack );
+                    cond1 = cf2_stack_popFixed( opStack );
+                    arg2  = cf2_stack_popFixed( opStack );
+                    arg1  = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushFixed( opStack, cond1 <= cond2 ? arg1 : arg2 );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escRANDOM: /* in spec */
+                  FT_TRACE4(( " random\n" ));
+
+                  CF2_FIXME;
+                  break;
+
+                case cf2_escMUL:
+                  {
+                    CF2_F16Dot16  factor1;
+                    CF2_F16Dot16  factor2;
+
+
+                    FT_TRACE4(( " mul\n" ));
+
+                    factor2 = cf2_stack_popFixed( opStack );
+                    factor1 = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushFixed( opStack, FT_MulFix( factor1, factor2 ) );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escSQRT:
+                  {
+                    CF2_F16Dot16  arg;
+
+
+                    FT_TRACE4(( " sqrt\n" ));
+
+                    arg = cf2_stack_popFixed( opStack );
+                    if ( arg > 0 )
+                    {
+                      FT_Fixed  root = arg;
+                      FT_Fixed  new_root;
+
+
+                      /* Babylonian method */
+                      for (;;)
+                      {
+                        new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1;
+                        if ( new_root == root )
+                          break;
+                        root = new_root;
+                      }
+                      arg = new_root;
+                    }
+                    else
+                      arg = 0;
+
+                    cf2_stack_pushFixed( opStack, arg );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escDUP:
+                  {
+                    CF2_F16Dot16  arg;
+
+
+                    FT_TRACE4(( " dup\n" ));
+
+                    arg = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushFixed( opStack, arg );
+                    cf2_stack_pushFixed( opStack, arg );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escEXCH:
+                  {
+                    CF2_F16Dot16  arg1;
+                    CF2_F16Dot16  arg2;
+
+
+                    FT_TRACE4(( " exch\n" ));
+
+                    arg2 = cf2_stack_popFixed( opStack );
+                    arg1 = cf2_stack_popFixed( opStack );
+
+                    cf2_stack_pushFixed( opStack, arg2 );
+                    cf2_stack_pushFixed( opStack, arg1 );
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escINDEX:
+                  {
+                    CF2_Int   idx;
+                    CF2_UInt  size;
+
+
+                    FT_TRACE4(( " index\n" ));
+
+                    idx  = cf2_stack_popInt( opStack );
+                    size = cf2_stack_count( opStack );
+
+                    if ( size > 0 )
+                    {
+                      /* for `cf2_stack_getReal', index 0 is bottom of stack */
+                      CF2_UInt  gr_idx;
+
+
+                      if ( idx < 0 )
+                        gr_idx = size - 1;
+                      else if ( (CF2_UInt)idx >= size )
+                        gr_idx = 0;
+                      else
+                        gr_idx = size - 1 - (CF2_UInt)idx;
+
+                      cf2_stack_pushFixed( opStack,
+                                           cf2_stack_getReal( opStack, gr_idx ) );
+                    }
+                  }
+                  continue; /* do not clear the stack */
+
+                case cf2_escROLL:
+                  {
+                    CF2_Int  idx;
+                    CF2_Int  count;
+
+
+                    FT_TRACE4(( " roll\n" ));
+
+                    idx   = cf2_stack_popInt( opStack );
+                    count = cf2_stack_popInt( opStack );
+
+                    cf2_stack_roll( opStack, count, idx );
+                  }
+                  continue; /* do not clear the stack */
+
+                } /* end of 2nd switch checking op2 */
+              }
+            }
+          } /* end of 1st switch checking op2 */
         } /* case cf2_cmdESC */
+
         break;
 
       case cf2_cmdENDCHAR:
@@ -1285,7 +1421,8 @@
         /* close path if still open */
         cf2_glyphpath_closeOpenPath( &glyphPath );
 
-        if ( cf2_stack_count( opStack ) > 1 )
+        /* disable seac for CFF2 (charstring ending with args on stack) */
+        if ( !font->isCFF2 && cf2_stack_count( opStack ) > 1 )
         {
           /* must be either 4 or 5 --                       */
           /* this is a (deprecated) implied `seac' operator */
@@ -1514,7 +1651,7 @@
             {
               x1 = cf2_stack_getReal( opStack, index ) + curX;
 
-              ++index;
+              index++;
             }
             else
               x1 = curX;
@@ -1559,7 +1696,7 @@
             {
               y1 = cf2_stack_getReal( opStack, index ) + curY;
 
-              ++index;
+              index++;
             }
             else
               y1 = curY;
@@ -1587,7 +1724,7 @@
           CF2_UInt  count, count1 = cf2_stack_count( opStack );
           CF2_UInt  index = 0;
 
-          FT_Bool  alternate = op1 == cf2_cmdHVCURVETO;
+          FT_Bool  alternate = FT_BOOL( op1 == cf2_cmdHVCURVETO );
 
 
           /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */
@@ -1616,7 +1753,7 @@
               {
                 x3 = cf2_stack_getReal( opStack, index + 4 ) + x2;
 
-                ++index;
+                index++;
               }
               else
                 x3 = x2;
@@ -1635,7 +1772,7 @@
               {
                 y3 = cf2_stack_getReal( opStack, index + 4 ) + y2;
 
-                ++index;
+                index++;
               }
               else
                 y3 = y2;
@@ -1736,7 +1873,7 @@
                              ( byte3 <<  8 ) |
                                byte4         );
 
-            FT_TRACE4(( " %.2f", v / 65536.0 ));
+            FT_TRACE4(( " %.5f", v / 65536.0 ));
 
             cf2_stack_pushFixed( opStack, v );
           }
@@ -1757,6 +1894,9 @@
     /* check whether last error seen is also the first one */
     cf2_setError( error, lastError );
 
+    if ( *error )
+      FT_TRACE4(( "charstring error %d\n", *error ));
+
     /* free resources from objects we've used */
     cf2_glyphpath_finalize( &glyphPath );
     cf2_arrstack_finalize( &vStemHintArray );
diff --git a/src/cff/cf2stack.c b/src/cff/cf2stack.c
index 8f3adb6..12a026d 100644
--- a/src/cff/cf2stack.c
+++ b/src/cff/cf2stack.c
@@ -51,7 +51,8 @@
   /* `error').                                               */
   FT_LOCAL_DEF( CF2_Stack )
   cf2_stack_init( FT_Memory  memory,
-                  FT_Error*  e )
+                  FT_Error*  e,
+                  FT_UInt    stackSize )
   {
     FT_Error  error = FT_Err_Ok;     /* for FT_NEW */
 
@@ -63,9 +64,18 @@
       /* initialize the structure; FT_NEW zeroes it */
       stack->memory = memory;
       stack->error  = e;
-      stack->top    = &stack->buffer[0]; /* empty stack */
     }
 
+    /* allocate the stack buffer */
+    if ( FT_NEW_ARRAY( stack->buffer, stackSize ) )
+    {
+      FT_FREE( stack );
+      return NULL;
+    }
+
+    stack->stackSize = stackSize;
+    stack->top       = stack->buffer;     /* empty stack */
+
     return stack;
   }
 
@@ -77,6 +87,8 @@
     {
       FT_Memory  memory = stack->memory;
 
+      /* free the buffer */
+      FT_FREE( stack->buffer );
 
       /* free the main structure */
       FT_FREE( stack );
@@ -87,7 +99,7 @@
   FT_LOCAL_DEF( CF2_UInt )
   cf2_stack_count( CF2_Stack  stack )
   {
-    return (CF2_UInt)( stack->top - &stack->buffer[0] );
+    return (CF2_UInt)( stack->top - stack->buffer );
   }
 
 
@@ -95,7 +107,7 @@
   cf2_stack_pushInt( CF2_Stack  stack,
                      CF2_Int    val )
   {
-    if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
+    if ( stack->top == stack->buffer + stack->stackSize )
     {
       CF2_SET_ERROR( stack->error, Stack_Overflow );
       return;     /* stack overflow */
@@ -103,7 +115,7 @@
 
     stack->top->u.i  = val;
     stack->top->type = CF2_NumberInt;
-    ++stack->top;
+    stack->top++;
   }
 
 
@@ -111,7 +123,7 @@
   cf2_stack_pushFixed( CF2_Stack  stack,
                        CF2_Fixed  val )
   {
-    if ( stack->top == &stack->buffer[CF2_OPERAND_STACK_SIZE] )
+    if ( stack->top == stack->buffer + stack->stackSize )
     {
       CF2_SET_ERROR( stack->error, Stack_Overflow );
       return;     /* stack overflow */
@@ -119,7 +131,7 @@
 
     stack->top->u.r  = val;
     stack->top->type = CF2_NumberFixed;
-    ++stack->top;
+    stack->top++;
   }
 
 
@@ -127,7 +139,7 @@
   FT_LOCAL_DEF( CF2_Int )
   cf2_stack_popInt( CF2_Stack  stack )
   {
-    if ( stack->top == &stack->buffer[0] )
+    if ( stack->top == stack->buffer )
     {
       CF2_SET_ERROR( stack->error, Stack_Underflow );
       return 0;   /* underflow */
@@ -138,7 +150,7 @@
       return 0;   /* type mismatch */
     }
 
-    --stack->top;
+    stack->top--;
 
     return stack->top->u.i;
   }
@@ -149,13 +161,13 @@
   FT_LOCAL_DEF( CF2_Fixed )
   cf2_stack_popFixed( CF2_Stack  stack )
   {
-    if ( stack->top == &stack->buffer[0] )
+    if ( stack->top == stack->buffer )
     {
       CF2_SET_ERROR( stack->error, Stack_Underflow );
       return cf2_intToFixed( 0 );    /* underflow */
     }
 
-    --stack->top;
+    stack->top--;
 
     switch ( stack->top->type )
     {
@@ -175,7 +187,7 @@
   cf2_stack_getReal( CF2_Stack  stack,
                      CF2_UInt   idx )
   {
-    FT_ASSERT( cf2_stack_count( stack ) <= CF2_OPERAND_STACK_SIZE );
+    FT_ASSERT( cf2_stack_count( stack ) <= stack->stackSize );
 
     if ( idx >= cf2_stack_count( stack ) )
     {
@@ -195,7 +207,38 @@
   }
 
 
-  FT_LOCAL( void )
+  /* provide random access to stack */
+  FT_LOCAL_DEF( void )
+  cf2_stack_setReal( CF2_Stack  stack,
+                     CF2_UInt   idx,
+                     CF2_Fixed  val )
+  {
+    if ( idx > cf2_stack_count( stack ) )
+    {
+      CF2_SET_ERROR( stack->error, Stack_Overflow );
+      return;
+    }
+
+    stack->buffer[idx].u.r  = val;
+    stack->buffer[idx].type = CF2_NumberFixed;
+  }
+
+
+  /* discard (pop) num values from stack */
+  FT_LOCAL_DEF( void )
+  cf2_stack_pop( CF2_Stack  stack,
+                 CF2_UInt   num )
+  {
+    if ( num > cf2_stack_count( stack ) )
+    {
+      CF2_SET_ERROR( stack->error, Stack_Underflow );
+      return;
+    }
+    stack->top -= num;
+  }
+
+
+  FT_LOCAL_DEF( void )
   cf2_stack_roll( CF2_Stack  stack,
                   CF2_Int    count,
                   CF2_Int    shift )
@@ -278,7 +321,7 @@
   FT_LOCAL_DEF( void )
   cf2_stack_clear( CF2_Stack  stack )
   {
-    stack->top = &stack->buffer[0];
+    stack->top = stack->buffer;
   }
 
 
diff --git a/src/cff/cf2stack.h b/src/cff/cf2stack.h
index e740a7a..ef08eef 100644
--- a/src/cff/cf2stack.h
+++ b/src/cff/cf2stack.h
@@ -62,15 +62,17 @@
   {
     FT_Memory         memory;
     FT_Error*         error;
-    CF2_StackNumber   buffer[CF2_OPERAND_STACK_SIZE];
+    CF2_StackNumber*  buffer;
     CF2_StackNumber*  top;
+    FT_UInt           stackSize;
 
   } CF2_StackRec, *CF2_Stack;
 
 
   FT_LOCAL( CF2_Stack )
   cf2_stack_init( FT_Memory  memory,
-                  FT_Error*  error );
+                  FT_Error*  error,
+                  FT_UInt    stackSize );
   FT_LOCAL( void )
   cf2_stack_free( CF2_Stack  stack );
 
@@ -92,6 +94,14 @@
   FT_LOCAL( CF2_Fixed )
   cf2_stack_getReal( CF2_Stack  stack,
                      CF2_UInt   idx );
+  FT_LOCAL( void )
+  cf2_stack_setReal( CF2_Stack  stack,
+                     CF2_UInt   idx,
+                     CF2_Fixed  val );
+
+  FT_LOCAL( void )
+  cf2_stack_pop( CF2_Stack  stack,
+                 CF2_UInt   num );
 
   FT_LOCAL( void )
   cf2_stack_roll( CF2_Stack  stack,
diff --git a/src/cff/cff.c b/src/cff/cff.c
index 86ca1be..545fb20 100644
--- a/src/cff/cff.c
+++ b/src/cff/cff.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType OpenType driver component (body only).                      */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffcmap.c b/src/cff/cffcmap.c
index 3ef4832..4adce7a 100644
--- a/src/cff/cffcmap.c
+++ b/src/cff/cffcmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF character mapping table (cmap) support (body).                   */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -104,15 +104,21 @@
   }
 
 
-  FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec,
+  FT_DEFINE_CMAP_CLASS(
+    cff_cmap_encoding_class_rec,
+
     sizeof ( CFF_CMapStdRec ),
 
-    (FT_CMap_InitFunc)     cff_cmap_encoding_init,
-    (FT_CMap_DoneFunc)     cff_cmap_encoding_done,
-    (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index,
-    (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next,
+    (FT_CMap_InitFunc)     cff_cmap_encoding_init,        /* init       */
+    (FT_CMap_DoneFunc)     cff_cmap_encoding_done,        /* done       */
+    (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index,  /* char_index */
+    (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next,   /* char_next  */
 
-    NULL, NULL, NULL, NULL, NULL
+    (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+    (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+    (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+    (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+    (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
   )
 
 
@@ -202,15 +208,22 @@
   }
 
 
-  FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec,
+  FT_DEFINE_CMAP_CLASS(
+    cff_cmap_unicode_class_rec,
+
     sizeof ( PS_UnicodesRec ),
 
-    (FT_CMap_InitFunc)     cff_cmap_unicode_init,
-    (FT_CMap_DoneFunc)     cff_cmap_unicode_done,
-    (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index,
-    (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next,
+    (FT_CMap_InitFunc)     cff_cmap_unicode_init,        /* init       */
+    (FT_CMap_DoneFunc)     cff_cmap_unicode_done,        /* done       */
+    (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index,  /* char_index */
+    (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next,   /* char_next  */
 
-    NULL, NULL, NULL, NULL, NULL
+    (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+    (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+    (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+    (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+    (FT_CMap_VariantCharListFunc) NULL   /* variantchar_list */
   )
 
+
 /* END */
diff --git a/src/cff/cffcmap.h b/src/cff/cffcmap.h
index 23795d5..7792e04 100644
--- a/src/cff/cffcmap.h
+++ b/src/cff/cffcmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF character mapping table (cmap) support (specification).          */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 67bf09d..cbafd7e 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType font driver implementation (body).                          */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -32,6 +32,11 @@
 #include "cffcmap.h"
 #include "cffparse.h"
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#include FT_SERVICE_MULTIPLE_MASTERS_H
+#include FT_SERVICE_METRICS_VARIATIONS_H
+#endif
+
 #include "cfferrs.h"
 #include "cffpic.h"
 
@@ -207,6 +212,13 @@
 
       if ( flags & FT_LOAD_VERTICAL_LAYOUT )
       {
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+        /* no fast retrieval for blended MM fonts without VVAR table */
+        if ( !ttface->is_default_instance                               &&
+             !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+          return FT_THROW( Unimplemented_Feature );
+#endif
+
         /* check whether we have data from the `vmtx' table at all; */
         /* otherwise we extract the info from the CFF glyphstrings  */
         /* (instead of synthesizing a global value using the `OS/2' */
@@ -232,6 +244,13 @@
       }
       else
       {
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+        /* no fast retrieval for blended MM fonts without HVAR table */
+        if ( !ttface->is_default_instance                               &&
+             !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
+          return FT_THROW( Unimplemented_Feature );
+#endif
+
         /* check whether we have data from the `hmtx' table at all */
         if ( !ttface->horizontal.number_Of_HMetrics )
           goto Missing_Table;
@@ -291,6 +310,35 @@
     FT_Error    error;
 
 
+    /* CFF2 table does not have glyph names; */
+    /* we need to use `post' table method    */
+    if ( font->version_major == 2 )
+    {
+      FT_Library            library     = FT_FACE_LIBRARY( face );
+      FT_Module             sfnt_module = FT_Get_Module( library, "sfnt" );
+      FT_Service_GlyphDict  service     =
+        (FT_Service_GlyphDict)ft_module_get_service(
+                                 sfnt_module,
+                                 FT_SERVICE_ID_GLYPH_DICT,
+                                 0 );
+
+
+      if ( service && service->get_name )
+        return service->get_name( FT_FACE( face ),
+                                  glyph_index,
+                                  buffer,
+                                  buffer_max );
+      else
+      {
+        FT_ERROR(( "cff_get_glyph_name:"
+                   " cannot get glyph name from a CFF2 font\n"
+                   "                   "
+                   " without the `PSNames' module\n" ));
+        error = FT_THROW( Missing_Module );
+        goto Exit;
+      }
+    }
+
     if ( !font->psnames )
     {
       FT_ERROR(( "cff_get_glyph_name:"
@@ -332,6 +380,31 @@
     cff     = (CFF_FontRec *)face->extra.data;
     charset = &cff->charset;
 
+    /* CFF2 table does not have glyph names; */
+    /* we need to use `post' table method    */
+    if ( cff->version_major == 2 )
+    {
+      FT_Library            library     = FT_FACE_LIBRARY( face );
+      FT_Module             sfnt_module = FT_Get_Module( library, "sfnt" );
+      FT_Service_GlyphDict  service     =
+        (FT_Service_GlyphDict)ft_module_get_service(
+                                 sfnt_module,
+                                 FT_SERVICE_ID_GLYPH_DICT,
+                                 0 );
+
+
+      if ( service && service->name_index )
+        return service->name_index( FT_FACE( face ), glyph_name );
+      else
+      {
+        FT_ERROR(( "cff_get_name_index:"
+                   " cannot get glyph index from a CFF2 font\n"
+                   "                   "
+                   " without the `PSNames' module\n" ));
+        return 0;
+      }
+    }
+
     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
     if ( !psnames )
       return 0;
@@ -358,6 +431,7 @@
 
   FT_DEFINE_SERVICE_GLYPHDICTREC(
     cff_service_glyph_dict,
+
     (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,      /* get_name   */
     (FT_GlyphDict_NameIndexFunc)cff_get_name_index       /* name_index */
   )
@@ -383,11 +457,11 @@
     FT_Error  error = FT_Err_Ok;
 
 
-    if ( cff && cff->font_info == NULL )
+    if ( cff && !cff->font_info )
     {
-      CFF_FontRecDict  dict   = &cff->top_font.font_dict;
+      CFF_FontRecDict  dict      = &cff->top_font.font_dict;
       PS_FontInfoRec  *font_info = NULL;
-      FT_Memory        memory = face->root.memory;
+      FT_Memory        memory    = face->root.memory;
 
 
       if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
@@ -421,6 +495,7 @@
 
   FT_DEFINE_SERVICE_PSINFOREC(
     cff_service_ps_info,
+
     (PS_GetFontInfoFunc)   cff_ps_get_font_info,    /* ps_get_font_info    */
     (PS_GetFontExtraFunc)  NULL,                    /* ps_get_font_extra   */
     (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,  /* ps_has_glyph_names  */
@@ -453,7 +528,8 @@
       FT_Service_PsFontName  service     =
         (FT_Service_PsFontName)ft_module_get_service(
                                  sfnt_module,
-                                 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME );
+                                 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME,
+                                 0 );
 
 
       if ( service && service->get_ps_font_name )
@@ -466,6 +542,7 @@
 
   FT_DEFINE_SERVICE_PSFONTNAMEREC(
     cff_service_ps_name,
+
     (FT_PsName_GetFunc)cff_get_ps_name      /* get_ps_font_name */
   )
 
@@ -491,21 +568,21 @@
     FT_Library  library = FT_FACE_LIBRARY( face );
 
 
-    cmap_info->language = 0;
-    cmap_info->format   = 0;
-
     if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET &&
          cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET  )
     {
       FT_Module           sfnt    = FT_Get_Module( library, "sfnt" );
       FT_Service_TTCMaps  service =
         (FT_Service_TTCMaps)ft_module_get_service( sfnt,
-                                                   FT_SERVICE_ID_TT_CMAP );
+                                                   FT_SERVICE_ID_TT_CMAP,
+                                                   0 );
 
 
       if ( service && service->get_cmap_info )
         error = service->get_cmap_info( charmap, cmap_info );
     }
+    else
+      error = FT_THROW( Invalid_CharMap_Format );
 
     return error;
   }
@@ -513,6 +590,7 @@
 
   FT_DEFINE_SERVICE_TTCMAPSREC(
     cff_service_get_cmap_info,
+
     (TT_CMap_Info_GetFunc)cff_get_cmap_info    /* get_cmap_info */
   )
 
@@ -544,7 +622,7 @@
 
       if ( registry )
       {
-        if ( cff->registry == NULL )
+        if ( !cff->registry )
           cff->registry = cff_index_get_sid_string( cff,
                                                     dict->cid_registry );
         *registry = cff->registry;
@@ -552,7 +630,7 @@
 
       if ( ordering )
       {
-        if ( cff->ordering == NULL )
+        if ( !cff->ordering )
           cff->ordering = cff_index_get_sid_string( cff,
                                                     dict->cid_ordering );
         *ordering = cff->ordering;
@@ -643,6 +721,7 @@
 
   FT_DEFINE_SERVICE_CIDREC(
     cff_service_cid_info,
+
     (FT_CID_GetRegistryOrderingSupplementFunc)
       cff_get_ros,                             /* get_ros                  */
     (FT_CID_GetIsInternallyCIDKeyedFunc)
@@ -855,10 +934,137 @@
 
   FT_DEFINE_SERVICE_PROPERTIESREC(
     cff_service_properties,
+
     (FT_Properties_SetFunc)cff_property_set,      /* set_property */
     (FT_Properties_GetFunc)cff_property_get )     /* get_property */
 
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+  /*
+   *  MULTIPLE MASTER SERVICE
+   *
+   */
+
+  static FT_Error
+  cff_set_mm_blend( CFF_Face   face,
+                    FT_UInt    num_coords,
+                    FT_Fixed*  coords )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->set_mm_blend( FT_FACE( face ), num_coords, coords );
+  }
+
+
+  static FT_Error
+  cff_get_mm_blend( CFF_Face   face,
+                    FT_UInt    num_coords,
+                    FT_Fixed*  coords )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->get_mm_blend( FT_FACE( face ), num_coords, coords );
+  }
+
+
+  static FT_Error
+  cff_get_mm_var( CFF_Face     face,
+                  FT_MM_Var*  *master )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->get_mm_var( FT_FACE( face ), master );
+  }
+
+
+  static FT_Error
+  cff_set_var_design( CFF_Face   face,
+                      FT_UInt    num_coords,
+                      FT_Fixed*  coords )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->set_var_design( FT_FACE( face ), num_coords, coords );
+  }
+
+
+  static FT_Error
+  cff_get_var_design( CFF_Face   face,
+                      FT_UInt    num_coords,
+                      FT_Fixed*  coords )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->get_var_design( FT_FACE( face ), num_coords, coords );
+  }
+
+
+  FT_DEFINE_SERVICE_MULTIMASTERSREC(
+    cff_service_multi_masters,
+
+    (FT_Get_MM_Func)        NULL,                   /* get_mm         */
+    (FT_Set_MM_Design_Func) NULL,                   /* set_mm_design  */
+    (FT_Set_MM_Blend_Func)  cff_set_mm_blend,       /* set_mm_blend   */
+    (FT_Get_MM_Blend_Func)  cff_get_mm_blend,       /* get_mm_blend   */
+    (FT_Get_MM_Var_Func)    cff_get_mm_var,         /* get_mm_var     */
+    (FT_Set_Var_Design_Func)cff_set_var_design,     /* set_var_design */
+    (FT_Get_Var_Design_Func)cff_get_var_design,     /* get_var_design */
+
+    (FT_Get_Var_Blend_Func) cff_get_var_blend,      /* get_var_blend  */
+    (FT_Done_Blend_Func)    cff_done_blend          /* done_blend     */
+  )
+
+
+  /*
+   *  METRICS VARIATIONS SERVICE
+   *
+   */
+
+  static FT_Error
+  cff_hadvance_adjust( CFF_Face  face,
+                       FT_UInt   gindex,
+                       FT_Int   *avalue )
+  {
+    FT_Service_MetricsVariations  var = (FT_Service_MetricsVariations)face->var;
+
+
+    return var->hadvance_adjust( FT_FACE( face ), gindex, avalue );
+  }
+
+
+  static void
+  cff_metrics_adjust( CFF_Face  face )
+  {
+    FT_Service_MetricsVariations  var = (FT_Service_MetricsVariations)face->var;
+
+
+    var->metrics_adjust( FT_FACE( face ) );
+  }
+
+
+  FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
+    cff_service_metrics_variations,
+
+    (FT_HAdvance_Adjust_Func)cff_hadvance_adjust,    /* hadvance_adjust */
+    (FT_LSB_Adjust_Func)     NULL,                   /* lsb_adjust      */
+    (FT_RSB_Adjust_Func)     NULL,                   /* rsb_adjust      */
+
+    (FT_VAdvance_Adjust_Func)NULL,                   /* vadvance_adjust */
+    (FT_TSB_Adjust_Func)     NULL,                   /* tsb_adjust      */
+    (FT_BSB_Adjust_Func)     NULL,                   /* bsb_adjust      */
+    (FT_VOrg_Adjust_Func)    NULL,                   /* vorg_adjust     */
+
+    (FT_Metrics_Adjust_Func) cff_metrics_adjust      /* metrics_adjust  */
+  )
+#endif
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
@@ -871,9 +1077,25 @@
   /*************************************************************************/
   /*************************************************************************/
 
-#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
+#if !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES && \
+     defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
+  FT_DEFINE_SERVICEDESCREC9(
+    cff_services,
+
+    FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
+    FT_SERVICE_ID_MULTI_MASTERS,        &CFF_SERVICE_MULTI_MASTERS_GET,
+    FT_SERVICE_ID_METRICS_VARIATIONS,   &CFF_SERVICE_METRICS_VAR_GET,
+    FT_SERVICE_ID_POSTSCRIPT_INFO,      &CFF_SERVICE_PS_INFO_GET,
+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
+    FT_SERVICE_ID_GLYPH_DICT,           &CFF_SERVICE_GLYPH_DICT_GET,
+    FT_SERVICE_ID_TT_CMAP,              &CFF_SERVICE_GET_CMAP_INFO_GET,
+    FT_SERVICE_ID_CID,                  &CFF_SERVICE_CID_INFO_GET,
+    FT_SERVICE_ID_PROPERTIES,           &CFF_SERVICE_PROPERTIES_GET
+  )
+#elif !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES
   FT_DEFINE_SERVICEDESCREC7(
     cff_services,
+
     FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
     FT_SERVICE_ID_POSTSCRIPT_INFO,      &CFF_SERVICE_PS_INFO_GET,
     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
@@ -882,9 +1104,23 @@
     FT_SERVICE_ID_CID,                  &CFF_SERVICE_CID_INFO_GET,
     FT_SERVICE_ID_PROPERTIES,           &CFF_SERVICE_PROPERTIES_GET
   )
+#elif defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
+  FT_DEFINE_SERVICEDESCREC8(
+    cff_services,
+
+    FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
+    FT_SERVICE_ID_MULTI_MASTERS,        &CFF_SERVICE_MULTI_MASTERS_GET,
+    FT_SERVICE_ID_METRICS_VARIATIONS,   &CFF_SERVICE_METRICS_VAR_GET,
+    FT_SERVICE_ID_POSTSCRIPT_INFO,      &CFF_SERVICE_PS_INFO_GET,
+    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
+    FT_SERVICE_ID_TT_CMAP,              &CFF_SERVICE_GET_CMAP_INFO_GET,
+    FT_SERVICE_ID_CID,                  &CFF_SERVICE_CID_INFO_GET,
+    FT_SERVICE_ID_PROPERTIES,           &CFF_SERVICE_PROPERTIES_GET
+  )
 #else
   FT_DEFINE_SERVICEDESCREC6(
     cff_services,
+
     FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
     FT_SERVICE_ID_POSTSCRIPT_INFO,      &CFF_SERVICE_PS_INFO_GET,
     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET,
@@ -914,7 +1150,7 @@
 #endif
 
     result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface );
-    if ( result != NULL )
+    if ( result )
       return result;
 
     /* `driver' is not yet evaluated in non-PIC mode */
@@ -954,7 +1190,7 @@
       0x10000L,
       0x20000L,
 
-      0,   /* module-specific interface */
+      NULL,   /* module-specific interface */
 
       cff_driver_init,          /* FT_Module_Constructor  module_init   */
       cff_driver_done,          /* FT_Module_Destructor   module_done   */
@@ -974,7 +1210,7 @@
     cff_glyph_load,             /* FT_Slot_LoadFunc  load_glyph */
 
     cff_get_kerning,            /* FT_Face_GetKerningFunc   get_kerning  */
-    0,                          /* FT_Face_AttachFunc       attach_file  */
+    NULL,                       /* FT_Face_AttachFunc       attach_file  */
     cff_get_advances,           /* FT_Face_GetAdvancesFunc  get_advances */
 
     cff_size_request,           /* FT_Size_RequestFunc  request_size */
diff --git a/src/cff/cffdrivr.h b/src/cff/cffdrivr.h
index d7b0598..05381e6 100644
--- a/src/cff/cffdrivr.h
+++ b/src/cff/cffdrivr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level OpenType driver interface (specification).                */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cfferrs.h b/src/cff/cfferrs.h
index e7fc6eb..40808c1 100644
--- a/src/cff/cfferrs.h
+++ b/src/cff/cfferrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF error codes (specification only).                                */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 4f375a6..f8e80c1 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (body).                                        */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -391,7 +391,7 @@
 
 
     /* clear everything */
-    FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
+    FT_ZERO( decoder );
 
     /* initialize builder */
     cff_builder_init( &decoder->builder, face, size, slot, hinting );
@@ -1026,7 +1026,7 @@
         if ( !( val & 0xFFFFL ) )
           FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
         else
-          FT_TRACE4(( " %.2f", val / 65536.0 ));
+          FT_TRACE4(( " %.5f", val / 65536.0 ));
 #endif
 
       }
@@ -2445,7 +2445,7 @@
 
         case cff_op_and:
           {
-            FT_Fixed  cond = args[0] && args[1];
+            FT_Fixed  cond = ( args[0] && args[1] );
 
 
             FT_TRACE4(( " and\n" ));
@@ -2457,7 +2457,7 @@
 
         case cff_op_or:
           {
-            FT_Fixed  cond = args[0] || args[1];
+            FT_Fixed  cond = ( args[0] || args[1] );
 
 
             FT_TRACE4(( " or\n" ));
@@ -2481,7 +2481,7 @@
 
         case cff_op_eq:
           {
-            FT_Fixed  cond = args[0] == args[1];
+            FT_Fixed  cond = ( args[0] == args[1] );
 
 
             FT_TRACE4(( " eq\n" ));
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index b875fbe..0fa93b4 100644
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (specification).                               */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 470fa82..935e612 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType and CFF data/program tables loader (body).                  */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -23,12 +23,20 @@
 #include FT_TRUETYPE_TAGS_H
 #include FT_TYPE1_TABLES_H
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#include FT_MULTIPLE_MASTERS_H
+#include FT_SERVICE_MULTIPLE_MASTERS_H
+#endif
+
 #include "cffload.h"
 #include "cffparse.h"
 
 #include "cfferrs.h"
 
 
+#define FT_FIXED_ONE  ( (FT_Fixed)0x10000 )
+
+
 #if 1
 
   static const FT_UShort  cff_isoadobe_charset[229] =
@@ -225,19 +233,33 @@
   static FT_Error
   cff_index_init( CFF_Index  idx,
                   FT_Stream  stream,
-                  FT_Bool    load )
+                  FT_Bool    load,
+                  FT_Bool    cff2 )
   {
     FT_Error   error;
     FT_Memory  memory = stream->memory;
-    FT_UShort  count;
+    FT_UInt    count;
 
 
-    FT_MEM_ZERO( idx, sizeof ( *idx ) );
+    FT_ZERO( idx );
 
     idx->stream = stream;
     idx->start  = FT_STREAM_POS();
-    if ( !FT_READ_USHORT( count ) &&
-         count > 0                )
+
+    if ( cff2 )
+    {
+      if ( FT_READ_ULONG( count ) )
+        goto Exit;
+      idx->hdr_size = 5;
+    }
+    else
+    {
+      if ( FT_READ_USHORT( count ) )
+        goto Exit;
+      idx->hdr_size = 3;
+    }
+
+    if ( count > 0 )
     {
       FT_Byte   offsize;
       FT_ULong  size;
@@ -258,7 +280,7 @@
       idx->off_size = offsize;
       size          = (FT_ULong)( count + 1 ) * offsize;
 
-      idx->data_offset = idx->start + 3 + size;
+      idx->data_offset = idx->start + idx->hdr_size + size;
 
       if ( FT_STREAM_SKIP( size - offsize ) )
         goto Exit;
@@ -310,7 +332,7 @@
         FT_FRAME_RELEASE( idx->bytes );
 
       FT_FREE( idx->offsets );
-      FT_MEM_ZERO( idx, sizeof ( *idx ) );
+      FT_ZERO( idx );
     }
   }
 
@@ -323,7 +345,7 @@
     FT_Memory  memory = stream->memory;
 
 
-    if ( idx->count > 0 && idx->offsets == NULL )
+    if ( idx->count > 0 && !idx->offsets )
     {
       FT_Byte    offsize = idx->off_size;
       FT_ULong   data_size;
@@ -335,7 +357,7 @@
       data_size = (FT_ULong)( idx->count + 1 ) * offsize;
 
       if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
-           FT_STREAM_SEEK( idx->start + 3 )             ||
+           FT_STREAM_SEEK( idx->start + idx->hdr_size ) ||
            FT_FRAME_ENTER( data_size )                  )
         goto Exit;
 
@@ -395,7 +417,7 @@
 
     *table = NULL;
 
-    if ( idx->offsets == NULL )
+    if ( !idx->offsets )
     {
       error = cff_index_load_offsets( idx );
       if ( error )
@@ -493,7 +515,7 @@
         FT_ULong  pos = element * idx->off_size;
 
 
-        if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
+        if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) )
           goto Exit;
 
         off1 = cff_index_read_offset( idx, &error );
@@ -589,13 +611,18 @@
                       FT_UInt   element )
   {
     CFF_Index   idx = &font->name_index;
-    FT_Memory   memory = idx->stream->memory;
+    FT_Memory   memory;
     FT_Byte*    bytes;
     FT_ULong    byte_len;
     FT_Error    error;
     FT_String*  name = 0;
 
 
+    if ( !idx->stream )  /* CFF2 does not include a name index */
+      goto Exit;
+
+    memory = idx->stream->memory;
+
     error = cff_index_access_element( idx, element, &bytes, &byte_len );
     if ( error )
       goto Exit;
@@ -725,6 +752,11 @@
     FT_Byte  fd = 0;
 
 
+    /* if there is no FDSelect, return zero               */
+    /* Note: CFF2 with just one Font Dict has no FDSelect */
+    if ( !fdselect->data )
+      goto Exit;
+
     switch ( fdselect->format )
     {
     case 0:
@@ -777,6 +809,7 @@
       ;
     }
 
+  Exit:
     return fd;
   }
 
@@ -1055,6 +1088,512 @@
 
 
   static void
+  cff_vstore_done( CFF_VStoreRec*  vstore,
+                   FT_Memory       memory )
+  {
+    FT_UInt  i;
+
+
+    /* free regionList and axisLists */
+    if ( vstore->varRegionList )
+    {
+      for ( i = 0; i < vstore->regionCount; i++ )
+        FT_FREE( vstore->varRegionList[i].axisList );
+    }
+    FT_FREE( vstore->varRegionList );
+
+    /* free varData and indices */
+    if ( vstore->varData )
+    {
+      for ( i = 0; i < vstore->dataCount; i++ )
+        FT_FREE( vstore->varData[i].regionIndices );
+    }
+    FT_FREE( vstore->varData );
+  }
+
+
+  /* convert 2.14 to Fixed */
+  #define FT_fdot14ToFixed( x )  ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
+
+
+  static FT_Error
+  cff_vstore_load( CFF_VStoreRec*  vstore,
+                   FT_Stream       stream,
+                   FT_ULong        base_offset,
+                   FT_ULong        offset )
+  {
+    FT_Memory  memory = stream->memory;
+    FT_Error   error  = FT_ERR( Invalid_File_Format );
+
+    FT_ULong*  dataOffsetArray = NULL;
+    FT_UInt    i, j;
+
+
+    /* no offset means no vstore to parse */
+    if ( offset )
+    {
+      FT_UInt   vsOffset;
+      FT_UInt   format;
+      FT_ULong  regionListOffset;
+
+
+      /* we need to parse the table to determine its size; */
+      /* skip table length                                 */
+      if ( FT_STREAM_SEEK( base_offset + offset ) ||
+           FT_STREAM_SKIP( 2 )                    )
+        goto Exit;
+
+      /* actual variation store begins after the length */
+      vsOffset = FT_STREAM_POS();
+
+      /* check the header */
+      if ( FT_READ_USHORT( format ) )
+        goto Exit;
+      if ( format != 1 )
+      {
+        error = FT_THROW( Invalid_File_Format );
+        goto Exit;
+      }
+
+      /* read top level fields */
+      if ( FT_READ_ULONG( regionListOffset )   ||
+           FT_READ_USHORT( vstore->dataCount ) )
+        goto Exit;
+
+      /* make temporary copy of item variation data offsets; */
+      /* we'll parse region list first, then come back       */
+      if ( FT_NEW_ARRAY( dataOffsetArray, vstore->dataCount ) )
+        goto Exit;
+
+      for ( i = 0; i < vstore->dataCount; i++ )
+      {
+        if ( FT_READ_ULONG( dataOffsetArray[i] ) )
+          goto Exit;
+      }
+
+      /* parse regionList and axisLists */
+      if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) ||
+           FT_READ_USHORT( vstore->axisCount )           ||
+           FT_READ_USHORT( vstore->regionCount )         )
+        goto Exit;
+
+      if ( FT_NEW_ARRAY( vstore->varRegionList, vstore->regionCount ) )
+        goto Exit;
+
+      for ( i = 0; i < vstore->regionCount; i++ )
+      {
+        CFF_VarRegion*  region = &vstore->varRegionList[i];
+
+
+        if ( FT_NEW_ARRAY( region->axisList, vstore->axisCount ) )
+          goto Exit;
+
+        for ( j = 0; j < vstore->axisCount; j++ )
+        {
+          CFF_AxisCoords*  axis = &region->axisList[j];
+
+          FT_Int16  start14, peak14, end14;
+
+
+          if ( FT_READ_SHORT( start14 ) ||
+               FT_READ_SHORT( peak14 )  ||
+               FT_READ_SHORT( end14 )   )
+            goto Exit;
+
+          axis->startCoord = FT_fdot14ToFixed( start14 );
+          axis->peakCoord  = FT_fdot14ToFixed( peak14 );
+          axis->endCoord   = FT_fdot14ToFixed( end14 );
+        }
+      }
+
+      /* use dataOffsetArray now to parse varData items */
+      if ( FT_NEW_ARRAY( vstore->varData, vstore->dataCount ) )
+        goto Exit;
+
+      for ( i = 0; i < vstore->dataCount; i++ )
+      {
+        CFF_VarData*  data = &vstore->varData[i];
+
+
+        if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) )
+          goto Exit;
+
+        /* ignore `itemCount' and `shortDeltaCount' */
+        /* because CFF2 has no delta sets           */
+        if ( FT_STREAM_SKIP( 4 ) )
+          goto Exit;
+
+        /* Note: just record values; consistency is checked later    */
+        /*       by cff_blend_build_vector when it consumes `vstore' */
+
+        if ( FT_READ_USHORT( data->regionIdxCount ) )
+          goto Exit;
+
+        if ( FT_NEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
+          goto Exit;
+
+        for ( j = 0; j < data->regionIdxCount; j++ )
+        {
+          if ( FT_READ_USHORT( data->regionIndices[j] ) )
+            goto Exit;
+        }
+      }
+    }
+
+    error = FT_Err_Ok;
+
+  Exit:
+    FT_FREE( dataOffsetArray );
+    if ( error )
+      cff_vstore_done( vstore, memory );
+
+    return error;
+  }
+
+
+  /* Clear blend stack (after blend values are consumed). */
+  /*                                                      */
+  /* TODO: Should do this in cff_run_parse, but subFont   */
+  /*       ref is not available there.                    */
+  /*                                                      */
+  /* Allocation is not changed when stack is cleared.     */
+  FT_LOCAL_DEF( void )
+  cff_blend_clear( CFF_SubFont  subFont )
+  {
+    subFont->blend_top  = subFont->blend_stack;
+    subFont->blend_used = 0;
+  }
+
+
+  /* Blend numOperands on the stack,                       */
+  /* store results into the first numBlends values,        */
+  /* then pop remaining arguments.                         */
+  /*                                                       */
+  /* This is comparable to `cf2_doBlend' but               */
+  /* the cffparse stack is different and can't be written. */
+  /* Blended values are written to a different buffer,     */
+  /* using reserved operator 255.                          */
+  /*                                                       */
+  /* Blend calculation is done in 16.16 fixed point.       */
+  FT_LOCAL_DEF( FT_Error )
+  cff_blend_doBlend( CFF_SubFont  subFont,
+                     CFF_Parser   parser,
+                     FT_UInt      numBlends )
+  {
+    FT_UInt  delta;
+    FT_UInt  base;
+    FT_UInt  i, j;
+    FT_UInt  size;
+
+    CFF_Blend  blend = &subFont->blend;
+
+    FT_Memory  memory = subFont->blend.font->memory; /* for FT_REALLOC */
+    FT_Error   error  = FT_Err_Ok;                   /* for FT_REALLOC */
+
+    /* compute expected number of operands for this blend */
+    FT_UInt  numOperands = (FT_UInt)( numBlends * blend->lenBV );
+    FT_UInt  count       = (FT_UInt)( parser->top - 1 - parser->stack );
+
+
+    if ( numOperands > count )
+    {
+      FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d args\n", count ));
+
+      error = FT_THROW( Stack_Underflow );
+      goto Exit;
+    }
+
+    /* check whether we have room for `numBlends' values at `blend_top' */
+    size = 5 * numBlends;           /* add 5 bytes per entry    */
+    if ( subFont->blend_used + size > subFont->blend_alloc )
+    {
+      FT_Byte*  blend_stack_old = subFont->blend_stack;
+      FT_Byte*  blend_top_old   = subFont->blend_top;
+
+
+      /* increase or allocate `blend_stack' and reset `blend_top'; */
+      /* prepare to append `numBlends' values to the buffer        */
+      if ( FT_REALLOC( subFont->blend_stack,
+                       subFont->blend_alloc,
+                       subFont->blend_alloc + size ) )
+        goto Exit;
+
+      subFont->blend_top    = subFont->blend_stack + subFont->blend_used;
+      subFont->blend_alloc += size;
+
+      /* iterate over the parser stack and adjust pointers */
+      /* if the reallocated buffer has a different address */
+      if ( blend_stack_old                         &&
+           subFont->blend_stack != blend_stack_old )
+      {
+        FT_PtrDist  offset = subFont->blend_stack - blend_stack_old;
+        FT_Byte**   p;
+
+
+        for ( p = parser->stack; p < parser->top; p++ )
+        {
+          if ( *p >= blend_stack_old && *p < blend_top_old )
+            *p += offset;
+        }
+      }
+    }
+    subFont->blend_used += size;
+
+    base  = count - numOperands;     /* index of first blend arg */
+    delta = base + numBlends;        /* index of first delta arg */
+
+    for ( i = 0; i < numBlends; i++ )
+    {
+      const FT_Int32*  weight = &blend->BV[1];
+      FT_Int32         sum;
+
+
+      /* convert inputs to 16.16 fixed point */
+      sum = cff_parse_num( parser, &parser->stack[i + base] ) * 65536;
+
+      for ( j = 1; j < blend->lenBV; j++ )
+        sum += FT_MulFix( *weight++,
+                          cff_parse_num( parser,
+                                         &parser->stack[delta++] ) * 65536 );
+
+      /* point parser stack to new value on blend_stack */
+      parser->stack[i + base] = subFont->blend_top;
+
+      /* Push blended result as Type 2 5-byte fixed point number.  This */
+      /* will not conflict with actual DICTs because 255 is a reserved  */
+      /* opcode in both CFF and CFF2 DICTs.  See `cff_parse_num' for    */
+      /* decode of this, which rounds to an integer.                    */
+      *subFont->blend_top++ = 255;
+      *subFont->blend_top++ = ( (FT_UInt32)sum & 0xFF000000U ) >> 24;
+      *subFont->blend_top++ = ( (FT_UInt32)sum & 0x00FF0000U ) >> 16;
+      *subFont->blend_top++ = ( (FT_UInt32)sum & 0x0000FF00U ) >>  8;
+      *subFont->blend_top++ =   (FT_UInt32)sum & 0x000000FFU;
+    }
+
+    /* leave only numBlends results on parser stack */
+    parser->top = &parser->stack[base + numBlends];
+
+  Exit:
+    return error;
+  }
+
+
+  /* Compute a blend vector from variation store index and normalized  */
+  /* vector based on pseudo-code in OpenType Font Variations Overview. */
+  /*                                                                   */
+  /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...).   */
+  FT_LOCAL_DEF( FT_Error )
+  cff_blend_build_vector( CFF_Blend  blend,
+                          FT_UInt    vsindex,
+                          FT_UInt    lenNDV,
+                          FT_Fixed*  NDV )
+  {
+    FT_Error   error  = FT_Err_Ok;            /* for FT_REALLOC */
+    FT_Memory  memory = blend->font->memory;  /* for FT_REALLOC */
+
+    FT_UInt       len;
+    CFF_VStore    vs;
+    CFF_VarData*  varData;
+    FT_UInt       master;
+
+
+    FT_ASSERT( lenNDV == 0 || NDV );
+
+    blend->builtBV = FALSE;
+
+    vs = &blend->font->vstore;
+
+    /* VStore and fvar must be consistent */
+    if ( lenNDV != 0 && lenNDV != vs->axisCount )
+    {
+      FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    if ( vsindex >= vs->dataCount )
+    {
+      FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    /* select the item variation data structure */
+    varData = &vs->varData[vsindex];
+
+    /* prepare buffer for the blend vector */
+    len = varData->regionIdxCount + 1;    /* add 1 for default component */
+    if ( FT_REALLOC( blend->BV,
+                     blend->lenBV * sizeof( *blend->BV ),
+                     len * sizeof( *blend->BV ) ) )
+      goto Exit;
+
+    blend->lenBV = len;
+
+    /* outer loop steps through master designs to be blended */
+    for ( master = 0; master < len; master++ )
+    {
+      FT_UInt         j;
+      FT_UInt         idx;
+      CFF_VarRegion*  varRegion;
+
+
+      /* default factor is always one */
+      if ( master == 0 )
+      {
+        blend->BV[master] = FT_FIXED_ONE;
+        FT_TRACE4(( "   build blend vector len %d\n"
+                    "   [ %f ",
+                    len,
+                    blend->BV[master] / 65536.0 ));
+        continue;
+      }
+
+      /* VStore array does not include default master, so subtract one */
+      idx       = varData->regionIndices[master - 1];
+      varRegion = &vs->varRegionList[idx];
+
+      if ( idx >= vs->regionCount )
+      {
+        FT_TRACE4(( " cff_blend_build_vector:"
+                    " region index out of range\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Exit;
+      }
+
+      /* Note: `lenNDV' could be zero.                              */
+      /*       In that case, build default blend vector (1,0,0...). */
+      /*       In the normal case, initialize each component to 1   */
+      /*       before inner loop.                                   */
+      if ( lenNDV != 0 )
+        blend->BV[master] = FT_FIXED_ONE; /* default */
+
+      /* inner loop steps through axes in this region */
+      for ( j = 0; j < lenNDV; j++ )
+      {
+        CFF_AxisCoords*  axis = &varRegion->axisList[j];
+        FT_Fixed         axisScalar;
+
+
+        /* compute the scalar contribution of this axis; */
+        /* ignore invalid ranges                         */
+        if ( axis->startCoord > axis->peakCoord ||
+             axis->peakCoord > axis->endCoord   )
+          axisScalar = FT_FIXED_ONE;
+
+        else if ( axis->startCoord < 0 &&
+                  axis->endCoord > 0   &&
+                  axis->peakCoord != 0 )
+          axisScalar = FT_FIXED_ONE;
+
+        /* peak of 0 means ignore this axis */
+        else if ( axis->peakCoord == 0 )
+          axisScalar = FT_FIXED_ONE;
+
+        /* ignore this region if coords are out of range */
+        else if ( NDV[j] < axis->startCoord ||
+                  NDV[j] > axis->endCoord   )
+          axisScalar = 0;
+
+        /* calculate a proportional factor */
+        else
+        {
+          if ( NDV[j] == axis->peakCoord )
+            axisScalar = FT_FIXED_ONE;
+          else if ( NDV[j] < axis->peakCoord )
+            axisScalar = FT_DivFix( NDV[j] - axis->startCoord,
+                                    axis->peakCoord - axis->startCoord );
+          else
+            axisScalar = FT_DivFix( axis->endCoord - NDV[j],
+                                    axis->endCoord - axis->peakCoord );
+        }
+
+        /* take product of all the axis scalars */
+        blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar );
+      }
+
+      FT_TRACE4(( ", %f ",
+                  blend->BV[master] / 65536.0 ));
+    }
+
+    FT_TRACE4(( "]\n" ));
+
+    /* record the parameters used to build the blend vector */
+    blend->lastVsindex = vsindex;
+
+    if ( lenNDV != 0 )
+    {
+      /* user has set a normalized vector */
+      if ( FT_REALLOC( blend->lastNDV,
+                       blend->lenNDV * sizeof ( *NDV ),
+                       lenNDV * sizeof ( *NDV ) ) )
+        goto Exit;
+
+      blend->lenNDV = lenNDV;
+      FT_MEM_COPY( blend->lastNDV,
+                   NDV,
+                   lenNDV * sizeof ( *NDV ) );
+    }
+
+    blend->builtBV = TRUE;
+
+  Exit:
+    return error;
+  }
+
+
+  /* `lenNDV' is zero for default vector;           */
+  /* return TRUE if blend vector needs to be built. */
+  FT_LOCAL_DEF( FT_Bool )
+  cff_blend_check_vector( CFF_Blend  blend,
+                          FT_UInt    vsindex,
+                          FT_UInt    lenNDV,
+                          FT_Fixed*  NDV )
+  {
+    if ( !blend->builtBV                             ||
+         blend->lastVsindex != vsindex               ||
+         blend->lenNDV != lenNDV                     ||
+         ( lenNDV                                  &&
+           memcmp( NDV,
+                   blend->lastNDV,
+                   lenNDV * sizeof ( *NDV ) ) != 0 ) )
+    {
+      /* need to build blend vector */
+      return TRUE;
+    }
+
+    return FALSE;
+  }
+
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+  FT_LOCAL_DEF( FT_Error )
+  cff_get_var_blend( CFF_Face     face,
+                     FT_UInt     *num_coords,
+                     FT_Fixed*   *coords,
+                     FT_MM_Var*  *mm_var )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    return mm->get_var_blend( FT_FACE( face ), num_coords, coords, mm_var );
+  }
+
+
+  FT_LOCAL_DEF( void )
+  cff_done_blend( CFF_Face  face )
+  {
+    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+
+    mm->done_blend( FT_FACE( face ) );
+  }
+
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+
+
+  static void
   cff_encoding_done( CFF_Encoding  encoding )
   {
     encoding->format = 0;
@@ -1306,31 +1845,127 @@
   }
 
 
+  /* Parse private dictionary; first call is always from `cff_face_init', */
+  /* so NDV has not been set for CFF2 variation.                          */
+  /*                                                                      */
+  /* `cff_slot_load' must call this function each time NDV changes.       */
+  FT_LOCAL_DEF( FT_Error )
+  cff_load_private_dict( CFF_Font     font,
+                         CFF_SubFont  subfont,
+                         FT_UInt      lenNDV,
+                         FT_Fixed*    NDV )
+  {
+    FT_Error         error  = FT_Err_Ok;
+    CFF_ParserRec    parser;
+    CFF_FontRecDict  top    = &subfont->font_dict;
+    CFF_Private      priv   = &subfont->private_dict;
+    FT_Stream        stream = font->stream;
+    FT_UInt          stackSize;
+
+
+    /* store handle needed to access memory, vstore for blend;    */
+    /* we need this for clean-up even if there is no private DICT */
+    subfont->blend.font   = font;
+    subfont->blend.usedBV = FALSE;  /* clear state */
+
+    if ( !top->private_offset || !top->private_size )
+      goto Exit2;       /* no private DICT, do nothing */
+
+    /* set defaults */
+    FT_ZERO( priv );
+
+    priv->blue_shift       = 7;
+    priv->blue_fuzz        = 1;
+    priv->lenIV            = -1;
+    priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
+    priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
+
+    /* provide inputs for blend calculations */
+    priv->subfont   = subfont;
+    subfont->lenNDV = lenNDV;
+    subfont->NDV    = NDV;
+
+    stackSize = font->cff2 ? font->top_font.font_dict.maxstack
+                           : CFF_MAX_STACK_DEPTH + 1;
+
+    if ( cff_parser_init( &parser,
+                          font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
+                          priv,
+                          font->library,
+                          stackSize,
+                          top->num_designs,
+                          top->num_axes ) )
+      goto Exit;
+
+    if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
+         FT_FRAME_ENTER( top->private_size )                       )
+      goto Exit;
+
+    FT_TRACE4(( " private dictionary:\n" ));
+    error = cff_parser_run( &parser,
+                            (FT_Byte*)stream->cursor,
+                            (FT_Byte*)stream->limit );
+    FT_FRAME_EXIT();
+
+    if ( error )
+      goto Exit;
+
+    /* ensure that `num_blue_values' is even */
+    priv->num_blue_values &= ~1;
+
+  Exit:
+    /* clean up */
+    cff_blend_clear( subfont ); /* clear blend stack */
+    cff_parser_done( &parser ); /* free parser stack */
+
+  Exit2:
+    /* no clean up (parser not initialized) */
+    return error;
+  }
+
+
+  /* There are 3 ways to call this function, distinguished by code.  */
+  /*                                                                 */
+  /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
+  /* . CFF2_CODE_TOPDICT for CFF2 Top DICT                           */
+  /* . CFF2_CODE_FONTDICT for CFF2 Font DICT                         */
+
   static FT_Error
-  cff_subfont_load( CFF_SubFont  font,
+  cff_subfont_load( CFF_SubFont  subfont,
                     CFF_Index    idx,
                     FT_UInt      font_index,
                     FT_Stream    stream,
                     FT_ULong     base_offset,
-                    FT_Library   library )
+                    FT_UInt      code,
+                    CFF_Font     font )
   {
     FT_Error         error;
     CFF_ParserRec    parser;
     FT_Byte*         dict = NULL;
     FT_ULong         dict_len;
-    CFF_FontRecDict  top  = &font->font_dict;
-    CFF_Private      priv = &font->private_dict;
+    CFF_FontRecDict  top  = &subfont->font_dict;
+    CFF_Private      priv = &subfont->private_dict;
+
+    FT_Bool  cff2      = FT_BOOL( code == CFF2_CODE_TOPDICT  ||
+                                  code == CFF2_CODE_FONTDICT );
+    FT_UInt  stackSize = cff2 ? CFF2_DEFAULT_STACK
+                              : CFF_MAX_STACK_DEPTH;
 
 
-    cff_parser_init( &parser,
-                     CFF_CODE_TOPDICT,
-                     &font->font_dict,
-                     library,
-                     0,
-                     0 );
+    /* Note: We use default stack size for CFF2 Font DICT because        */
+    /*       Top and Font DICTs are not allowed to have blend operators. */
+    error = cff_parser_init( &parser,
+                             code,
+                             &subfont->font_dict,
+                             font->library,
+                             stackSize,
+                             0,
+                             0 );
+    if ( error )
+      goto Exit;
 
     /* set defaults */
-    FT_MEM_ZERO( top, sizeof ( *top ) );
+    FT_ZERO( top );
 
     top->underline_position  = -( 100L << 16 );
     top->underline_thickness = 50L << 16;
@@ -1353,14 +1988,35 @@
     top->cid_ordering        = 0xFFFFU;
     top->cid_font_name       = 0xFFFFU;
 
-    error = cff_index_access_element( idx, font_index, &dict, &dict_len );
+    /* set default stack size */
+    top->maxstack            = cff2 ? CFF2_DEFAULT_STACK : 48;
+
+    if ( idx->count )   /* count is nonzero for a real index */
+      error = cff_index_access_element( idx, font_index, &dict, &dict_len );
+    else
+    {
+      /* CFF2 has a fake top dict index;     */
+      /* simulate `cff_index_access_element' */
+
+      /* Note: macros implicitly use `stream' and set `error' */
+      if ( FT_STREAM_SEEK( idx->data_offset )       ||
+           FT_FRAME_EXTRACT( idx->data_size, dict ) )
+        goto Exit;
+
+      dict_len = idx->data_size;
+    }
+
     if ( !error )
     {
       FT_TRACE4(( " top dictionary:\n" ));
       error = cff_parser_run( &parser, dict, dict + dict_len );
     }
 
-    cff_index_forget_element( idx, &dict );
+    /* clean up regardless of error */
+    if ( idx->count )
+      cff_index_forget_element( idx, &dict );
+    else
+      FT_FRAME_RELEASE( dict );
 
     if ( error )
       goto Exit;
@@ -1369,40 +2025,14 @@
     if ( top->cid_registry != 0xFFFFU )
       goto Exit;
 
-    /* parse the private dictionary, if any */
-    if ( top->private_offset && top->private_size )
-    {
-      /* set defaults */
-      FT_MEM_ZERO( priv, sizeof ( *priv ) );
-
-      priv->blue_shift       = 7;
-      priv->blue_fuzz        = 1;
-      priv->lenIV            = -1;
-      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
-      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
-
-      cff_parser_init( &parser,
-                       CFF_CODE_PRIVATE,
-                       priv,
-                       library,
-                       top->num_designs,
-                       top->num_axes );
-
-      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
-           FT_FRAME_ENTER( font->font_dict.private_size )                 )
-        goto Exit;
-
-      FT_TRACE4(( " private dictionary:\n" ));
-      error = cff_parser_run( &parser,
-                              (FT_Byte*)stream->cursor,
-                              (FT_Byte*)stream->limit );
-      FT_FRAME_EXIT();
-      if ( error )
-        goto Exit;
-
-      /* ensure that `num_blue_values' is even */
-      priv->num_blue_values &= ~1;
-    }
+    /* Parse the private dictionary, if any.                   */
+    /*                                                         */
+    /* CFF2 does not have a private dictionary in the Top DICT */
+    /* but may have one in a Font DICT.  We need to parse      */
+    /* the latter here in order to load any local subrs.       */
+    error = cff_load_private_dict( font, subfont, 0, 0 );
+    if ( error )
+      goto Exit;
 
     /* read the local subrs, if any */
     if ( priv->local_subrs_offset )
@@ -1411,17 +2041,19 @@
                            priv->local_subrs_offset ) )
         goto Exit;
 
-      error = cff_index_init( &font->local_subrs_index, stream, 1 );
+      error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 );
       if ( error )
         goto Exit;
 
-      error = cff_index_get_pointers( &font->local_subrs_index,
-                                      &font->local_subrs, NULL, NULL );
+      error = cff_index_get_pointers( &subfont->local_subrs_index,
+                                      &subfont->local_subrs, NULL, NULL );
       if ( error )
         goto Exit;
     }
 
   Exit:
+    cff_parser_done( &parser ); /* free parser stack */
+
     return error;
   }
 
@@ -1434,6 +2066,10 @@
     {
       cff_index_done( &subfont->local_subrs_index );
       FT_FREE( subfont->local_subrs );
+
+      FT_FREE( subfont->blend.lastNDV );
+      FT_FREE( subfont->blend.BV );
+      FT_FREE( subfont->blend_stack );
     }
   }
 
@@ -1443,18 +2079,18 @@
                  FT_Stream  stream,
                  FT_Int     face_index,
                  CFF_Font   font,
-                 FT_Bool    pure_cff )
+                 FT_Bool    pure_cff,
+                 FT_Bool    cff2 )
   {
     static const FT_Frame_Field  cff_header_fields[] =
     {
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  CFF_FontRec
 
-      FT_FRAME_START( 4 ),
+      FT_FRAME_START( 3 ),
         FT_FRAME_BYTE( version_major ),
         FT_FRAME_BYTE( version_minor ),
         FT_FRAME_BYTE( header_size ),
-        FT_FRAME_BYTE( absolute_offsize ),
       FT_FRAME_END
     };
 
@@ -1469,43 +2105,131 @@
     FT_ZERO( font );
     FT_ZERO( &string_index );
 
-    font->stream = stream;
-    font->memory = memory;
-    dict         = &font->top_font.font_dict;
-    base_offset  = FT_STREAM_POS();
+    dict        = &font->top_font.font_dict;
+    base_offset = FT_STREAM_POS();
+
+    font->library     = library;
+    font->stream      = stream;
+    font->memory      = memory;
+    font->cff2        = cff2;
+    font->base_offset = base_offset;
 
     /* read CFF font header */
     if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
       goto Exit;
 
-    /* check format */
-    if ( font->version_major   != 1 ||
-         font->header_size      < 4 ||
-         font->absolute_offsize > 4 )
+    if ( cff2 )
     {
-      FT_TRACE2(( "  not a CFF font header\n" ));
-      error = FT_THROW( Unknown_File_Format );
-      goto Exit;
+      if ( font->version_major != 2 ||
+           font->header_size < 5    )
+      {
+        FT_TRACE2(( "  not a CFF2 font header\n" ));
+        error = FT_THROW( Unknown_File_Format );
+        goto Exit;
+      }
+
+      if ( FT_READ_USHORT( font->top_dict_length ) )
+        goto Exit;
+    }
+    else
+    {
+      FT_Byte  absolute_offset;
+
+
+      if ( FT_READ_BYTE( absolute_offset ) )
+        goto Exit;
+
+      if ( font->version_major != 1 ||
+           font->header_size < 4    ||
+           absolute_offset > 4      )
+      {
+        FT_TRACE2(( "  not a CFF font header\n" ));
+        error = FT_THROW( Unknown_File_Format );
+        goto Exit;
+      }
     }
 
     /* skip the rest of the header */
-    if ( FT_STREAM_SKIP( font->header_size - 4 ) )
+    if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
+    {
+      /* For pure CFFs we have read only four bytes so far.  Contrary to */
+      /* other formats like SFNT those bytes doesn't define a signature; */
+      /* it is thus possible that the font isn't a CFF at all.           */
+      if ( pure_cff )
+      {
+        FT_TRACE2(( "  not a CFF file\n" ));
+        error = FT_THROW( Unknown_File_Format );
+      }
       goto Exit;
+    }
 
-    /* read the name, top dict, string and global subrs index */
-    if ( FT_SET_ERROR( cff_index_init( &font->name_index,
-                                       stream, 0 ) )                       ||
-         FT_SET_ERROR( cff_index_init( &font->font_dict_index,
-                                       stream, 0 ) )                       ||
-         FT_SET_ERROR( cff_index_init( &string_index,
-                                       stream, 1 ) )                       ||
-         FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
-                                       stream, 1 ) )                       ||
-         FT_SET_ERROR( cff_index_get_pointers( &string_index,
-                                               &font->strings,
-                                               &font->string_pool,
-                                               &font->string_pool_size ) ) )
-      goto Exit;
+    if ( cff2 )
+    {
+      /* For CFF2, the top dict data immediately follow the header    */
+      /* and the length is stored in the header `offSize' field;      */
+      /* there is no index for it.                                    */
+      /*                                                              */
+      /* Use the `font_dict_index' to save the current position       */
+      /* and length of data, but leave count at zero as an indicator. */
+      FT_ZERO( &font->font_dict_index );
+
+      font->font_dict_index.data_offset = FT_STREAM_POS();
+      font->font_dict_index.data_size   = font->top_dict_length;
+
+      /* skip the top dict data for now, we will parse it later */
+      if ( FT_STREAM_SKIP( font->top_dict_length ) )
+        goto Exit;
+
+      /* next, read the global subrs index */
+      if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
+                                         stream, 1, cff2 ) ) )
+        goto Exit;
+    }
+    else
+    {
+      /* for CFF, read the name, top dict, string and global subrs index */
+      if ( FT_SET_ERROR( cff_index_init( &font->name_index,
+                                         stream, 0, cff2 ) ) )
+      {
+        if ( pure_cff )
+        {
+          FT_TRACE2(( "  not a CFF file\n" ));
+          error = FT_THROW( Unknown_File_Format );
+        }
+        goto Exit;
+      }
+
+      /* font names must not be empty */
+      if ( font->name_index.data_size < font->name_index.count )
+      {
+        /* for pure CFFs, we still haven't checked enough bytes */
+        /* to be sure that it is a CFF at all                   */
+        error = pure_cff ? FT_THROW( Unknown_File_Format )
+                         : FT_THROW( Invalid_File_Format );
+        goto Exit;
+      }
+
+      if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index,
+                                         stream, 0, cff2 ) )                 ||
+           FT_SET_ERROR( cff_index_init( &string_index,
+                                         stream, 1, cff2 ) )                 ||
+           FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
+                                         stream, 1, cff2 ) )                 ||
+           FT_SET_ERROR( cff_index_get_pointers( &string_index,
+                                                 &font->strings,
+                                                 &font->string_pool,
+                                                 &font->string_pool_size ) ) )
+        goto Exit;
+
+      /* there must be a Top DICT index entry for each name index entry */
+      if ( font->name_index.count > font->font_dict_index.count )
+      {
+        FT_ERROR(( "cff_font_load:"
+                   " not enough entries in Top DICT index\n" ));
+        error = FT_THROW( Invalid_File_Format );
+        goto Exit;
+      }
+    }
 
     font->num_strings = string_index.count;
 
@@ -1551,34 +2275,47 @@
                               subfont_index,
                               stream,
                               base_offset,
-                              library );
+                              cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT,
+                              font );
     if ( error )
       goto Exit;
 
     if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
       goto Exit;
 
-    error = cff_index_init( &font->charstrings_index, stream, 0 );
+    error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
     if ( error )
       goto Exit;
 
-    /* now, check for a CID font */
-    if ( dict->cid_registry != 0xFFFFU )
+    /* now, check for a CID or CFF2 font */
+    if ( dict->cid_registry != 0xFFFFU ||
+         cff2                          )
     {
       CFF_IndexRec  fd_index;
       CFF_SubFont   sub = NULL;
       FT_UInt       idx;
 
 
+      /* for CFF2, read the Variation Store if available;                 */
+      /* this must follow the Top DICT parse and precede any Private DICT */
+      error = cff_vstore_load( &font->vstore,
+                               stream,
+                               base_offset,
+                               dict->vstore_offset );
+      if ( error )
+        goto Exit;
+
       /* this is a CID-keyed font, we must now allocate a table of */
       /* sub-fonts, then load each of them separately              */
       if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
         goto Exit;
 
-      error = cff_index_init( &fd_index, stream, 0 );
+      error = cff_index_init( &fd_index, stream, 0, cff2 );
       if ( error )
         goto Exit;
 
+      /* Font Dicts are not limited to 256 for CFF2. */
+      /* TODO: support this for CFF2                 */
       if ( fd_index.count > CFF_MAX_CID_FONTS )
       {
         FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
@@ -1599,17 +2336,25 @@
       {
         sub = font->subfonts[idx];
         FT_TRACE4(( "parsing subfont %u\n", idx ));
-        error = cff_subfont_load( sub, &fd_index, idx,
-                                  stream, base_offset, library );
+        error = cff_subfont_load( sub,
+                                  &fd_index,
+                                  idx,
+                                  stream,
+                                  base_offset,
+                                  cff2 ? CFF2_CODE_FONTDICT
+                                       : CFF_CODE_TOPDICT,
+                                  font );
         if ( error )
           goto Fail_CID;
       }
 
-      /* now load the FD Select array */
-      error = CFF_Load_FD_Select( &font->fd_select,
-                                  font->charstrings_index.count,
-                                  stream,
-                                  base_offset + dict->cid_fd_select_offset );
+      /* now load the FD Select array;               */
+      /* CFF2 omits FDSelect if there is only one FD */
+      if ( !cff2 || fd_index.count > 1 )
+        error = CFF_Load_FD_Select( &font->fd_select,
+                                    font->charstrings_index.count,
+                                    stream,
+                                    base_offset + dict->cid_fd_select_offset );
 
     Fail_CID:
       cff_index_done( &fd_index );
@@ -1637,7 +2382,7 @@
       goto Exit;
 
     /* read the Charset and Encoding tables if available */
-    if ( font->num_glyphs > 0 )
+    if ( !cff2 && font->num_glyphs > 0 )
     {
       FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
 
@@ -1685,7 +2430,7 @@
     cff_index_done( &font->charstrings_index );
 
     /* release font dictionaries, but only if working with */
-    /* a CID keyed CFF font                                */
+    /* a CID keyed CFF font or a CFF2 font                 */
     if ( font->num_subfonts > 0 )
     {
       for ( idx = 0; idx < font->num_subfonts; idx++ )
@@ -1697,6 +2442,7 @@
 
     cff_encoding_done( &font->encoding );
     cff_charset_done( &font->charset, font->stream );
+    cff_vstore_done( &font->vstore, memory );
 
     cff_subfont_done( memory, &font->top_font );
 
diff --git a/src/cff/cffload.h b/src/cff/cffload.h
index 1dd07ba..8be6452 100644
--- a/src/cff/cffload.h
+++ b/src/cff/cffload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType & CFF data/program tables loader (specification).           */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -22,6 +22,8 @@
 
 #include <ft2build.h>
 #include "cfftypes.h"
+#include "cffparse.h"
+#include "cffobjs.h"  /* for CFF_Face */
 
 
 FT_BEGIN_HEADER
@@ -60,20 +62,58 @@
 
 
   FT_LOCAL( FT_Error )
-  cff_font_load( FT_Library library,
-                 FT_Stream  stream,
-                 FT_Int     face_index,
-                 CFF_Font   font,
-                 FT_Bool    pure_cff );
+  cff_font_load( FT_Library  library,
+                 FT_Stream   stream,
+                 FT_Int      face_index,
+                 CFF_Font    font,
+                 FT_Bool     pure_cff,
+                 FT_Bool     cff2 );
 
   FT_LOCAL( void )
   cff_font_done( CFF_Font  font );
 
 
+  FT_LOCAL( FT_Error )
+  cff_load_private_dict( CFF_Font     font,
+                         CFF_SubFont  subfont,
+                         FT_UInt      lenNDV,
+                         FT_Fixed*    NDV );
+
   FT_LOCAL( FT_Byte )
   cff_fd_select_get( CFF_FDSelect  fdselect,
                      FT_UInt       glyph_index );
 
+  FT_LOCAL( FT_Bool )
+  cff_blend_check_vector( CFF_Blend  blend,
+                          FT_UInt    vsindex,
+                          FT_UInt    lenNDV,
+                          FT_Fixed*  NDV );
+
+  FT_LOCAL( FT_Error )
+  cff_blend_build_vector( CFF_Blend  blend,
+                          FT_UInt    vsindex,
+                          FT_UInt    lenNDV,
+                          FT_Fixed*  NDV );
+
+  FT_LOCAL( void )
+  cff_blend_clear( CFF_SubFont  subFont );
+
+  FT_LOCAL( FT_Error )
+  cff_blend_doBlend( CFF_SubFont  subfont,
+                     CFF_Parser   parser,
+                     FT_UInt      numBlends );
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+  FT_LOCAL( FT_Error )
+  cff_get_var_blend( CFF_Face     face,
+                     FT_UInt     *num_coords,
+                     FT_Fixed*   *coords,
+                     FT_MM_Var*  *mm_var );
+
+  FT_LOCAL( void )
+  cff_done_blend( CFF_Face  face );
+#endif
+
 
 FT_END_HEADER
 
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 0f07696..a639350 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType objects manager (body).                                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -114,7 +114,7 @@
     FT_UInt      n, count;
 
 
-    FT_MEM_ZERO( priv, sizeof ( *priv ) );
+    FT_ZERO( priv );
 
     count = priv->num_blue_values = cpriv->num_blue_values;
     for ( n = 0; n < count; n++ )
@@ -450,7 +450,7 @@
       FT_Int  idx;
 
 
-      for ( idx = 1; idx <= style_name_length; ++idx )
+      for ( idx = 1; idx <= style_name_length; idx++ )
       {
         if ( family_name[family_name_length - idx] !=
              style_name[style_name_length - idx] )
@@ -469,7 +469,7 @@
                   family_name[idx] == ' ' ||
                   family_name[idx] == '_' ||
                   family_name[idx] == '+' ) )
-          --idx;
+          idx--;
 
         if ( idx > 0 )
           family_name[idx + 1] = '\0';
@@ -491,6 +491,7 @@
     FT_Service_PsCMaps  psnames;
     PSHinter_Service    pshinter;
     FT_Bool             pure_cff    = 1;
+    FT_Bool             cff2        = 0;
     FT_Bool             sfnt_format = 0;
     FT_Library          library     = cffface->driver->root.library;
 
@@ -516,6 +517,7 @@
       goto Exit;
 
     /* check whether we have a valid OpenType file */
+    FT_TRACE2(( "  " ));
     error = sfnt->init_face( stream, face, face_index, num_params, params );
     if ( !error )
     {
@@ -553,8 +555,18 @@
           goto Exit;
       }
 
-      /* now load the CFF part of the file */
-      error = face->goto_table( face, TTAG_CFF, stream, 0 );
+      /* now load the CFF part of the file; */
+      /* give priority to CFF2              */
+      error = face->goto_table( face, TTAG_CFF2, stream, 0 );
+      if ( !error )
+      {
+        cff2         = 1;
+        face->isCFF2 = cff2;
+      }
+
+      if ( FT_ERR_EQ( error, Table_Missing ) )
+        error = face->goto_table( face, TTAG_CFF, stream, 0 );
+
       if ( error )
         goto Exit;
     }
@@ -579,7 +591,12 @@
         goto Exit;
 
       face->extra.data = cff;
-      error = cff_font_load( library, stream, face_index, cff, pure_cff );
+      error = cff_font_load( library,
+                             stream,
+                             face_index,
+                             cff,
+                             pure_cff,
+                             cff2 );
       if ( error )
         goto Exit;
 
@@ -667,6 +684,62 @@
       }
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
+
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
+    {
+      FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+
+      FT_Int  instance_index = face_index >> 16;
+
+
+      if ( FT_HAS_MULTIPLE_MASTERS( cffface ) &&
+           mm                                 &&
+           instance_index > 0                 )
+      {
+        FT_MM_Var*  mm_var;
+
+
+        error = mm->get_mm_var( cffface, NULL );
+        if ( error )
+          goto Exit;
+
+        mm->get_var_blend( cffface, NULL, NULL, &mm_var );
+
+        if ( mm_var->namedstyle )
+        {
+          FT_Var_Named_Style*  named_style;
+          FT_String*           style_name;
+
+
+          /* in `face_index', the instance index starts with value 1 */
+          named_style = mm_var->namedstyle + instance_index - 1;
+          error = sfnt->get_name( face,
+                                  (FT_UShort)named_style->strid,
+                                  &style_name );
+          if ( error )
+            goto Exit;
+
+          /* set style name; if already set, replace it */
+          if ( face->root.style_name )
+            FT_FREE( face->root.style_name );
+          face->root.style_name = style_name;
+
+          /* finally, select the named instance */
+          error = mm->set_var_design( cffface,
+                                      mm_var->num_axis,
+                                      named_style->coords );
+          if ( error )
+            goto Exit;
+        }
+      }
+    }
+
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
+
+
+
       if ( !dict->has_font_matrix )
         dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
 
@@ -1011,7 +1084,7 @@
         error = FT_Err_Ok;
 
         /* if no Unicode charmap was previously selected, select this one */
-        if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
+        if ( !cffface->charmap && nn != (FT_UInt)cffface->num_charmaps )
           cffface->charmap = cffface->charmaps[nn];
 
       Skip_Unicode:
@@ -1079,6 +1152,11 @@
         FT_FREE( face->extra.data );
       }
     }
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    cff_done_blend( face );
+    face->blend = NULL;
+#endif
   }
 
 
diff --git a/src/cff/cffobjs.h b/src/cff/cffobjs.h
index 9dc7753..5d26977 100644
--- a/src/cff/cffobjs.h
+++ b/src/cff/cffobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType objects manager (specification).                            */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index a4f986b..59fa290 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token stream parser (body)                                       */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -24,6 +24,7 @@
 #include "cfferrs.h"
 #include "cffpic.h"
 #include "cffgload.h"
+#include "cffload.h"
 
 
   /*************************************************************************/
@@ -36,22 +37,52 @@
 #define FT_COMPONENT  trace_cffparse
 
 
-  FT_LOCAL_DEF( void )
+  FT_LOCAL_DEF( FT_Error )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
                    void*       object,
                    FT_Library  library,
+                   FT_UInt     stackSize,
                    FT_UShort   num_designs,
                    FT_UShort   num_axes )
   {
-    FT_MEM_ZERO( parser, sizeof ( *parser ) );
+    FT_Memory  memory = library->memory;    /* for FT_NEW_ARRAY */
+    FT_Error   error;                       /* for FT_NEW_ARRAY */
 
+
+    FT_ZERO( parser );
+
+#if 0
     parser->top         = parser->stack;
+#endif
     parser->object_code = code;
     parser->object      = object;
     parser->library     = library;
     parser->num_designs = num_designs;
     parser->num_axes    = num_axes;
+
+    /* allocate the stack buffer */
+    if ( FT_NEW_ARRAY( parser->stack, stackSize ) )
+    {
+      FT_FREE( parser->stack );
+      goto Exit;
+    }
+
+    parser->stackSize = stackSize;
+    parser->top       = parser->stack;    /* empty stack */
+
+  Exit:
+    return error;
+  }
+
+
+  FT_LOCAL_DEF( void )
+  cff_parser_done( CFF_Parser  parser )
+  {
+    FT_Memory  memory = parser->library->memory;    /* for FT_FREE */
+
+
+    FT_FREE( parser->stack );
   }
 
 
@@ -402,24 +433,54 @@
 
 
   /* read a number, either integer or real */
-  static FT_Long
-  cff_parse_num( FT_Byte**  d )
+  FT_LOCAL_DEF( FT_Long )
+  cff_parse_num( CFF_Parser  parser,
+                 FT_Byte**   d )
   {
-    return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 )
-                     :   cff_parse_integer( d[0], d[1] );
+    if ( **d == 30 )
+    {
+      /* binary-coded decimal is truncated to integer */
+      return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
+    }
+
+    else if ( **d == 255 )
+    {
+      /* 16.16 fixed point is used internally for CFF2 blend results. */
+      /* Since these are trusted values, a limit check is not needed. */
+
+      /* After the 255, 4 bytes give the number.                 */
+      /* The blend value is converted to integer, with rounding; */
+      /* due to the right-shift we don't need the lowest byte.   */
+#if 0
+      return (FT_Short)(
+               ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) |
+                   ( (FT_UInt32)*( d[0] + 2 ) << 16 ) |
+                   ( (FT_UInt32)*( d[0] + 3 ) <<  8 ) |
+                     (FT_UInt32)*( d[0] + 4 )         ) + 0x8000U ) >> 16 );
+#else
+      return (FT_Short)(
+               ( ( ( (FT_UInt32)*( d[0] + 1 ) << 16 ) |
+                   ( (FT_UInt32)*( d[0] + 2 ) <<  8 ) |
+                     (FT_UInt32)*( d[0] + 3 )         ) + 0x80U ) >> 8 );
+#endif
+    }
+
+    else
+      return cff_parse_integer( *d, parser->limit );
   }
 
 
   /* read a floating point number, either integer or real */
   static FT_Fixed
-  do_fixed( FT_Byte**  d,
-            FT_Long    scaling )
+  do_fixed( CFF_Parser  parser,
+            FT_Byte**   d,
+            FT_Long     scaling )
   {
     if ( **d == 30 )
-      return cff_parse_real( d[0], d[1], scaling, NULL );
+      return cff_parse_real( *d, parser->limit, scaling, NULL );
     else
     {
-      FT_Long  val = cff_parse_integer( d[0], d[1] );
+      FT_Long  val = cff_parse_integer( *d, parser->limit );
 
 
       if ( scaling )
@@ -447,19 +508,21 @@
 
   /* read a floating point number, either integer or real */
   static FT_Fixed
-  cff_parse_fixed( FT_Byte**  d )
+  cff_parse_fixed( CFF_Parser  parser,
+                   FT_Byte**   d )
   {
-    return do_fixed( d, 0 );
+    return do_fixed( parser, d, 0 );
   }
 
 
   /* read a floating point number, either integer or real, */
   /* but return `10^scaling' times the number read in      */
   static FT_Fixed
-  cff_parse_fixed_scaled( FT_Byte**  d,
-                          FT_Long    scaling )
+  cff_parse_fixed_scaled( CFF_Parser  parser,
+                          FT_Byte**   d,
+                          FT_Long     scaling )
   {
-    return do_fixed( d, scaling );
+    return do_fixed( parser, d, scaling );
   }
 
 
@@ -467,13 +530,14 @@
   /* and return it as precise as possible -- `scaling' returns */
   /* the scaling factor (as a power of 10)                     */
   static FT_Fixed
-  cff_parse_fixed_dynamic( FT_Byte**  d,
-                           FT_Long*   scaling )
+  cff_parse_fixed_dynamic( CFF_Parser  parser,
+                           FT_Byte**   d,
+                           FT_Long*    scaling )
   {
     FT_ASSERT( scaling );
 
     if ( **d == 30 )
-      return cff_parse_real( d[0], d[1], 0, scaling );
+      return cff_parse_real( *d, parser->limit, 0, scaling );
     else
     {
       FT_Long  number;
@@ -543,7 +607,7 @@
 
       for ( i = 0; i < 6; i++ )
       {
-        values[i] = cff_parse_fixed_dynamic( data++, &scalings[i] );
+        values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] );
         if ( values[i] )
         {
           if ( scalings[i] > max_scaling )
@@ -640,10 +704,10 @@
 
     if ( parser->top >= parser->stack + 4 )
     {
-      bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) );
-      bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) );
-      bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) );
-      bbox->yMax = FT_RoundFix( cff_parse_fixed( data   ) );
+      bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
+      bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
+      bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) );
+      bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data   ) );
       error = FT_Err_Ok;
 
       FT_TRACE4(( " [%d %d %d %d]\n",
@@ -672,7 +736,7 @@
       FT_Long  tmp;
 
 
-      tmp = cff_parse_num( data++ );
+      tmp = cff_parse_num( parser, data++ );
       if ( tmp < 0 )
       {
         FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" ));
@@ -681,7 +745,7 @@
       }
       dict->private_size = (FT_ULong)tmp;
 
-      tmp = cff_parse_num( data );
+      tmp = cff_parse_num( parser, data );
       if ( tmp < 0 )
       {
         FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" ));
@@ -726,7 +790,7 @@
     /* currently, we handle only the first argument */
     if ( parser->top >= parser->stack + 5 )
     {
-      FT_Long  num_designs = cff_parse_num( parser->stack );
+      FT_Long  num_designs = cff_parse_num( parser, parser->stack );
 
 
       if ( num_designs > 16 || num_designs < 2 )
@@ -763,11 +827,11 @@
 
     if ( parser->top >= parser->stack + 3 )
     {
-      dict->cid_registry = (FT_UInt)cff_parse_num( data++ );
-      dict->cid_ordering = (FT_UInt)cff_parse_num( data++ );
+      dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ );
+      dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ );
       if ( **data == 30 )
         FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" ));
-      dict->cid_supplement = cff_parse_num( data );
+      dict->cid_supplement = cff_parse_num( parser, data );
       if ( dict->cid_supplement < 0 )
         FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n",
                    dict->cid_supplement ));
@@ -783,6 +847,125 @@
   }
 
 
+  static FT_Error
+  cff_parse_vsindex( CFF_Parser  parser )
+  {
+    /* vsindex operator can only be used in a Private DICT */
+    CFF_Private  priv = (CFF_Private)parser->object;
+    FT_Byte**    data = parser->stack;
+    CFF_Blend    blend;
+    FT_Error     error;
+
+
+    if ( !priv || !priv->subfont )
+    {
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    blend = &priv->subfont->blend;
+
+    if ( blend->usedBV )
+    {
+      FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" ));
+      error = FT_THROW( Syntax_Error );
+      goto Exit;
+    }
+
+    priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ );
+
+    FT_TRACE4(( " %d\n", priv->vsindex ));
+
+    error = FT_Err_Ok;
+
+  Exit:
+    return error;
+  }
+
+
+  static FT_Error
+  cff_parse_blend( CFF_Parser  parser )
+  {
+    /* blend operator can only be used in a Private DICT */
+    CFF_Private  priv = (CFF_Private)parser->object;
+    CFF_SubFont  subFont;
+    CFF_Blend    blend;
+    FT_UInt      numBlends;
+    FT_Error     error;
+
+
+    error = FT_ERR( Stack_Underflow );
+
+    if ( !priv || !priv->subfont )
+    {
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    subFont = priv->subfont;
+    blend   = &subFont->blend;
+
+    if ( cff_blend_check_vector( blend,
+                                 priv->vsindex,
+                                 subFont->lenNDV,
+                                 subFont->NDV ) )
+    {
+      error = cff_blend_build_vector( blend,
+                                      priv->vsindex,
+                                      subFont->lenNDV,
+                                      subFont->NDV );
+      if ( error )
+        goto Exit;
+    }
+
+    numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 );
+    if ( numBlends > parser->stackSize )
+    {
+      FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    FT_TRACE4(( "   %d values blended\n", numBlends ));
+
+    error = cff_blend_doBlend( subFont, parser, numBlends );
+
+    blend->usedBV = TRUE;
+
+  Exit:
+    return error;
+  }
+
+
+  /* maxstack operator increases parser and operand stacks for CFF2 */
+  static FT_Error
+  cff_parse_maxstack( CFF_Parser  parser )
+  {
+    /* maxstack operator can only be used in a Top DICT */
+    CFF_FontRecDict  dict  = (CFF_FontRecDict)parser->object;
+    FT_Byte**        data  = parser->stack;
+    FT_Error         error = FT_Err_Ok;
+
+
+    if ( !dict )
+    {
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ );
+    if ( dict->maxstack > CFF2_MAX_STACK )
+      dict->maxstack = CFF2_MAX_STACK;
+    if ( dict->maxstack < CFF2_DEFAULT_STACK )
+      dict->maxstack = CFF2_DEFAULT_STACK;
+
+    FT_TRACE4(( " %d\n", dict->maxstack ));
+
+  Exit:
+    return error;
+  }
+
+
 #define CFF_FIELD_NUM( code, name, id )             \
           CFF_FIELD( code, name, id, cff_kind_num )
 #define CFF_FIELD_FIXED( code, name, id )             \
@@ -794,9 +977,6 @@
 #define CFF_FIELD_BOOL( code, name, id )             \
           CFF_FIELD( code, name, id, cff_kind_bool )
 
-#define CFFCODE_TOPDICT  0x1000
-#define CFFCODE_PRIVATE  0x2000
-
 
 #ifndef FT_CONFIG_OPTION_PIC
 
@@ -817,6 +997,15 @@
             0, 0                             \
           },
 
+#define CFF_FIELD_BLEND( code, id ) \
+          {                         \
+            cff_kind_blend,         \
+            code | CFFCODE,         \
+            0, 0,                   \
+            cff_parse_blend,        \
+            0, 0                    \
+          },
+
 #define CFF_FIELD( code, name, id, kind ) \
           {                               \
             kind,                         \
@@ -860,6 +1049,16 @@
             id                               \
           },
 
+#define CFF_FIELD_BLEND( code, id ) \
+          {                         \
+            cff_kind_blend,         \
+            code | CFFCODE,         \
+            0, 0,                   \
+            cff_parse_blend,        \
+            0, 0,                   \
+            id                      \
+          },
+
 #define CFF_FIELD( code, name, id, kind ) \
           {                               \
             kind,                         \
@@ -926,6 +1125,8 @@
 #define CFF_FIELD_DELTA( code, name, max, id ) i++;
 #undef CFF_FIELD_CALLBACK
 #define CFF_FIELD_CALLBACK( code, name, id ) i++;
+#undef CFF_FIELD_BLEND
+#define CFF_FIELD_BLEND( code, id ) i++;
 
 #include "cfftoken.h"
 
@@ -973,6 +1174,17 @@
           clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \
           i++;
 
+#undef  CFF_FIELD_BLEND
+#define CFF_FIELD_BLEND( code_, id_ )              \
+          clazz[i].kind         = cff_kind_blend;  \
+          clazz[i].code         = code_ | CFFCODE; \
+          clazz[i].offset       = 0;               \
+          clazz[i].size         = 0;               \
+          clazz[i].reader       = cff_parse_blend; \
+          clazz[i].array_max    = 0;               \
+          clazz[i].count_offset = 0;               \
+          i++;
+
 #include "cfftoken.h"
 
     clazz[i].kind         = 0;
@@ -1023,6 +1235,18 @@
           clazz[i].id           = id_;                              \
           i++;
 
+#undef  CFF_FIELD_BLEND
+#define CFF_FIELD_BLEND( code_, id_ )              \
+          clazz[i].kind         = cff_kind_blend;  \
+          clazz[i].code         = code_ | CFFCODE; \
+          clazz[i].offset       = 0;               \
+          clazz[i].size         = 0;               \
+          clazz[i].reader       = cff_parse_blend; \
+          clazz[i].array_max    = 0;               \
+          clazz[i].count_offset = 0;               \
+          clazz[i].id           = id_;             \
+          i++;
+
 #include "cfftoken.h"
 
     clazz[i].kind         = 0;
@@ -1067,11 +1291,13 @@
     {
       FT_UInt  v = *p;
 
-
-      if ( v >= 27 && v != 31 )
+      /* Opcode 31 is legacy MM T2 operator, not a number.      */
+      /* Opcode 255 is reserved and should not appear in fonts; */
+      /* it is used internally for CFF2 blends.                 */
+      if ( v >= 27 && v != 31 && v != 255 )
       {
         /* it's a number; we will push its position on the stack */
-        if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
+        if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
           goto Stack_Overflow;
 
         *parser->top++ = p;
@@ -1132,8 +1358,8 @@
         charstring_len = (FT_ULong)( p - charstring_base ) + 1;
 
         /* construct CFF_Decoder object */
-        FT_MEM_ZERO( &decoder, sizeof ( decoder ) );
-        FT_MEM_ZERO( &cff_rec, sizeof ( cff_rec ) );
+        FT_ZERO( &decoder );
+        FT_ZERO( &cff_rec );
 
         cff_rec.top_font.font_dict.num_designs = parser->num_designs;
         cff_rec.top_font.font_dict.num_axes    = parser->num_axes;
@@ -1162,7 +1388,7 @@
           FT_Bool   neg;
 
 
-          if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
+          if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
             goto Stack_Overflow;
 
           *parser->top++ = q;
@@ -1239,13 +1465,17 @@
         /* and look for it in our current list.                            */
 
         FT_UInt                   code;
-        FT_UInt                   num_args = (FT_UInt)
-                                             ( parser->top - parser->stack );
+        FT_UInt                   num_args;
         const CFF_Field_Handler*  field;
 
 
+        if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
+          goto Stack_Overflow;
+
+        num_args     = (FT_UInt)( parser->top - parser->stack );
         *parser->top = p;
-        code = v;
+        code         = v;
+
         if ( v == 12 )
         {
           /* two byte operator */
@@ -1280,15 +1510,15 @@
             case cff_kind_bool:
             case cff_kind_string:
             case cff_kind_num:
-              val = cff_parse_num( parser->stack );
+              val = cff_parse_num( parser, parser->stack );
               goto Store_Number;
 
             case cff_kind_fixed:
-              val = cff_parse_fixed( parser->stack );
+              val = cff_parse_fixed( parser, parser->stack );
               goto Store_Number;
 
             case cff_kind_fixed_thousand:
-              val = cff_parse_fixed_scaled( parser->stack, 3 );
+              val = cff_parse_fixed_scaled( parser, parser->stack, 3 );
 
             Store_Number:
               switch ( field->size )
@@ -1357,7 +1587,7 @@
                 val = 0;
                 while ( num_args > 0 )
                 {
-                  val += cff_parse_num( data++ );
+                  val += cff_parse_num( parser, data++ );
                   switch ( field->size )
                   {
                   case (8 / FT_CHAR_BIT):
@@ -1386,7 +1616,7 @@
               }
               break;
 
-            default:  /* callback */
+            default:  /* callback or blend */
               error = field->reader( parser );
               if ( error )
                 goto Exit;
@@ -1400,7 +1630,10 @@
 
       Found:
         /* clear stack */
-        parser->top = parser->stack;
+        /* TODO: could clear blend stack here,       */
+        /*       but we don't have access to subFont */
+        if ( field->kind != cff_kind_blend )
+          parser->top = parser->stack;
       }
       p++;
     }
diff --git a/src/cff/cffparse.h b/src/cff/cffparse.h
index a95970e..9976d42 100644
--- a/src/cff/cffparse.h
+++ b/src/cff/cffparse.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token stream parser (specification)                              */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -28,10 +28,17 @@
 FT_BEGIN_HEADER
 
 
+  /* CFF uses constant parser stack size; */
+  /* CFF2 can increase from default 193   */
 #define CFF_MAX_STACK_DEPTH  96
+#define CFF2_MAX_STACK      513
+#define CFF2_DEFAULT_STACK  193
 
-#define CFF_CODE_TOPDICT  0x1000
-#define CFF_CODE_PRIVATE  0x2000
+#define CFF_CODE_TOPDICT    0x1000
+#define CFF_CODE_PRIVATE    0x2000
+#define CFF2_CODE_TOPDICT   0x3000
+#define CFF2_CODE_FONTDICT  0x4000
+#define CFF2_CODE_PRIVATE   0x5000
 
 
   typedef struct  CFF_ParserRec_
@@ -41,8 +48,9 @@
     FT_Byte*    limit;
     FT_Byte*    cursor;
 
-    FT_Byte*    stack[CFF_MAX_STACK_DEPTH + 1];
+    FT_Byte**   stack;
     FT_Byte**   top;
+    FT_UInt     stackSize;  /* allocated size */
 
     FT_UInt     object_code;
     void*       object;
@@ -53,14 +61,22 @@
   } CFF_ParserRec, *CFF_Parser;
 
 
-  FT_LOCAL( void )
+  FT_LOCAL( FT_Long )
+  cff_parse_num( CFF_Parser  parser,
+                 FT_Byte**   d );
+
+  FT_LOCAL( FT_Error )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
                    void*       object,
                    FT_Library  library,
+                   FT_UInt     stackSize,
                    FT_UShort   num_designs,
                    FT_UShort   num_axes );
 
+  FT_LOCAL( void )
+  cff_parser_done( CFF_Parser  parser );
+
   FT_LOCAL( FT_Error )
   cff_parser_run( CFF_Parser  parser,
                   FT_Byte*    start,
@@ -77,6 +93,7 @@
     cff_kind_bool,
     cff_kind_delta,
     cff_kind_callback,
+    cff_kind_blend,
 
     cff_kind_max  /* do not remove */
   };
diff --git a/src/cff/cffpic.c b/src/cff/cffpic.c
index a0bc34f..4e9ba12 100644
--- a/src/cff/cffpic.c
+++ b/src/cff/cffpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for cff module.      */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/cff/cffpic.h b/src/cff/cffpic.h
index bed6b35..5db39cd 100644
--- a/src/cff/cffpic.h
+++ b/src/cff/cffpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for cff module.      */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -32,6 +32,8 @@
 #define CFF_SERVICE_CID_INFO_GET         cff_service_cid_info
 #define CFF_SERVICE_PROPERTIES_GET       cff_service_properties
 #define CFF_SERVICES_GET                 cff_services
+#define CFF_SERVICE_MULTI_MASTERS_GET    cff_service_multi_masters
+#define CFF_SERVICE_METRICS_VAR_GET      cff_service_metrics_variations
 #define CFF_CMAP_ENCODING_CLASS_REC_GET  cff_cmap_encoding_class_rec
 #define CFF_CMAP_UNICODE_CLASS_REC_GET   cff_cmap_unicode_class_rec
 #define CFF_FIELD_HANDLERS_GET           cff_field_handlers
@@ -45,22 +47,26 @@
 #include FT_SERVICE_TT_CMAP_H
 #include FT_SERVICE_CID_H
 #include FT_SERVICE_PROPERTIES_H
+#include FT_SERVICE_MULTIPLE_MASTERS_H
+#include FT_SERVICE_METRICS_VARIATIONS_H
 
 
 FT_BEGIN_HEADER
 
   typedef struct  CffModulePIC_
   {
-    FT_ServiceDescRec*        cff_services;
-    CFF_Field_Handler*        cff_field_handlers;
-    FT_Service_PsInfoRec      cff_service_ps_info;
-    FT_Service_GlyphDictRec   cff_service_glyph_dict;
-    FT_Service_PsFontNameRec  cff_service_ps_name;
-    FT_Service_TTCMapsRec     cff_service_get_cmap_info;
-    FT_Service_CIDRec         cff_service_cid_info;
-    FT_Service_PropertiesRec  cff_service_properties;
-    FT_CMap_ClassRec          cff_cmap_encoding_class_rec;
-    FT_CMap_ClassRec          cff_cmap_unicode_class_rec;
+    FT_ServiceDescRec*               cff_services;
+    CFF_Field_Handler*               cff_field_handlers;
+    FT_Service_PsInfoRec             cff_service_ps_info;
+    FT_Service_GlyphDictRec          cff_service_glyph_dict;
+    FT_Service_PsFontNameRec         cff_service_ps_name;
+    FT_Service_TTCMapsRec            cff_service_get_cmap_info;
+    FT_Service_CIDRec                cff_service_cid_info;
+    FT_Service_PropertiesRec         cff_service_properties;
+    FT_Service_MultiMastersRec       cff_service_multi_masters;
+    FT_Service_MetricsVariationsRec  cff_service_metrics_variations;
+    FT_CMap_ClassRec                 cff_cmap_encoding_class_rec;
+    FT_CMap_ClassRec                 cff_cmap_unicode_class_rec;
 
   } CffModulePIC;
 
@@ -82,6 +88,10 @@
           ( GET_PIC( library )->cff_service_properties )
 #define CFF_SERVICES_GET                       \
           ( GET_PIC( library )->cff_services )
+#define CFF_SERVICE_MULTI_MASTERS_GET                       \
+          ( GET_PIC( library )->cff_service_multi_masters )
+#define CFF_SERVICE_METRICS_VAR_GET                              \
+          ( GET_PIC( library )->cff_service_metrics_variations )
 #define CFF_CMAP_ENCODING_CLASS_REC_GET                       \
           ( GET_PIC( library )->cff_cmap_encoding_class_rec )
 #define CFF_CMAP_UNICODE_CLASS_REC_GET                       \
diff --git a/src/cff/cfftoken.h b/src/cff/cfftoken.h
index 22637c7..3222e93 100644
--- a/src/cff/cfftoken.h
+++ b/src/cff/cfftoken.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CFF token definitions (specification only).                          */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,7 +20,7 @@
 #define FT_STRUCTURE  CFF_FontRecDictRec
 
 #undef  CFFCODE
-#define CFFCODE       CFFCODE_TOPDICT
+#define CFFCODE       CFF_CODE_TOPDICT
 
   CFF_FIELD_STRING  ( 0,     version,             "Version" )
   CFF_FIELD_STRING  ( 1,     notice,              "Notice" )
@@ -78,7 +78,7 @@
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  CFF_PrivateRec
 #undef  CFFCODE
-#define CFFCODE       CFFCODE_PRIVATE
+#define CFFCODE       CFF_CODE_PRIVATE
 
   CFF_FIELD_DELTA     ( 6,     blue_values, 14,        "BlueValues" )
   CFF_FIELD_DELTA     ( 7,     other_blues, 10,        "OtherBlues" )
@@ -102,4 +102,49 @@
   CFF_FIELD_NUM       ( 21,    nominal_width,          "nominalWidthX" )
 
 
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  CFF_FontRecDictRec
+#undef  CFFCODE
+#define CFFCODE       CFF2_CODE_TOPDICT
+
+  CFF_FIELD_CALLBACK( 0x107, font_matrix,          "FontMatrix" )
+  CFF_FIELD_NUM     ( 17,    charstrings_offset,   "CharStrings" )
+  CFF_FIELD_NUM     ( 0x124, cid_fd_array_offset,  "FDArray" )
+  CFF_FIELD_NUM     ( 0x125, cid_fd_select_offset, "FDSelect" )
+  CFF_FIELD_NUM     ( 24,    vstore_offset,        "vstore" )
+  CFF_FIELD_CALLBACK( 25,    maxstack,             "maxstack" )
+
+
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  CFF_FontRecDictRec
+#undef  CFFCODE
+#define CFFCODE       CFF2_CODE_FONTDICT
+
+  CFF_FIELD_CALLBACK( 18,    private_dict, "Private" )
+  CFF_FIELD_CALLBACK( 0x107, font_matrix,  "FontMatrix" )
+
+
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  CFF_PrivateRec
+#undef  CFFCODE
+#define CFFCODE       CFF2_CODE_PRIVATE
+
+  CFF_FIELD_DELTA     ( 6,     blue_values, 14,        "BlueValues" )
+  CFF_FIELD_DELTA     ( 7,     other_blues, 10,        "OtherBlues" )
+  CFF_FIELD_DELTA     ( 8,     family_blues, 14,       "FamilyBlues" )
+  CFF_FIELD_DELTA     ( 9,     family_other_blues, 10, "FamilyOtherBlues" )
+  CFF_FIELD_FIXED_1000( 0x109, blue_scale,             "BlueScale" )
+  CFF_FIELD_NUM       ( 0x10A, blue_shift,             "BlueShift" )
+  CFF_FIELD_NUM       ( 0x10B, blue_fuzz,              "BlueFuzz" )
+  CFF_FIELD_NUM       ( 10,    standard_width,         "StdHW" )
+  CFF_FIELD_NUM       ( 11,    standard_height,        "StdVW" )
+  CFF_FIELD_DELTA     ( 0x10C, snap_widths, 13,        "StemSnapH" )
+  CFF_FIELD_DELTA     ( 0x10D, snap_heights, 13,       "StemSnapV" )
+  CFF_FIELD_NUM       ( 0x111, language_group,         "LanguageGroup" )
+  CFF_FIELD_FIXED     ( 0x112, expansion_factor,       "ExpansionFactor" )
+  CFF_FIELD_CALLBACK  ( 22,    vsindex,                "vsindex" )
+  CFF_FIELD_BLEND     ( 23,                            "blend" )
+  CFF_FIELD_NUM       ( 19,    local_subrs_offset,     "Subrs" )
+
+
 /* END */
diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h
index 4426c7e..412712c 100644
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -5,7 +5,7 @@
 /*    Basic OpenType/CFF type definitions and interface (specification     */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -64,6 +64,7 @@
   {
     FT_Stream  stream;
     FT_ULong   start;
+    FT_UInt    hdr_size;
     FT_UInt    count;
     FT_Byte    off_size;
     FT_ULong   data_offset;
@@ -102,6 +103,79 @@
   } CFF_CharsetRec, *CFF_Charset;
 
 
+  /* cf. similar fields in file `ttgxvar.h' from the `truetype' module */
+
+  typedef struct  CFF_VarData_
+  {
+#if 0
+    FT_UInt  itemCount;       /* not used; always zero */
+    FT_UInt  shortDeltaCount; /* not used; always zero */
+#endif
+
+    FT_UInt   regionIdxCount; /* number of regions in this var data */
+    FT_UInt*  regionIndices;  /* array of `regionCount' indices;    */
+                              /* these index `varRegionList'        */
+  } CFF_VarData;
+
+
+  /* contribution of one axis to a region */
+  typedef struct  CFF_AxisCoords_
+  {
+    FT_Fixed  startCoord;
+    FT_Fixed  peakCoord;      /* zero peak means no effect (factor = 1) */
+    FT_Fixed  endCoord;
+
+  } CFF_AxisCoords;
+
+
+  typedef struct  CFF_VarRegion_
+  {
+    CFF_AxisCoords*  axisList;      /* array of axisCount records */
+
+  } CFF_VarRegion;
+
+
+  typedef struct  CFF_VStoreRec_
+  {
+    FT_UInt         dataCount;
+    CFF_VarData*    varData;        /* array of dataCount records      */
+                                    /* vsindex indexes this array      */
+    FT_UShort       axisCount;
+    FT_UInt         regionCount;    /* total number of regions defined */
+    CFF_VarRegion*  varRegionList;
+
+  } CFF_VStoreRec, *CFF_VStore;
+
+
+  /* forward reference */
+  typedef struct CFF_FontRec_*  CFF_Font;
+
+
+  /* This object manages one cached blend vector.                  */
+  /*                                                               */
+  /* There is a BlendRec for Private DICT parsing in each subfont  */
+  /* and a BlendRec for charstrings in CF2_Font instance data.     */
+  /* A cached BV may be used across DICTs or Charstrings if inputs */
+  /* have not changed.                                             */
+  /*                                                               */
+  /* `usedBV' is reset at the start of each parse or charstring.   */
+  /* vsindex cannot be changed after a BV is used.                 */
+  /*                                                               */
+  /* Note: NDV is long (32/64 bit), while BV is 16.16 (FT_Int32).  */
+  typedef struct  CFF_BlendRec_
+  {
+    FT_Bool    builtBV;        /* blendV has been built           */
+    FT_Bool    usedBV;         /* blendV has been used            */
+    CFF_Font   font;           /* top level font struct           */
+    FT_UInt    lastVsindex;    /* last vsindex used               */
+    FT_UInt    lenNDV;         /* normDV length (aka numAxes)     */
+    FT_Fixed*  lastNDV;        /* last NDV used                   */
+    FT_UInt    lenBV;          /* BlendV length (aka numMasters)  */
+    FT_Int32*  BV;             /* current blendV (per DICT/glyph) */
+
+  } CFF_BlendRec, *CFF_Blend;
+
+
   typedef struct  CFF_FontRecDictRec_
   {
     FT_UInt    version;
@@ -151,9 +225,17 @@
     FT_UShort  num_designs;
     FT_UShort  num_axes;
 
+    /* fields for CFF2 */
+    FT_ULong   vstore_offset;
+    FT_UInt    maxstack;
+
   } CFF_FontRecDictRec, *CFF_FontRecDict;
 
 
+  /* forward reference */
+  typedef struct CFF_SubFontRec_*  CFF_SubFont;
+
+
   typedef struct  CFF_PrivateRec_
   {
     FT_Byte   num_blue_values;
@@ -186,6 +268,10 @@
     FT_Pos    default_width;
     FT_Pos    nominal_width;
 
+    /* fields for CFF2 */
+    FT_UInt      vsindex;
+    CFF_SubFont  subfont;
+
   } CFF_PrivateRec, *CFF_Private;
 
 
@@ -213,10 +299,29 @@
     CFF_FontRecDictRec  font_dict;
     CFF_PrivateRec      private_dict;
 
-    CFF_IndexRec        local_subrs_index;
-    FT_Byte**           local_subrs; /* array of pointers into Local Subrs INDEX data */
+    /* fields for CFF2 */
+    CFF_BlendRec  blend;      /* current blend vector       */
+    FT_UInt       lenNDV;     /* current length NDV or zero */
+    FT_Fixed*     NDV;        /* ptr to current NDV or NULL */
 
-  } CFF_SubFontRec, *CFF_SubFont;
+    /* `blend_stack' is a writable buffer to hold blend results.          */
+    /* This buffer is to the side of the normal cff parser stack;         */
+    /* `cff_parse_blend' and `cff_blend_doBlend' push blend results here. */
+    /* The normal stack then points to these values instead of the DICT   */
+    /* because all other operators in Private DICT clear the stack.       */
+    /* `blend_stack' could be cleared at each operator other than blend.  */
+    /* Blended values are stored as 5-byte fixed point values.            */
+
+    FT_Byte*  blend_stack;    /* base of stack allocation     */
+    FT_Byte*  blend_top;      /* first empty slot             */
+    FT_UInt   blend_used;     /* number of bytes in use       */
+    FT_UInt   blend_alloc;    /* number of bytes allocated    */
+
+    CFF_IndexRec  local_subrs_index;
+    FT_Byte**     local_subrs; /* array of pointers           */
+                               /* into Local Subrs INDEX data */
+
+  } CFF_SubFontRec;
 
 
 #define CFF_MAX_CID_FONTS  256
@@ -224,16 +329,20 @@
 
   typedef struct  CFF_FontRec_
   {
+    FT_Library       library;
     FT_Stream        stream;
-    FT_Memory        memory;
+    FT_Memory        memory;        /* TODO: take this from stream->memory? */
+    FT_ULong         base_offset;   /* offset to start of CFF */
     FT_UInt          num_faces;
     FT_UInt          num_glyphs;
 
     FT_Byte          version_major;
     FT_Byte          version_minor;
     FT_Byte          header_size;
-    FT_Byte          absolute_offsize;
 
+    FT_UInt          top_dict_length;   /* cff2 only */
+
+    FT_Bool          cff2;
 
     CFF_IndexRec     name_index;
     CFF_IndexRec     top_dict_index;
@@ -280,7 +389,9 @@
     /* since version 2.4.12 */
     FT_Generic       cf2_instance;
 
-  } CFF_FontRec, *CFF_Font;
+    CFF_VStoreRec    vstore;        /* parsed vstore structure */
+
+  } CFF_FontRec;
 
 
 FT_END_HEADER
diff --git a/src/gzip/ftgzip.c b/src/gzip/ftgzip.c
index 9cab80e..c487786 100644
--- a/src/gzip/ftgzip.c
+++ b/src/gzip/ftgzip.c
@@ -8,7 +8,7 @@
 /*  parse compressed PCF fonts, as found with many X11 server              */
 /*  distributions.                                                         */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -51,17 +51,29 @@
 
 #else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */
 
- /* In this case, we include our own modified sources of the ZLib    */
- /* within the "ftgzip" component.  The modifications were necessary */
- /* to #include all files without conflicts, as well as preventing   */
- /* the definition of "extern" functions that may cause linking      */
- /* conflicts when a program is linked with both FreeType and the    */
- /* original ZLib.                                                   */
+  /* In this case, we include our own modified sources of the ZLib  */
+  /* within the `gzip' component.  The modifications were necessary */
+  /* to #include all files without conflicts, as well as preventing */
+  /* the definition of `extern' functions that may cause linking    */
+  /* conflicts when a program is linked with both FreeType and the  */
+  /* original ZLib.                                                 */
 
 #ifndef USE_ZLIB_ZCALLOC
 #define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutil.c */
 #endif
 
+  /* Note that our `zlib.h' includes `ftzconf.h' instead of `zconf.h'; */
+  /* the main reason is that even a global `zlib.h' includes `zconf.h' */
+  /* with                                                              */
+  /*                                                                   */
+  /*   #include "zconf.h"                                              */
+  /*                                                                   */
+  /* instead of the expected                                           */
+  /*                                                                   */
+  /*   #include <zconf.h>                                              */
+  /*                                                                   */
+  /* so that configuration with `FT_CONFIG_OPTION_SYSTEM_ZLIB' might   */
+  /* include the wrong `zconf.h' file, leading to errors.              */
 #include "zlib.h"
 
 #undef  SLOW
@@ -305,7 +317,7 @@
     zstream->next_in  = zip->buffer;
 
     if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK ||
-         zstream->next_in == NULL                     )
+         !zstream->next_in                           )
       error = FT_THROW( Invalid_File_Format );
 
   Exit:
diff --git a/src/gzip/ftzconf.h b/src/gzip/ftzconf.h
new file mode 100644
index 0000000..3abf0ba
--- /dev/null
+++ b/src/gzip/ftzconf.h
@@ -0,0 +1,284 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_         z_deflateInit_
+#  define deflate              z_deflate
+#  define deflateEnd           z_deflateEnd
+#  define inflateInit_         z_inflateInit_
+#  define inflate              z_inflate
+#  define inflateEnd           z_inflateEnd
+#  define deflateInit2_        z_deflateInit2_
+#  define deflateSetDictionary z_deflateSetDictionary
+#  define deflateCopy          z_deflateCopy
+#  define deflateReset         z_deflateReset
+#  define deflateParams        z_deflateParams
+#  define inflateInit2_        z_inflateInit2_
+#  define inflateSetDictionary z_inflateSetDictionary
+#  define inflateSync          z_inflateSync
+#  define inflateSyncPoint     z_inflateSyncPoint
+#  define inflateReset         z_inflateReset
+#  define compress             z_compress
+#  define compress2            z_compress2
+#  define uncompress           z_uncompress
+#  define adler32              z_adler32
+#  define crc32                z_crc32
+#  define get_crc_table        z_get_crc_table
+
+#  define Byte   z_Byte
+#  define uInt   z_uInt
+#  define uLong  z_uLong
+#  define Bytef  z_Bytef
+#  define charf  z_charf
+#  define intf   z_intf
+#  define uIntf  z_uIntf
+#  define uLongf z_uLongf
+#  define voidpf z_voidpf
+#  define voidp  z_voidp
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+#  ifndef __32BIT__
+#    define __32BIT__
+#  endif
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+
+/* WinCE doesn't have errno.h */
+#ifdef _WIN32_WCE
+#  define NO_ERRNO_H
+#endif
+
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(MSDOS) && !defined(__32BIT__)
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
+#  define STDC
+#endif
+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
+#  ifndef STDC
+#    define STDC
+#  endif
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Old Borland C and LCC incorrectly complains about missing returns: */
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
+#  define NEED_DUMMY_RETURN
+#endif
+
+#if defined(__LCC__)
+#  define  NEED_DUMMY_RETURN
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
+   /* MSC small or medium model */
+#  define SMALL_MEDIUM
+#  ifdef _MSC_VER
+#    define FAR _far
+#  else
+#    define FAR far
+#  endif
+#endif
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
+#  ifndef __32BIT__
+#    define SMALL_MEDIUM
+#    define FAR _far
+#  endif
+#endif
+
+/* Compile with -DZLIB_DLL for Windows DLL support */
+#if defined(ZLIB_DLL)
+#  if defined(_WINDOWS) || defined(WINDOWS)
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+#    define ZEXPORT(x)  x WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA(x)  x WINAPIV
+#    else
+#      define ZEXPORTVA(x)  x FAR _cdecl _export
+#    endif
+#  endif
+#  if defined (__BORLANDC__)
+#    if (__BORLANDC__ >= 0x0500) && defined (WIN32)
+#      include <windows.h>
+#      define ZEXPORT(x) x __declspec(dllexport) WINAPI
+#      define ZEXPORTRVA(x)  x __declspec(dllexport) WINAPIV
+#    else
+#      if defined (_Windows) && defined (__DLL__)
+#        define ZEXPORT(x) x _export
+#        define ZEXPORTVA(x) x _export
+#      endif
+#    endif
+#  endif
+#endif
+
+
+#ifndef ZEXPORT
+#  define ZEXPORT(x)   static x
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA(x)   static x
+#endif
+#ifndef ZEXTERN
+#  define ZEXTERN(x) static x
+#endif
+#ifndef ZEXTERNDEF
+#  define ZEXTERNDEF(x)  static x
+#endif
+
+#ifndef FAR
+#   define FAR
+#endif
+
+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void FAR *voidpf;
+   typedef void     *voidp;
+#else
+   typedef Byte FAR *voidpf;
+   typedef Byte     *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  define z_off_t  off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define  z_off_t long
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(inflate_blocks,"INBL")
+#   pragma map(inflate_blocks_new,"INBLNE")
+#   pragma map(inflate_blocks_free,"INBLFR")
+#   pragma map(inflate_blocks_reset,"INBLRE")
+#   pragma map(inflate_codes_free,"INCOFR")
+#   pragma map(inflate_codes,"INCO")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_flush,"INFLU")
+#   pragma map(inflate_mask,"INMA")
+#   pragma map(inflate_set_dictionary,"INSEDI2")
+#   pragma map(inflate_copyright,"INCOPY")
+#   pragma map(inflate_trees_bits,"INTRBI")
+#   pragma map(inflate_trees_dynamic,"INTRDY")
+#   pragma map(inflate_trees_fixed,"INTRFI")
+#   pragma map(inflate_trees_free,"INTRFR")
+#endif
+
+#endif /* _ZCONF_H */
diff --git a/src/gzip/zlib.h b/src/gzip/zlib.h
index d361ff4..a4e82c6 100644
--- a/src/gzip/zlib.h
+++ b/src/gzip/zlib.h
@@ -31,7 +31,7 @@
 #ifndef _ZLIB_H
 #define _ZLIB_H
 
-#include "zconf.h"
+#include "ftzconf.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c
index 8f131be..9ad1a3a 100644
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinting algorithm (body).                                 */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
@@ -898,7 +898,7 @@
   static void
   psh_print_zone( PSH_Zone  zone )
   {
-    printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n",
+    printf( "zone [scale,delta,min,max] = [%.5f,%.2f,%d,%d]\n",
              zone->scale / 65536.0,
              zone->delta / 64.0,
              zone->min,
@@ -1162,7 +1162,7 @@
 
 
     /* clear all fields */
-    FT_MEM_ZERO( glyph, sizeof ( *glyph ) );
+    FT_ZERO( glyph );
 
     memory = glyph->memory = globals->memory;
 
@@ -1531,7 +1531,7 @@
           }
         }
 
-        if ( point->hint == NULL )
+        if ( !point->hint )
         {
           for ( nn = 0; nn < num_hints; nn++ )
           {
@@ -1572,8 +1572,8 @@
     PS_Mask         mask      = table->hint_masks->masks;
     FT_UInt         num_masks = table->hint_masks->num_masks;
     FT_UInt         first     = 0;
-    FT_Int          major_dir = dimension == 0 ? PSH_DIR_VERTICAL
-                                               : PSH_DIR_HORIZONTAL;
+    FT_Int          major_dir = ( dimension == 0 ) ? PSH_DIR_VERTICAL
+                                                   : PSH_DIR_HORIZONTAL;
     PSH_Dimension   dim       = &glyph->globals->dimension[dimension];
     FT_Fixed        scale     = dim->scale_mult;
     FT_Int          threshold;
diff --git a/src/pshinter/pshalgo.h b/src/pshinter/pshalgo.h
index f1bda65..62e97d1 100644
--- a/src/pshinter/pshalgo.h
+++ b/src/pshinter/pshalgo.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinting algorithm (specification).                        */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshglob.c b/src/pshinter/pshglob.c
index 2ac5ef1..c68770c 100644
--- a/src/pshinter/pshglob.c
+++ b/src/pshinter/pshglob.c
@@ -5,7 +5,7 @@
 /*    PostScript hinter global hinting management (body).                  */
 /*    Inspired by the new auto-hinter module.                              */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
diff --git a/src/pshinter/pshglob.h b/src/pshinter/pshglob.h
index 45c957b..8801cba 100644
--- a/src/pshinter/pshglob.h
+++ b/src/pshinter/pshglob.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinter global hinting management.                         */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshinter.c b/src/pshinter/pshinter.c
index 614e0bb..e6727ae 100644
--- a/src/pshinter/pshinter.c
+++ b/src/pshinter/pshinter.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript Hinting module                                   */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshmod.c b/src/pshinter/pshmod.c
index fa4ad1f..860dc0a 100644
--- a/src/pshinter/pshmod.c
+++ b/src/pshinter/pshmod.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript hinter module implementation (body).             */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -95,9 +95,11 @@
 
   FT_DEFINE_PSHINTER_INTERFACE(
     pshinter_interface,
+
     pshinter_get_globals_funcs,
     pshinter_get_t1_funcs,
-    pshinter_get_t2_funcs )
+    pshinter_get_t2_funcs
+  )
 
 
   FT_DEFINE_MODULE(
@@ -111,9 +113,9 @@
 
     &PSHINTER_INTERFACE_GET,              /* module-specific interface */
 
-    (FT_Module_Constructor)ps_hinter_init,
-    (FT_Module_Destructor) ps_hinter_done,
-    (FT_Module_Requester)  NULL )   /* no additional interface for now */
-
+    (FT_Module_Constructor)ps_hinter_init,  /* module_init   */
+    (FT_Module_Destructor) ps_hinter_done,  /* module_done   */
+    (FT_Module_Requester)  NULL             /* get_interface */
+  )
 
 /* END */
diff --git a/src/pshinter/pshmod.h b/src/pshinter/pshmod.h
index 39112a9..1d2b40f 100644
--- a/src/pshinter/pshmod.h
+++ b/src/pshinter/pshmod.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript hinter module interface (specification).                  */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshnterr.h b/src/pshinter/pshnterr.h
index 7a94588..73d144e 100644
--- a/src/pshinter/pshnterr.h
+++ b/src/pshinter/pshnterr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PS Hinter error codes (specification only).                          */
 /*                                                                         */
-/*  Copyright 2003-2016 by                                                 */
+/*  Copyright 2003-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshpic.c b/src/pshinter/pshpic.c
index d0a3d8e..c0d3a64 100644
--- a/src/pshinter/pshpic.c
+++ b/src/pshinter/pshpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for pshinter module. */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshpic.h b/src/pshinter/pshpic.h
index 75ee573..8d9a01c 100644
--- a/src/pshinter/pshpic.h
+++ b/src/pshinter/pshpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for pshinter module. */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c
index d7cc4a0..fff6d34 100644
--- a/src/pshinter/pshrec.c
+++ b/src/pshinter/pshrec.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PostScript hints recorder (body).                           */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -818,7 +818,7 @@
   ps_hints_init( PS_Hints   hints,
                  FT_Memory  memory )
   {
-    FT_MEM_ZERO( hints, sizeof ( *hints ) );
+    FT_ZERO( hints );
     hints->memory = memory;
   }
 
@@ -1140,7 +1140,7 @@
   FT_LOCAL_DEF( void )
   t1_hints_funcs_init( T1_Hints_FuncsRec*  funcs )
   {
-    FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) );
+    FT_ZERO( funcs );
 
     funcs->open  = (T1_Hints_OpenFunc)    t1_hints_open;
     funcs->close = (T1_Hints_CloseFunc)   ps_hints_close;
@@ -1206,7 +1206,7 @@
   FT_LOCAL_DEF( void )
   t2_hints_funcs_init( T2_Hints_FuncsRec*  funcs )
   {
-    FT_MEM_ZERO( funcs, sizeof ( *funcs ) );
+    FT_ZERO( funcs );
 
     funcs->open    = (T2_Hints_OpenFunc)   t2_hints_open;
     funcs->close   = (T2_Hints_CloseFunc)  ps_hints_close;
diff --git a/src/pshinter/pshrec.h b/src/pshinter/pshrec.h
index 97e6f0e..e10bc2b 100644
--- a/src/pshinter/pshrec.h
+++ b/src/pshinter/pshrec.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Postscript (Type1/Type2) hints recorder (specification).             */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c
index 345402d..3ff8cb9 100644
--- a/src/psnames/psmodule.c
+++ b/src/psnames/psmodule.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PSNames module implementation (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -22,6 +22,9 @@
 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
 
 #include "psmodule.h"
+
+#include "pstables.h"
+#define  DEFINE_PS_TABLES
 #include "pstables.h"
 
 #include "psnamerr.h"
@@ -525,6 +528,7 @@
 
   FT_DEFINE_SERVICE_PSCMAPSREC(
     pscmaps_interface,
+
     (PS_Unicode_ValueFunc)     ps_unicode_value,        /* unicode_value         */
     (PS_Unicodes_InitFunc)     ps_unicodes_init,        /* unicodes_init         */
     (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,  /* unicodes_char_index   */
@@ -534,12 +538,14 @@
     (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */
 
     t1_standard_encoding,                               /* adobe_std_encoding    */
-    t1_expert_encoding )                                /* adobe_expert_encoding */
+    t1_expert_encoding                                  /* adobe_expert_encoding */
+  )
 
 #else
 
   FT_DEFINE_SERVICE_PSCMAPSREC(
     pscmaps_interface,
+
     NULL,                                               /* unicode_value         */
     NULL,                                               /* unicodes_init         */
     NULL,                                               /* unicodes_char_index   */
@@ -549,13 +555,15 @@
     (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */
 
     t1_standard_encoding,                               /* adobe_std_encoding    */
-    t1_expert_encoding )                                /* adobe_expert_encoding */
+    t1_expert_encoding                                  /* adobe_expert_encoding */
+  )
 
 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
 
 
   FT_DEFINE_SERVICEDESCREC1(
     pscmaps_services,
+
     FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET )
 
 
@@ -601,9 +609,11 @@
 
     PUT_PS_NAMES_SERVICE(
       (void*)&PSCMAPS_INTERFACE_GET ),   /* module specific interface */
-    (FT_Module_Constructor)NULL,
-    (FT_Module_Destructor) NULL,
-    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE( psnames_get_service ) )
+
+    (FT_Module_Constructor)NULL,                                       /* module_init   */
+    (FT_Module_Destructor) NULL,                                       /* module_done   */
+    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE( psnames_get_service ) /* get_interface */
+  )
 
 
 /* END */
diff --git a/src/psnames/psmodule.h b/src/psnames/psmodule.h
index ee3c6cb..6983b79 100644
--- a/src/psnames/psmodule.h
+++ b/src/psnames/psmodule.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level PSNames module interface (specification).                 */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/psnamerr.h b/src/psnames/psnamerr.h
index 3a9f653..f90bf5e 100644
--- a/src/psnames/psnamerr.h
+++ b/src/psnames/psnamerr.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PS names module error codes (specification only).                    */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/psnames.c b/src/psnames/psnames.c
index e7b2c0b..5b7bc8b 100644
--- a/src/psnames/psnames.c
+++ b/src/psnames/psnames.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType PSNames module component (body only).                       */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/pspic.c b/src/psnames/pspic.c
index a78ec5a..8b90034 100644
--- a/src/psnames/pspic.c
+++ b/src/psnames/pspic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for psnames module.  */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/pspic.h b/src/psnames/pspic.h
index 4834876..14497e7 100644
--- a/src/psnames/pspic.h
+++ b/src/psnames/pspic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for psnames module.  */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/psnames/pstables.h b/src/psnames/pstables.h
index eb827fa..e0f5e30 100644
--- a/src/psnames/pstables.h
+++ b/src/psnames/pstables.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PostScript glyph names.                                              */
 /*                                                                         */
-/*  Copyright 2005-2016 by                                                 */
+/*  Copyright 2005-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -19,7 +19,16 @@
   /* This file has been generated automatically -- do not edit! */
 
 
-  static const char  ft_standard_glyph_names[3696] =
+#ifndef  DEFINE_PS_TABLES
+#ifdef  __cplusplus
+  extern "C"
+#else
+  extern
+#endif
+#endif
+  const char  ft_standard_glyph_names[3696]
+#ifdef  DEFINE_PS_TABLES
+  =
   {
     '.','n','u','l','l', 0,
     'n','o','n','m','a','r','k','i','n','g','r','e','t','u','r','n', 0,
@@ -441,14 +450,25 @@
     'R','e','g','u','l','a','r', 0,
     'R','o','m','a','n', 0,
     'S','e','m','i','b','o','l','d', 0,
-  };
+  }
+#endif /* DEFINE_PS_TABLES */
+  ;
 
 
 #define FT_NUM_MAC_NAMES  258
 
   /* Values are offsets into the `ft_standard_glyph_names' table */
 
-  static const short  ft_mac_names[FT_NUM_MAC_NAMES] =
+#ifndef  DEFINE_PS_TABLES
+#ifdef  __cplusplus
+  extern "C"
+#else
+  extern
+#endif
+#endif
+  const short  ft_mac_names[FT_NUM_MAC_NAMES]
+#ifdef  DEFINE_PS_TABLES
+  =
   {
      253,   0,   6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351,
      360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430,
@@ -469,14 +489,25 @@
     1066,1073,1101,1143,1536,1783,1596,1843,1253,1207,1319,1579,1826,1229,
     1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200,
      209, 218, 225, 232, 239, 246
-  };
+  }
+#endif /* DEFINE_PS_TABLES */
+  ;
 
 
 #define FT_NUM_SID_NAMES  391
 
   /* Values are offsets into the `ft_standard_glyph_names' table */
 
-  static const short  ft_sid_names[FT_NUM_SID_NAMES] =
+#ifndef  DEFINE_PS_TABLES
+#ifdef  __cplusplus
+  extern "C"
+#else
+  extern
+#endif
+#endif
+  const short  ft_sid_names[FT_NUM_SID_NAMES]
+#ifdef  DEFINE_PS_TABLES
+  =
   {
      253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365,
      371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, 436, 441,
@@ -506,11 +537,22 @@
     3237,3249,3264,3275,3283,3297,3309,3321,3338,3353,3365,3377,3394,3409,
     3418,3430,3442,3454,3471,3483,3498,3506,3518,3530,3542,3559,3574,3586,
     3597,3612,3620,3628,3636,3644,3650,3655,3660,3666,3673,3681,3687
-  };
+  }
+#endif /* DEFINE_PS_TABLES */
+  ;
 
 
   /* the following are indices into the SID name table */
-  static const unsigned short  t1_standard_encoding[256] =
+#ifndef  DEFINE_PS_TABLES
+#ifdef  __cplusplus
+  extern "C"
+#else
+  extern
+#endif
+#endif
+  const unsigned short  t1_standard_encoding[256]
+#ifdef  DEFINE_PS_TABLES
+  =
   {
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
@@ -528,11 +570,22 @@
     137,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,138,  0,139,  0,  0,  0,  0,140,141,142,143,  0,  0,  0,  0,
       0,144,  0,  0,  0,145,  0,  0,146,147,148,149,  0,  0,  0,  0
-  };
+  }
+#endif /* DEFINE_PS_TABLES */
+  ;
 
 
   /* the following are indices into the SID name table */
-  static const unsigned short  t1_expert_encoding[256] =
+#ifndef  DEFINE_PS_TABLES
+#ifdef  __cplusplus
+  extern "C"
+#else
+  extern
+#endif
+#endif
+  const unsigned short  t1_expert_encoding[256]
+#ifdef  DEFINE_PS_TABLES
+  =
   {
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
@@ -550,7 +603,9 @@
     331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,
     347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,
     363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378
-  };
+  }
+#endif /* DEFINE_PS_TABLES */
+  ;
 
 
   /*
@@ -564,7 +619,16 @@
 
 #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
 
-  static const unsigned char  ft_adobe_glyph_list[55997L] =
+#ifndef  DEFINE_PS_TABLES
+#ifdef  __cplusplus
+  extern "C"
+#else
+  extern
+#endif
+#endif
+  const unsigned char  ft_adobe_glyph_list[55997L]
+#ifdef  DEFINE_PS_TABLES
+  =
   {
       0, 52,  0,106,  2,167,  3, 63,  4,220,  6,125,  9,143, 10, 23,
      11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88,
@@ -4066,9 +4130,12 @@
     248,232,239,239,107,128,  2,144,243,244,242,239,235,101,128,  1,
     182,117,  2,218,167,218,178,232,233,242,225,231,225,238, 97,128,
      48, 90,235,225,244,225,235,225,238, 97,128, 48,186
-  };
+  }
+#endif /* DEFINE_PS_TABLES */
+  ;
 
 
+#ifdef  DEFINE_PS_TABLES
   /*
    *  This function searches the compressed table efficiently.
    */
@@ -4163,6 +4230,7 @@
   NotFound:
     return 0;
   }
+#endif /* DEFINE_PS_TABLES */
 
 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
 
diff --git a/src/raster/ftmisc.h b/src/raster/ftmisc.h
index 981ce32..d1e6627 100644
--- a/src/raster/ftmisc.h
+++ b/src/raster/ftmisc.h
@@ -5,7 +5,7 @@
 /*    Miscellaneous macros for stand-alone rasterizer (specification       */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 2005-2016 by                                                 */
+/*  Copyright 2005-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index 0fa2f26..c5643f6 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -251,6 +251,10 @@
 #define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )
 #endif
 
+#ifndef FT_ZERO
+#define FT_ZERO( p )  FT_MEM_ZERO( p, sizeof ( *(p) ) )
+#endif
+
   /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is       */
   /* typically a small value and the result of a*b is known to fit into */
   /* 32 bits.                                                           */
@@ -1516,8 +1520,9 @@
         state_bez = y1 < y3 ? Ascending_State : Descending_State;
         if ( ras.state != state_bez )
         {
-          Bool  o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )
-                                                 : IS_TOP_OVERSHOOT( y1 );
+          Bool  o = ( state_bez == Ascending_State )
+                      ? IS_BOTTOM_OVERSHOOT( y1 )
+                      : IS_TOP_OVERSHOOT( y1 );
 
 
           /* finalize current profile if any */
@@ -1652,8 +1657,9 @@
         /* detect a change of direction */
         if ( ras.state != state_bez )
         {
-          Bool  o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 )
-                                                 : IS_TOP_OVERSHOOT( y1 );
+          Bool  o = ( state_bez == Ascending_State )
+                      ? IS_BOTTOM_OVERSHOOT( y1 )
+                      : IS_TOP_OVERSHOOT( y1 );
 
 
           /* finalize current profile if any */
@@ -2386,7 +2392,7 @@
           pxl = e2;
 
         /* check that the other pixel isn't set */
-        e1 = pxl == e1 ? e2 : e1;
+        e1 = ( pxl == e1 ) ? e2 : e1;
 
         e1 = TRUNC( e1 );
 
@@ -2587,7 +2593,7 @@
           pxl = e2;
 
         /* check that the other pixel isn't set */
-        e1 = pxl == e1 ? e2 : e1;
+        e1 = ( pxl == e1 ) ? e2 : e1;
 
         e1 = TRUNC( e1 );
 
@@ -3057,7 +3063,7 @@
 
 
      *araster = (FT_Raster)&the_raster;
-     FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
+     FT_ZERO( &the_raster );
      ft_black_init( &the_raster );
 
      return 0;
@@ -3208,11 +3214,12 @@
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Raster_New_Func)     ft_black_new,
-    (FT_Raster_Reset_Func)   ft_black_reset,
-    (FT_Raster_Set_Mode_Func)ft_black_set_mode,
-    (FT_Raster_Render_Func)  ft_black_render,
-    (FT_Raster_Done_Func)    ft_black_done )
+    (FT_Raster_New_Func)     ft_black_new,       /* raster_new      */
+    (FT_Raster_Reset_Func)   ft_black_reset,     /* raster_reset    */
+    (FT_Raster_Set_Mode_Func)ft_black_set_mode,  /* raster_set_mode */
+    (FT_Raster_Render_Func)  ft_black_render,    /* raster_render   */
+    (FT_Raster_Done_Func)    ft_black_done       /* raster_done     */
+  )
 
 
 /* END */
diff --git a/src/raster/ftraster.h b/src/raster/ftraster.h
index 65cd5f9..6b3050c 100644
--- a/src/raster/ftraster.h
+++ b/src/raster/ftraster.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer (specification).                       */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used        */
diff --git a/src/raster/ftrend1.c b/src/raster/ftrend1.c
index 494f112..1a83e9e 100644
--- a/src/raster/ftrend1.c
+++ b/src/raster/ftrend1.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer interface (body).                      */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -88,7 +88,7 @@
                        FT_GlyphSlot  slot,
                        FT_BBox*      cbox )
   {
-    FT_MEM_ZERO( cbox, sizeof ( *cbox ) );
+    FT_ZERO( cbox );
 
     if ( slot->format == render->glyph_format )
       FT_Outline_Get_CBox( &slot->outline, cbox );
@@ -224,7 +224,8 @@
   }
 
 
-  FT_DEFINE_RENDERER( ft_raster1_renderer_class,
+  FT_DEFINE_RENDERER(
+    ft_raster1_renderer_class,
 
       FT_MODULE_RENDERER,
       sizeof ( FT_RendererRec ),
@@ -233,21 +234,20 @@
       0x10000L,
       0x20000L,
 
-      0,    /* module specific interface */
+      NULL,    /* module specific interface */
 
-      (FT_Module_Constructor)ft_raster1_init,
-      (FT_Module_Destructor) 0,
-      (FT_Module_Requester)  0
-    ,
+      (FT_Module_Constructor)ft_raster1_init,  /* module_init   */
+      (FT_Module_Destructor) NULL,             /* module_done   */
+      (FT_Module_Requester)  NULL,             /* get_interface */
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Renderer_RenderFunc)   ft_raster1_render,
-    (FT_Renderer_TransformFunc)ft_raster1_transform,
-    (FT_Renderer_GetCBoxFunc)  ft_raster1_get_cbox,
-    (FT_Renderer_SetModeFunc)  ft_raster1_set_mode,
+    (FT_Renderer_RenderFunc)   ft_raster1_render,     /* render_glyph    */
+    (FT_Renderer_TransformFunc)ft_raster1_transform,  /* transform_glyph */
+    (FT_Renderer_GetCBoxFunc)  ft_raster1_get_cbox,   /* get_glyph_cbox  */
+    (FT_Renderer_SetModeFunc)  ft_raster1_set_mode,   /* set_mode        */
 
-    (FT_Raster_Funcs*)    &FT_STANDARD_RASTER_GET
+    (FT_Raster_Funcs*)&FT_STANDARD_RASTER_GET         /* raster_class    */
   )
 
 
diff --git a/src/raster/ftrend1.h b/src/raster/ftrend1.h
index a431f18..cff702d 100644
--- a/src/raster/ftrend1.h
+++ b/src/raster/ftrend1.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType glyph rasterizer interface (specification).             */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/raster/raster.c b/src/raster/raster.c
index 5b21dcb..ee54ae1 100644
--- a/src/raster/raster.c
+++ b/src/raster/raster.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType monochrome rasterer module component (body only).           */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/raster/rasterrs.h b/src/raster/rasterrs.h
index 44da7fc..0d64690 100644
--- a/src/raster/rasterrs.h
+++ b/src/raster/rasterrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    monochrome renderer error codes (specification only).                */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/raster/rastpic.c b/src/raster/rastpic.c
index dcfa92e..7085339 100644
--- a/src/raster/rastpic.c
+++ b/src/raster/rastpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for raster module.   */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/raster/rastpic.h b/src/raster/rastpic.h
index 7815876..dcd6913 100644
--- a/src/raster/rastpic.h
+++ b/src/raster/rastpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for raster module.   */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
index ff67292..96fc08e 100644
--- a/src/sfnt/pngshim.c
+++ b/src/sfnt/pngshim.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PNG Bitmap glyph support.                                            */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  Google, Inc.                                                           */
 /*  Written by Stuart Gill and Behdad Esfahbod.                            */
 /*                                                                         */
@@ -26,7 +26,7 @@
 
 #ifdef FT_CONFIG_OPTION_USE_PNG
 
-  /* We always include <stjmp.h>, so make libpng shut up! */
+  /* We always include <setjmp.h>, so make libpng shut up! */
 #define PNG_SKIP_SETJMP_CHECK 1
 #include <png.h>
 #include "pngshim.h"
diff --git a/src/sfnt/pngshim.h b/src/sfnt/pngshim.h
index 0af4bfc..344ecea 100644
--- a/src/sfnt/pngshim.h
+++ b/src/sfnt/pngshim.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    PNG Bitmap glyph support.                                            */
 /*                                                                         */
-/*  Copyright 2013-2016 by                                                 */
+/*  Copyright 2013-2017 by                                                 */
 /*  Google, Inc.                                                           */
 /*  Written by Stuart Gill and Behdad Esfahbod.                            */
 /*                                                                         */
diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c
index 2233269..a70f9a2 100644
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level SFNT driver interface (body).                             */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -88,7 +88,7 @@
       break;
 
     case FT_SFNT_OS2:
-      table = face->os2.version == 0xFFFFU ? NULL : &face->os2;
+      table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2;
       break;
 
     case FT_SFNT_POST:
@@ -139,9 +139,11 @@
 
   FT_DEFINE_SERVICE_SFNT_TABLEREC(
     sfnt_service_sfnt_table,
+
     (FT_SFNT_TableLoadFunc)tt_face_load_any,     /* load_table */
     (FT_SFNT_TableGetFunc) get_sfnt_table,       /* get_table  */
-    (FT_SFNT_TableInfoFunc)sfnt_table_info )     /* table_info */
+    (FT_SFNT_TableInfoFunc)sfnt_table_info       /* table_info */
+  )
 
 
 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
@@ -152,7 +154,7 @@
    */
 
   static FT_Error
-  sfnt_get_glyph_name( TT_Face     face,
+  sfnt_get_glyph_name( FT_Face     face,
                        FT_UInt     glyph_index,
                        FT_Pointer  buffer,
                        FT_UInt     buffer_max )
@@ -161,7 +163,7 @@
     FT_Error    error;
 
 
-    error = tt_face_get_ps_name( face, glyph_index, &gname );
+    error = tt_face_get_ps_name( (TT_Face)face, glyph_index, &gname );
     if ( !error )
       FT_STRCPYN( buffer, gname, buffer_max );
 
@@ -170,26 +172,26 @@
 
 
   static FT_UInt
-  sfnt_get_name_index( TT_Face     face,
+  sfnt_get_name_index( FT_Face     face,
                        FT_String*  glyph_name )
   {
-    FT_Face  root = &face->root;
+    TT_Face  ttface = (TT_Face)face;
 
     FT_UInt  i, max_gid = FT_UINT_MAX;
 
 
-    if ( root->num_glyphs < 0 )
+    if ( face->num_glyphs < 0 )
       return 0;
-    else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX )
-      max_gid = (FT_UInt)root->num_glyphs;
+    else if ( (FT_ULong)face->num_glyphs < FT_UINT_MAX )
+      max_gid = (FT_UInt)face->num_glyphs;
     else
       FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
-                  FT_UINT_MAX, root->num_glyphs ));
+                  FT_UINT_MAX, face->num_glyphs ));
 
     for ( i = 0; i < max_gid; i++ )
     {
       FT_String*  gname;
-      FT_Error    error = tt_face_get_ps_name( face, i, &gname );
+      FT_Error    error = tt_face_get_ps_name( ttface, i, &gname );
 
 
       if ( error )
@@ -205,9 +207,10 @@
 
   FT_DEFINE_SERVICE_GLYPHDICTREC(
     sfnt_service_glyph_dict,
-    (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,    /* get_name   */
-    (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index )   /* name_index */
 
+    (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,    /* get_name   */
+    (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index     /* name_index */
+  )
 
 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
@@ -235,14 +238,15 @@
 
     for ( n = 0; n < face->num_names; n++ )
     {
-      TT_NameEntryRec*  name = face->name_table.names + n;
+      TT_Name  name = face->name_table.names + n;
 
 
       if ( name->nameID == 6 && name->stringLength > 0 )
       {
-        if ( name->platformID == 3     &&
-             name->encodingID == 1     &&
-             name->languageID == 0x409 )
+        /* handling of PID/EID 3/0 and 3/1 is the same */
+        if ( name->platformID == 3                              &&
+             ( name->encodingID == 1 || name->encodingID == 0 ) &&
+             name->languageID == 0x409                          )
           found_win = n;
 
         if ( name->platformID == 1 &&
@@ -254,10 +258,10 @@
 
     if ( found_win != -1 )
     {
-      FT_Memory         memory = face->root.memory;
-      TT_NameEntryRec*  name   = face->name_table.names + found_win;
-      FT_UInt           len    = name->stringLength / 2;
-      FT_Error          error  = FT_Err_Ok;
+      FT_Memory  memory = face->root.memory;
+      TT_Name    name   = face->name_table.names + found_win;
+      FT_UInt    len    = name->stringLength / 2;
+      FT_Error   error  = FT_Err_Ok;
 
       FT_UNUSED( error );
 
@@ -296,10 +300,10 @@
 
     if ( found_apple != -1 )
     {
-      FT_Memory         memory = face->root.memory;
-      TT_NameEntryRec*  name   = face->name_table.names + found_apple;
-      FT_UInt           len    = name->stringLength;
-      FT_Error          error  = FT_Err_Ok;
+      FT_Memory  memory = face->root.memory;
+      TT_Name    name   = face->name_table.names + found_apple;
+      FT_UInt    len    = name->stringLength;
+      FT_Error   error  = FT_Err_Ok;
 
       FT_UNUSED( error );
 
@@ -330,7 +334,9 @@
 
   FT_DEFINE_SERVICE_PSFONTNAMEREC(
     sfnt_service_ps_name,
-    (FT_PsName_GetFunc)sfnt_get_ps_name )     /* get_ps_font_name */
+
+    (FT_PsName_GetFunc)sfnt_get_ps_name       /* get_ps_font_name */
+  )
 
 
   /*
@@ -338,7 +344,9 @@
    */
   FT_DEFINE_SERVICE_TTCMAPSREC(
     tt_service_get_cmap_info,
-    (TT_CMap_Info_GetFunc)tt_get_cmap_info )  /* get_cmap_info */
+
+    (TT_CMap_Info_GetFunc)tt_get_cmap_info    /* get_cmap_info */
+  )
 
 
 #ifdef TT_CONFIG_OPTION_BDF
@@ -381,8 +389,10 @@
 
   FT_DEFINE_SERVICE_BDFRec(
     sfnt_service_bdf,
+
     (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id,     /* get_charset_id */
-    (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop )  /* get_property   */
+    (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop    /* get_property   */
+  )
 
 
 #endif /* TT_CONFIG_OPTION_BDF */
@@ -395,6 +405,7 @@
 #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
   FT_DEFINE_SERVICEDESCREC5(
     sfnt_services,
+
     FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
     FT_SERVICE_ID_GLYPH_DICT,           &SFNT_SERVICE_GLYPH_DICT_GET,
@@ -403,6 +414,7 @@
 #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
   FT_DEFINE_SERVICEDESCREC4(
     sfnt_services,
+
     FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
     FT_SERVICE_ID_GLYPH_DICT,           &SFNT_SERVICE_GLYPH_DICT_GET,
@@ -410,6 +422,7 @@
 #elif defined TT_CONFIG_OPTION_BDF
   FT_DEFINE_SERVICEDESCREC4(
     sfnt_services,
+
     FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
     FT_SERVICE_ID_BDF,                  &SFNT_SERVICE_BDF_GET,
@@ -417,6 +430,7 @@
 #else
   FT_DEFINE_SERVICEDESCREC3(
     sfnt_services,
+
     FT_SERVICE_ID_SFNT_TABLE,           &SFNT_SERVICE_SFNT_TABLE_GET,
     FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET,
     FT_SERVICE_ID_TT_CMAP,              &TT_SERVICE_CMAP_INFO_GET )
@@ -459,6 +473,7 @@
 
   FT_DEFINE_SFNT_INTERFACE(
     sfnt_interface,
+
     tt_face_goto_table,     /* TT_Loader_GotoTableFunc goto_table      */
 
     sfnt_init_face,         /* TT_Init_Face_Func       init_face       */
@@ -530,9 +545,10 @@
 
     (const void*)&SFNT_INTERFACE_GET,  /* module specific interface */
 
-    (FT_Module_Constructor)0,
-    (FT_Module_Destructor) 0,
-    (FT_Module_Requester)  sfnt_get_interface )
+    (FT_Module_Constructor)NULL,               /* module_init   */
+    (FT_Module_Destructor) NULL,               /* module_done   */
+    (FT_Module_Requester)  sfnt_get_interface  /* get_interface */
+  )
 
 
 /* END */
diff --git a/src/sfnt/sfdriver.h b/src/sfnt/sfdriver.h
index 2694488..38710b6 100644
--- a/src/sfnt/sfdriver.h
+++ b/src/sfnt/sfdriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level SFNT driver interface (specification).                    */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sferrors.h b/src/sfnt/sferrors.h
index c2f9fdf..3cf73d7 100644
--- a/src/sfnt/sferrors.h
+++ b/src/sfnt/sferrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT error codes (specification only).                               */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c
index 952d6d4..cffda6e 100644
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfnt.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Single object library component.                                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sfntpic.c b/src/sfnt/sfntpic.c
index 1f596c0..8eadd60 100644
--- a/src/sfnt/sfntpic.c
+++ b/src/sfnt/sfntpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for sfnt module.     */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sfntpic.h b/src/sfnt/sfntpic.h
index 5ce96d3..3afb668 100644
--- a/src/sfnt/sfntpic.h
+++ b/src/sfnt/sfntpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for sfnt module.     */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index ceeae20..67e868c 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT object management (base).                                       */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -28,6 +28,12 @@
 #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
+#include FT_SERVICE_METRICS_VARIATIONS_H
+#endif
+
 #include "sferrors.h"
 
 #ifdef TT_CONFIG_OPTION_BDF
@@ -48,8 +54,8 @@
 
   /* convert a UTF-16 name entry to ASCII */
   static FT_String*
-  tt_name_entry_ascii_from_utf16( TT_NameEntry  entry,
-                                  FT_Memory     memory )
+  tt_name_ascii_from_utf16( TT_Name    entry,
+                            FT_Memory  memory )
   {
     FT_String*  string = NULL;
     FT_UInt     len, code, n;
@@ -83,8 +89,8 @@
 
   /* convert an Apple Roman or symbol name entry to ASCII */
   static FT_String*
-  tt_name_entry_ascii_from_other( TT_NameEntry  entry,
-                                  FT_Memory     memory )
+  tt_name_ascii_from_other( TT_Name    entry,
+                            FT_Memory  memory )
   {
     FT_String*  string = NULL;
     FT_UInt     len, code, n;
@@ -116,8 +122,8 @@
   }
 
 
-  typedef FT_String*  (*TT_NameEntry_ConvertFunc)( TT_NameEntry  entry,
-                                                   FT_Memory     memory );
+  typedef FT_String*  (*TT_Name_ConvertFunc)( TT_Name    entry,
+                                              FT_Memory  memory );
 
 
   /* documentation is in sfnt.h */
@@ -127,20 +133,21 @@
                     FT_UShort    nameid,
                     FT_String**  name )
   {
-    FT_Memory         memory = face->root.memory;
-    FT_Error          error  = FT_Err_Ok;
-    FT_String*        result = NULL;
-    FT_UShort         n;
-    TT_NameEntryRec*  rec;
-    FT_Int            found_apple         = -1;
-    FT_Int            found_apple_roman   = -1;
-    FT_Int            found_apple_english = -1;
-    FT_Int            found_win           = -1;
-    FT_Int            found_unicode       = -1;
+    FT_Memory   memory = face->root.memory;
+    FT_Error    error  = FT_Err_Ok;
+    FT_String*  result = NULL;
+    FT_UShort   n;
+    TT_Name     rec;
 
-    FT_Bool           is_english = 0;
+    FT_Int  found_apple         = -1;
+    FT_Int  found_apple_roman   = -1;
+    FT_Int  found_apple_english = -1;
+    FT_Int  found_win           = -1;
+    FT_Int  found_unicode       = -1;
 
-    TT_NameEntry_ConvertFunc  convert;
+    FT_Bool  is_english = 0;
+
+    TT_Name_ConvertFunc  convert;
 
 
     FT_ASSERT( name );
@@ -225,7 +232,7 @@
         /* all Unicode strings are encoded using UTF-16BE */
       case TT_MS_ID_UNICODE_CS:
       case TT_MS_ID_SYMBOL_CS:
-        convert = tt_name_entry_ascii_from_utf16;
+        convert = tt_name_ascii_from_utf16;
         break;
 
       case TT_MS_ID_UCS_4:
@@ -234,7 +241,7 @@
         /* MsGothic font shipped with Windows Vista shows that this really */
         /* means UTF-16 encoded names (UCS-4 values are only used within   */
         /* charmaps).                                                      */
-        convert = tt_name_entry_ascii_from_utf16;
+        convert = tt_name_ascii_from_utf16;
         break;
 
       default:
@@ -244,17 +251,17 @@
     else if ( found_apple >= 0 )
     {
       rec     = face->name_table.names + found_apple;
-      convert = tt_name_entry_ascii_from_other;
+      convert = tt_name_ascii_from_other;
     }
     else if ( found_unicode >= 0 )
     {
       rec     = face->name_table.names + found_unicode;
-      convert = tt_name_entry_ascii_from_utf16;
+      convert = tt_name_ascii_from_utf16;
     }
 
     if ( rec && convert )
     {
-      if ( rec->string == NULL )
+      if ( !rec->string )
       {
         FT_Stream  stream = face->name_table.stream;
 
@@ -304,7 +311,7 @@
       { TT_PLATFORM_MICROSOFT,     TT_MS_ID_UCS_4,      FT_ENCODING_UNICODE },
       { TT_PLATFORM_MICROSOFT,     TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE },
       { TT_PLATFORM_MICROSOFT,     TT_MS_ID_SJIS,       FT_ENCODING_SJIS },
-      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_GB2312,     FT_ENCODING_GB2312 },
+      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_PRC,        FT_ENCODING_PRC },
       { TT_PLATFORM_MICROSOFT,     TT_MS_ID_BIG_5,      FT_ENCODING_BIG5 },
       { TT_PLATFORM_MICROSOFT,     TT_MS_ID_WANSUNG,    FT_ENCODING_WANSUNG },
       { TT_PLATFORM_MICROSOFT,     TT_MS_ID_JOHAB,      FT_ENCODING_JOHAB }
@@ -798,6 +805,9 @@
       if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
         return error;
 
+      FT_TRACE3(( "                with %ld subfonts\n",
+                  face->ttc_header.count ));
+
       if ( face->ttc_header.count == 0 )
         return FT_THROW( Invalid_Table );
 
@@ -872,6 +882,31 @@
 
     FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    if ( !face->mm )
+    {
+      /* we want the MM interface from the `truetype' module only */
+      FT_Module  tt_module = FT_Get_Module( library, "truetype" );
+
+
+      face->mm = ft_module_get_service( tt_module,
+                                        FT_SERVICE_ID_MULTI_MASTERS,
+                                        0 );
+    }
+
+    if ( !face->var )
+    {
+      /* we want the metrics variations interface */
+      /* from the `truetype' module only          */
+      FT_Module  tt_module = FT_Get_Module( library, "truetype" );
+
+
+      face->var = ft_module_get_service( tt_module,
+                                         FT_SERVICE_ID_METRICS_VARIATIONS,
+                                         0 );
+    }
+#endif
+
     FT_TRACE2(( "SFNT driver\n" ));
 
     error = sfnt_open_font( stream, face );
@@ -881,10 +916,14 @@
     /* Stream may have changed in sfnt_open_font. */
     stream = face->root.stream;
 
-    FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_instance_index ));
+    FT_TRACE2(( "sfnt_init_face: %08p, %d\n", face, face_instance_index ));
 
     face_index = FT_ABS( face_instance_index ) & 0xFFFF;
 
+    /* value -(N+1) requests information on index N */
+    if ( face_instance_index < 0 )
+      face_index--;
+
     if ( face_index >= face->ttc_header.count )
     {
       if ( face_instance_index >= 0 )
@@ -916,6 +955,8 @@
       FT_Int  instance_index;
 
 
+      face->is_default_instance = 1;
+
       instance_index = FT_ABS( face_instance_index ) >> 16;
 
       /* test whether current face is a GX font with named instances */
@@ -923,7 +964,7 @@
            fvar_len < 20                                          ||
            FT_READ_ULONG( version )                               ||
            FT_READ_USHORT( offset )                               ||
-           FT_STREAM_SKIP( 2 )                                    ||
+           FT_STREAM_SKIP( 2 ) /* count_size_pairs */             ||
            FT_READ_USHORT( num_axes )                             ||
            FT_READ_USHORT( axis_size )                            ||
            FT_READ_USHORT( num_instances )                        ||
@@ -937,17 +978,27 @@
         instance_size = 0;
       }
 
-      /* check that the data is bound by the table length; */
-      /* based on similar code in function `TT_Get_MM_Var' */
+      /* check that the data is bound by the table length */
       if ( version != 0x00010000UL                    ||
+#if 0
+           /* fonts like `JamRegular.ttf' have an incorrect value for   */
+           /* `count_size_pairs'; since value 2 is hard-coded in `fvar' */
+           /* version 1.0, we simply ignore it                          */
+           count_size_pairs != 2                      ||
+#endif
            axis_size != 20                            ||
+           num_axes == 0                              ||
+           /* `num_axes' limit implied by 16-bit `instance_size' */
            num_axes > 0x3FFE                          ||
-           instance_size != 4 + 4 * num_axes          ||
+           !( instance_size == 4 + 4 * num_axes ||
+              instance_size == 6 + 4 * num_axes )     ||
            num_instances > 0x7EFF                     ||
            offset                          +
              axis_size * num_axes          +
              instance_size * num_instances > fvar_len )
         num_instances = 0;
+      else
+        face->variation_support |= TT_FACE_FLAG_VAR_FVAR;
 
       /* we don't support Multiple Master CFFs yet */
       if ( !face->goto_table( face, TTAG_CFF, stream, 0 ) )
@@ -1039,8 +1090,8 @@
     FT_Bool       has_outline;
     FT_Bool       is_apple_sbit;
     FT_Bool       is_apple_sbix;
-    FT_Bool       ignore_preferred_family    = FALSE;
-    FT_Bool       ignore_preferred_subfamily = FALSE;
+    FT_Bool       ignore_typographic_family    = FALSE;
+    FT_Bool       ignore_typographic_subfamily = FALSE;
 
     SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
 
@@ -1055,10 +1106,10 @@
 
       for ( i = 0; i < num_params; i++ )
       {
-        if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY )
-          ignore_preferred_family = TRUE;
-        else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY )
-          ignore_preferred_subfamily = TRUE;
+        if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY )
+          ignore_typographic_family = TRUE;
+        else if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY )
+          ignore_typographic_subfamily = TRUE;
       }
     }
 
@@ -1083,12 +1134,14 @@
 
     /* do we have outlines in there? */
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
-    has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 ||
-                           tt_face_lookup_table( face, TTAG_glyf )    != 0 ||
-                           tt_face_lookup_table( face, TTAG_CFF )     != 0 );
+    has_outline = FT_BOOL( face->root.internal->incremental_interface ||
+                           tt_face_lookup_table( face, TTAG_glyf )    ||
+                           tt_face_lookup_table( face, TTAG_CFF )     ||
+                           tt_face_lookup_table( face, TTAG_CFF2 )    );
 #else
-    has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
-                           tt_face_lookup_table( face, TTAG_CFF )  != 0 );
+    has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) ||
+                           tt_face_lookup_table( face, TTAG_CFF )  ||
+                           tt_face_lookup_table( face, TTAG_CFF2 ) );
 #endif
 
     is_apple_sbit = 0;
@@ -1220,30 +1273,10 @@
 
     /* embedded bitmap support */
     if ( sfnt->load_eblc )
-    {
       LOAD_( eblc );
-      if ( error )
-      {
-        /* a font which contains neither bitmaps nor outlines is */
-        /* still valid (although rather useless in most cases);  */
-        /* however, you can find such stripped fonts in PDFs     */
-        if ( FT_ERR_EQ( error, Table_Missing ) )
-          error = FT_Err_Ok;
-        else
-          goto Exit;
-      }
-    }
 
+    /* consider the pclt, kerning, and gasp tables as optional */
     LOAD_( pclt );
-    if ( error )
-    {
-      if ( FT_ERR_NEQ( error, Table_Missing ) )
-        goto Exit;
-
-      face->pclt.Version = 0;
-    }
-
-    /* consider the kerning and gasp tables as optional */
     LOAD_( gasp );
     LOAD_( kern );
 
@@ -1259,27 +1292,27 @@
     face->root.style_name  = NULL;
     if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )
     {
-      if ( !ignore_preferred_family )
-        GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
+      if ( !ignore_typographic_family )
+        GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name );
       if ( !face->root.family_name )
         GET_NAME( FONT_FAMILY, &face->root.family_name );
 
-      if ( !ignore_preferred_subfamily )
-        GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
+      if ( !ignore_typographic_subfamily )
+        GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name );
       if ( !face->root.style_name )
         GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
     }
     else
     {
       GET_NAME( WWS_FAMILY, &face->root.family_name );
-      if ( !face->root.family_name && !ignore_preferred_family )
-        GET_NAME( PREFERRED_FAMILY, &face->root.family_name );
+      if ( !face->root.family_name && !ignore_typographic_family )
+        GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name );
       if ( !face->root.family_name )
         GET_NAME( FONT_FAMILY, &face->root.family_name );
 
       GET_NAME( WWS_SUBFAMILY, &face->root.style_name );
-      if ( !face->root.style_name && !ignore_preferred_subfamily )
-        GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name );
+      if ( !face->root.style_name && !ignore_typographic_subfamily )
+        GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name );
       if ( !face->root.style_name )
         GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
     }
@@ -1327,10 +1360,14 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
       /* Don't bother to load the tables unless somebody asks for them. */
       /* No need to do work which will (probably) not be used.          */
-      if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
-           tt_face_lookup_table( face, TTAG_fvar ) != 0 &&
-           tt_face_lookup_table( face, TTAG_gvar ) != 0 )
-        flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
+      if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
+      {
+        if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
+             tt_face_lookup_table( face, TTAG_gvar ) != 0 )
+          flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
+        if ( tt_face_lookup_table( face, TTAG_CFF2 ) != 0 )
+          flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
+      }
 #endif
 
       root->face_flags = flags;
@@ -1393,7 +1430,7 @@
                                                   charmap->encoding_id );
 
 #if 0
-          if ( root->charmap     == NULL &&
+          if ( !root->charmap                           &&
                charmap->encoding == FT_ENCODING_UNICODE )
           {
             /* set 'root->charmap' to the first Unicode encoding we find */
@@ -1637,18 +1674,10 @@
       face->cmap_size = 0;
     }
 
-    /* freeing the horizontal metrics */
-    {
-      FT_Stream  stream = FT_FACE_STREAM( face );
+    face->horz_metrics_size = 0;
+    face->vert_metrics_size = 0;
 
-
-      FT_FRAME_RELEASE( face->horz_metrics );
-      FT_FRAME_RELEASE( face->vert_metrics );
-      face->horz_metrics_size = 0;
-      face->vert_metrics_size = 0;
-    }
-
-    /* freeing the vertical ones, if any */
+    /* freeing vertical metrics, if any */
     if ( face->vertical_info )
     {
       FT_FREE( face->vertical.long_metrics  );
diff --git a/src/sfnt/sfobjs.h b/src/sfnt/sfobjs.h
index 60b5698..7053814 100644
--- a/src/sfnt/sfobjs.h
+++ b/src/sfnt/sfobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT object management (specification).                              */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttbdf.c b/src/sfnt/ttbdf.c
index f891691..e7e7220 100644
--- a/src/sfnt/ttbdf.c
+++ b/src/sfnt/ttbdf.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType and OpenType embedded BDF properties (body).                */
 /*                                                                         */
-/*  Copyright 2005-2016 by                                                 */
+/*  Copyright 2005-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -48,7 +48,7 @@
       FT_Stream  stream = FT_FACE(face)->stream;
 
 
-      if ( bdf->table != NULL )
+      if ( bdf->table )
         FT_FRAME_RELEASE( bdf->table );
 
       bdf->table_end    = NULL;
@@ -165,7 +165,7 @@
 
     error = FT_ERR( Invalid_Argument );
 
-    if ( size == NULL || property_name == NULL )
+    if ( !size || !property_name )
       goto Exit;
 
     property_len = ft_strlen( property_name );
@@ -177,6 +177,7 @@
       FT_UInt  _ppem  = FT_NEXT_USHORT( p );
       FT_UInt  _count = FT_NEXT_USHORT( p );
 
+
       if ( _ppem == size->metrics.y_ppem )
       {
         count = _count;
@@ -193,6 +194,7 @@
     {
       FT_UInt  type = FT_PEEK_USHORT( p + 4 );
 
+
       if ( ( type & 0x10 ) != 0 )
       {
         FT_UInt32  name_offset = FT_PEEK_ULONG( p     );
diff --git a/src/sfnt/ttbdf.h b/src/sfnt/ttbdf.h
index ae521c6..398b620 100644
--- a/src/sfnt/ttbdf.h
+++ b/src/sfnt/ttbdf.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType and OpenType embedded BDF properties (specification).       */
 /*                                                                         */
-/*  Copyright 2005-2016 by                                                 */
+/*  Copyright 2005-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index cd7467d..5afa6ae 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType character mapping table (cmap) support (body).              */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -180,22 +180,24 @@
 
   FT_DEFINE_TT_CMAP(
     tt_cmap0_class_rec,
-    sizeof ( TT_CMapRec ),
 
-    (FT_CMap_InitFunc)     tt_cmap_init,
-    (FT_CMap_DoneFunc)     NULL,
-    (FT_CMap_CharIndexFunc)tt_cmap0_char_index,
-    (FT_CMap_CharNextFunc) tt_cmap0_char_next,
+      sizeof ( TT_CMapRec ),
 
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
+      (FT_CMap_InitFunc)     tt_cmap_init,         /* init       */
+      (FT_CMap_DoneFunc)     NULL,                 /* done       */
+      (FT_CMap_CharIndexFunc)tt_cmap0_char_index,  /* char_index */
+      (FT_CMap_CharNextFunc) tt_cmap0_char_next,   /* char_next  */
+
+      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+      (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 
     0,
-    (TT_CMap_ValidateFunc)tt_cmap0_validate,
-    (TT_CMap_Info_GetFunc)tt_cmap0_get_info )
+    (TT_CMap_ValidateFunc)tt_cmap0_validate,  /* validate      */
+    (TT_CMap_Info_GetFunc)tt_cmap0_get_info   /* get_cmap_info */
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_0 */
 
@@ -571,22 +573,24 @@
 
   FT_DEFINE_TT_CMAP(
     tt_cmap2_class_rec,
-    sizeof ( TT_CMapRec ),
 
-    (FT_CMap_InitFunc)     tt_cmap_init,
-    (FT_CMap_DoneFunc)     NULL,
-    (FT_CMap_CharIndexFunc)tt_cmap2_char_index,
-    (FT_CMap_CharNextFunc) tt_cmap2_char_next,
+      sizeof ( TT_CMapRec ),
 
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
+      (FT_CMap_InitFunc)     tt_cmap_init,         /* init       */
+      (FT_CMap_DoneFunc)     NULL,                 /* done       */
+      (FT_CMap_CharIndexFunc)tt_cmap2_char_index,  /* char_index */
+      (FT_CMap_CharNextFunc) tt_cmap2_char_next,   /* char_next  */
+
+      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+      (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 
     2,
-    (TT_CMap_ValidateFunc)tt_cmap2_validate,
-    (TT_CMap_Info_GetFunc)tt_cmap2_get_info )
+    (TT_CMap_ValidateFunc)tt_cmap2_validate,  /* validate      */
+    (TT_CMap_Info_GetFunc)tt_cmap2_get_info   /* get_cmap_info */
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_2 */
 
@@ -1516,21 +1520,24 @@
 
   FT_DEFINE_TT_CMAP(
     tt_cmap4_class_rec,
-    sizeof ( TT_CMap4Rec ),
-    (FT_CMap_InitFunc)     tt_cmap4_init,
-    (FT_CMap_DoneFunc)     NULL,
-    (FT_CMap_CharIndexFunc)tt_cmap4_char_index,
-    (FT_CMap_CharNextFunc) tt_cmap4_char_next,
 
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
+      sizeof ( TT_CMap4Rec ),
+
+      (FT_CMap_InitFunc)     tt_cmap4_init,        /* init       */
+      (FT_CMap_DoneFunc)     NULL,                 /* done       */
+      (FT_CMap_CharIndexFunc)tt_cmap4_char_index,  /* char_index */
+      (FT_CMap_CharNextFunc) tt_cmap4_char_next,   /* char_next  */
+
+      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+      (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 
     4,
-    (TT_CMap_ValidateFunc)tt_cmap4_validate,
-    (TT_CMap_Info_GetFunc)tt_cmap4_get_info )
+    (TT_CMap_ValidateFunc)tt_cmap4_validate,  /* validate      */
+    (TT_CMap_Info_GetFunc)tt_cmap4_get_info   /* get_cmap_info */
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_4 */
 
@@ -1683,22 +1690,24 @@
 
   FT_DEFINE_TT_CMAP(
     tt_cmap6_class_rec,
-    sizeof ( TT_CMapRec ),
 
-    (FT_CMap_InitFunc)     tt_cmap_init,
-    (FT_CMap_DoneFunc)     NULL,
-    (FT_CMap_CharIndexFunc)tt_cmap6_char_index,
-    (FT_CMap_CharNextFunc) tt_cmap6_char_next,
+      sizeof ( TT_CMapRec ),
 
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
+      (FT_CMap_InitFunc)     tt_cmap_init,         /* init       */
+      (FT_CMap_DoneFunc)     NULL,                 /* done       */
+      (FT_CMap_CharIndexFunc)tt_cmap6_char_index,  /* char_index */
+      (FT_CMap_CharNextFunc) tt_cmap6_char_next,   /* char_next  */
+
+      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+      (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 
     6,
-    (TT_CMap_ValidateFunc)tt_cmap6_validate,
-    (TT_CMap_Info_GetFunc)tt_cmap6_get_info )
+    (TT_CMap_ValidateFunc)tt_cmap6_validate,  /* validate      */
+    (TT_CMap_Info_GetFunc)tt_cmap6_get_info   /* get_cmap_info */
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_6 */
 
@@ -1975,22 +1984,24 @@
 
   FT_DEFINE_TT_CMAP(
     tt_cmap8_class_rec,
-    sizeof ( TT_CMapRec ),
 
-    (FT_CMap_InitFunc)     tt_cmap_init,
-    (FT_CMap_DoneFunc)     NULL,
-    (FT_CMap_CharIndexFunc)tt_cmap8_char_index,
-    (FT_CMap_CharNextFunc) tt_cmap8_char_next,
+      sizeof ( TT_CMapRec ),
 
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
+      (FT_CMap_InitFunc)     tt_cmap_init,         /* init       */
+      (FT_CMap_DoneFunc)     NULL,                 /* done       */
+      (FT_CMap_CharIndexFunc)tt_cmap8_char_index,  /* char_index */
+      (FT_CMap_CharNextFunc) tt_cmap8_char_next,   /* char_next  */
+
+      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+      (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 
     8,
-    (TT_CMap_ValidateFunc)tt_cmap8_validate,
-    (TT_CMap_Info_GetFunc)tt_cmap8_get_info )
+    (TT_CMap_ValidateFunc)tt_cmap8_validate,  /* validate      */
+    (TT_CMap_Info_GetFunc)tt_cmap8_get_info   /* get_cmap_info */
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_8 */
 
@@ -2145,22 +2156,24 @@
 
   FT_DEFINE_TT_CMAP(
     tt_cmap10_class_rec,
-    sizeof ( TT_CMapRec ),
 
-    (FT_CMap_InitFunc)     tt_cmap_init,
-    (FT_CMap_DoneFunc)     NULL,
-    (FT_CMap_CharIndexFunc)tt_cmap10_char_index,
-    (FT_CMap_CharNextFunc) tt_cmap10_char_next,
+      sizeof ( TT_CMapRec ),
 
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
+      (FT_CMap_InitFunc)     tt_cmap_init,          /* init       */
+      (FT_CMap_DoneFunc)     NULL,                  /* done       */
+      (FT_CMap_CharIndexFunc)tt_cmap10_char_index,  /* char_index */
+      (FT_CMap_CharNextFunc) tt_cmap10_char_next,   /* char_next  */
+
+      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+      (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 
     10,
-    (TT_CMap_ValidateFunc)tt_cmap10_validate,
-    (TT_CMap_Info_GetFunc)tt_cmap10_get_info )
+    (TT_CMap_ValidateFunc)tt_cmap10_validate,  /* validate      */
+    (TT_CMap_Info_GetFunc)tt_cmap10_get_info   /* get_cmap_info */
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_10 */
 
@@ -2499,22 +2512,24 @@
 
   FT_DEFINE_TT_CMAP(
     tt_cmap12_class_rec,
-    sizeof ( TT_CMap12Rec ),
 
-    (FT_CMap_InitFunc)     tt_cmap12_init,
-    (FT_CMap_DoneFunc)     NULL,
-    (FT_CMap_CharIndexFunc)tt_cmap12_char_index,
-    (FT_CMap_CharNextFunc) tt_cmap12_char_next,
+      sizeof ( TT_CMap12Rec ),
 
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
+      (FT_CMap_InitFunc)     tt_cmap12_init,        /* init       */
+      (FT_CMap_DoneFunc)     NULL,                  /* done       */
+      (FT_CMap_CharIndexFunc)tt_cmap12_char_index,  /* char_index */
+      (FT_CMap_CharNextFunc) tt_cmap12_char_next,   /* char_next  */
+
+      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+      (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 
     12,
-    (TT_CMap_ValidateFunc)tt_cmap12_validate,
-    (TT_CMap_Info_GetFunc)tt_cmap12_get_info )
+    (TT_CMap_ValidateFunc)tt_cmap12_validate,  /* validate      */
+    (TT_CMap_Info_GetFunc)tt_cmap12_get_info   /* get_cmap_info */
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_12 */
 
@@ -2823,22 +2838,24 @@
 
   FT_DEFINE_TT_CMAP(
     tt_cmap13_class_rec,
-    sizeof ( TT_CMap13Rec ),
 
-    (FT_CMap_InitFunc)     tt_cmap13_init,
-    (FT_CMap_DoneFunc)     NULL,
-    (FT_CMap_CharIndexFunc)tt_cmap13_char_index,
-    (FT_CMap_CharNextFunc) tt_cmap13_char_next,
+      sizeof ( TT_CMap13Rec ),
 
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
+      (FT_CMap_InitFunc)     tt_cmap13_init,        /* init       */
+      (FT_CMap_DoneFunc)     NULL,                  /* done       */
+      (FT_CMap_CharIndexFunc)tt_cmap13_char_index,  /* char_index */
+      (FT_CMap_CharNextFunc) tt_cmap13_char_next,   /* char_next  */
+
+      (FT_CMap_CharVarIndexFunc)    NULL,  /* char_var_index   */
+      (FT_CMap_CharVarIsDefaultFunc)NULL,  /* char_var_default */
+      (FT_CMap_VariantListFunc)     NULL,  /* variant_list     */
+      (FT_CMap_CharVariantListFunc) NULL,  /* charvariant_list */
+      (FT_CMap_VariantCharListFunc) NULL,  /* variantchar_list */
 
     13,
-    (TT_CMap_ValidateFunc)tt_cmap13_validate,
-    (TT_CMap_Info_GetFunc)tt_cmap13_get_info )
+    (TT_CMap_ValidateFunc)tt_cmap13_validate,  /* validate      */
+    (TT_CMap_Info_GetFunc)tt_cmap13_get_info   /* get_cmap_info */
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_13 */
 
@@ -2929,7 +2946,7 @@
 
 
     cmap->max_results = 0;
-    if ( memory != NULL && cmap->results != NULL )
+    if ( memory && cmap->results )
       FT_FREE( cmap->results );
   }
 
@@ -3036,7 +3053,7 @@
           if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 )
             FT_INVALID_TOO_SHORT;
 
-          for ( i = 0; i < numRanges; ++i )
+          for ( i = 0; i < numRanges; i++ )
           {
             FT_ULong  base = TT_NEXT_UINT24( defp );
             FT_ULong  cnt  = FT_NEXT_BYTE( defp );
@@ -3069,7 +3086,7 @@
           if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 )
             FT_INVALID_TOO_SHORT;
 
-          for ( i = 0; i < numMappings; ++i )
+          for ( i = 0; i < numMappings; i++ )
           {
             FT_ULong  uni = TT_NEXT_UINT24( ndp );
             FT_ULong  gid = TT_NEXT_USHORT( ndp );
@@ -3310,7 +3327,7 @@
       return NULL;
 
     result = cmap14->results;
-    for ( i = 0; i < count; ++i )
+    for ( i = 0; i < count; i++ )
     {
       result[i] = (FT_UInt32)TT_NEXT_UINT24( p );
       p        += 8;
@@ -3335,7 +3352,7 @@
     if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) )
       return NULL;
 
-    for ( q = cmap14->results; count > 0; --count )
+    for ( q = cmap14->results; count > 0; count-- )
     {
       FT_UInt32  varSel    = TT_NEXT_UINT24( p );
       FT_ULong   defOff    = TT_NEXT_ULONG( p );
@@ -3394,7 +3411,7 @@
     if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) )
       return NULL;
 
-    for ( q = cmap14->results; numRanges > 0; --numRanges )
+    for ( q = cmap14->results; numRanges > 0; numRanges-- )
     {
       FT_UInt32  uni = (FT_UInt32)TT_NEXT_UINT24( p );
 
@@ -3431,7 +3448,7 @@
       return NULL;
 
     ret = cmap14->results;
-    for ( i = 0; i < numMappings; ++i )
+    for ( i = 0; i < numMappings; i++ )
     {
       ret[i] = (FT_UInt32)TT_NEXT_UINT24( p );
       p += 2;
@@ -3515,10 +3532,10 @@
       {
         if ( nuni > duni + dcnt )
         {
-          for ( k = 0; k <= dcnt; ++k )
+          for ( k = 0; k <= dcnt; k++ )
             ret[i++] = duni + k;
 
-          ++di;
+          di++;
 
           if ( di > numRanges )
             break;
@@ -3532,7 +3549,7 @@
             ret[i++] = nuni;
           /* If it is within the default range then ignore it -- */
           /* that should not have happened                       */
-          ++ni;
+          ni++;
           if ( ni > numMappings )
             break;
 
@@ -3551,7 +3568,7 @@
         {
           ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p );
           p += 2;
-          ++ni;
+          ni++;
         }
       }
       else if ( di <= numRanges )
@@ -3559,7 +3576,7 @@
         /* If we get here then we have run out of all non-default     */
         /* mappings.  We have read one default range which we haven't */
         /* stored and there may be others that need to be read.       */
-        for ( k = 0; k <= dcnt; ++k )
+        for ( k = 0; k <= dcnt; k++ )
           ret[i++] = duni + k;
 
         while ( di < numRanges )
@@ -3567,9 +3584,9 @@
           duni = (FT_UInt32)TT_NEXT_UINT24( dp );
           dcnt = FT_NEXT_BYTE( dp );
 
-          for ( k = 0; k <= dcnt; ++k )
+          for ( k = 0; k <= dcnt; k++ )
             ret[i++] = duni + k;
-          ++di;
+          di++;
         }
       }
 
@@ -3582,23 +3599,25 @@
 
   FT_DEFINE_TT_CMAP(
     tt_cmap14_class_rec,
-    sizeof ( TT_CMap14Rec ),
 
-    (FT_CMap_InitFunc)     tt_cmap14_init,
-    (FT_CMap_DoneFunc)     tt_cmap14_done,
-    (FT_CMap_CharIndexFunc)tt_cmap14_char_index,
-    (FT_CMap_CharNextFunc) tt_cmap14_char_next,
+      sizeof ( TT_CMap14Rec ),
 
-    /* Format 14 extension functions */
-    (FT_CMap_CharVarIndexFunc)    tt_cmap14_char_var_index,
-    (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
-    (FT_CMap_VariantListFunc)     tt_cmap14_variants,
-    (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
-    (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars,
+      (FT_CMap_InitFunc)     tt_cmap14_init,        /* init       */
+      (FT_CMap_DoneFunc)     tt_cmap14_done,        /* done       */
+      (FT_CMap_CharIndexFunc)tt_cmap14_char_index,  /* char_index */
+      (FT_CMap_CharNextFunc) tt_cmap14_char_next,   /* char_next  */
+
+      /* Format 14 extension functions */
+      (FT_CMap_CharVarIndexFunc)    tt_cmap14_char_var_index,
+      (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault,
+      (FT_CMap_VariantListFunc)     tt_cmap14_variants,
+      (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants,
+      (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars,
 
     14,
-    (TT_CMap_ValidateFunc)tt_cmap14_validate,
-    (TT_CMap_Info_GetFunc)tt_cmap14_get_info )
+    (TT_CMap_ValidateFunc)tt_cmap14_validate,  /* validate      */
+    (TT_CMap_Info_GetFunc)tt_cmap14_get_info   /* get_cmap_info */
+  )
 
 #endif /* TT_CONFIG_CMAP_FORMAT_14 */
 
@@ -3737,7 +3756,7 @@
               error = clazz->validate( cmap, FT_VALIDATOR( &valid ) );
             }
 
-            if ( valid.validator.error == 0 )
+            if ( !valid.validator.error )
             {
               FT_CMap  ttcmap;
 
@@ -3763,7 +3782,7 @@
           }
         }
 
-        if ( *pclazz == NULL )
+        if ( !*pclazz )
         {
           FT_TRACE0(( "tt_face_build_cmaps:"
                       " unsupported cmap sub-table ignored\n" ));
diff --git a/src/sfnt/ttcmap.h b/src/sfnt/ttcmap.h
index 2273cbd..83f12df 100644
--- a/src/sfnt/ttcmap.h
+++ b/src/sfnt/ttcmap.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType character mapping table (cmap) support (specification).     */
 /*                                                                         */
-/*  Copyright 2002-2016 by                                                 */
+/*  Copyright 2002-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttcmapc.h b/src/sfnt/ttcmapc.h
index 7c732fb..9a5e708 100644
--- a/src/sfnt/ttcmapc.h
+++ b/src/sfnt/ttcmapc.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TT CMAP classes definitions (specification only).                    */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttkern.c b/src/sfnt/ttkern.c
index 6f9fa52..78dc5eb 100644
--- a/src/sfnt/ttkern.c
+++ b/src/sfnt/ttkern.c
@@ -5,7 +5,7 @@
 /*    Load the basic TrueType kerning table.  This doesn't handle          */
 /*    kerning data within the GPOS table at the moment.                    */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttkern.h b/src/sfnt/ttkern.h
index 85dd5c3..db1a30b 100644
--- a/src/sfnt/ttkern.h
+++ b/src/sfnt/ttkern.h
@@ -5,7 +5,7 @@
 /*    Load the basic TrueType kerning table.  This doesn't handle          */
 /*    kerning data within the GPOS table at the moment.                    */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c
index a653a71..4695253 100644
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -5,7 +5,7 @@
 /*    Load the basic TrueType tables, i.e., tables that can be either in   */
 /*    TTF or OTF fonts (body).                                             */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -679,7 +679,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    tt_face_load_max_profile                                           */
+  /*    tt_face_load_maxp                                                  */
   /*                                                                       */
   /* <Description>                                                         */
   /*    Loads the maximum profile into a face object.                      */
@@ -808,7 +808,6 @@
     FT_Memory     memory = stream->memory;
     FT_ULong      table_pos, table_len;
     FT_ULong      storage_start, storage_limit;
-    FT_UInt       count;
     TT_NameTable  table;
 
     static const FT_Frame_Field  name_table_fields[] =
@@ -826,7 +825,7 @@
     static const FT_Frame_Field  name_record_fields[] =
     {
 #undef  FT_STRUCTURE
-#define FT_STRUCTURE  TT_NameEntryRec
+#define FT_STRUCTURE  TT_NameRec
 
       /* no FT_FRAME_START */
         FT_FRAME_USHORT( platformID ),
@@ -838,6 +837,17 @@
       FT_FRAME_END
     };
 
+    static const FT_Frame_Field  langTag_record_fields[] =
+    {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  TT_LangTagRec
+
+      /* no FT_FRAME_START */
+        FT_FRAME_USHORT( stringLength ),
+        FT_FRAME_USHORT( stringOffset ),
+      FT_FRAME_END
+    };
+
 
     table         = &face->name_table;
     table->stream = stream;
@@ -848,18 +858,17 @@
 
     table_pos = FT_STREAM_POS();
 
-
     if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )
       goto Exit;
 
-    /* Some popular Asian fonts have an invalid `storageOffset' value   */
-    /* (it should be at least "6 + 12*num_names").  However, the string */
-    /* offsets, computed as "storageOffset + entry->stringOffset", are  */
-    /* valid pointers within the name table...                          */
-    /*                                                                  */
-    /* We thus can't check `storageOffset' right now.                   */
-    /*                                                                  */
-    storage_start = table_pos + 6 + 12*table->numNameRecords;
+    /* Some popular Asian fonts have an invalid `storageOffset' value (it */
+    /* should be at least `6 + 12*numNameRecords').  However, the string  */
+    /* offsets, computed as `storageOffset + entry->stringOffset', are    */
+    /* valid pointers within the name table...                            */
+    /*                                                                    */
+    /* We thus can't check `storageOffset' right now.                     */
+    /*                                                                    */
+    storage_start = table_pos + 6 + 12 * table->numNameRecords;
     storage_limit = table_pos + table_len;
 
     if ( storage_start > storage_limit )
@@ -869,18 +878,56 @@
       goto Exit;
     }
 
-    /* Allocate the array of name records. */
-    count                 = table->numNameRecords;
-    table->numNameRecords = 0;
+    /* `name' format 1 contains additional language tag records, */
+    /* which we load first                                       */
+    if ( table->format == 1 )
+    {
+      if ( FT_STREAM_SEEK( storage_start )            ||
+           FT_READ_USHORT( table->numLangTagRecords ) )
+        goto Exit;
 
-    if ( FT_NEW_ARRAY( table->names, count ) ||
-         FT_FRAME_ENTER( count * 12 )        )
+      storage_start += 2 + 4 * table->numLangTagRecords;
+
+      /* allocate language tag records array */
+      if ( FT_NEW_ARRAY( table->langTags, table->numLangTagRecords ) ||
+           FT_FRAME_ENTER( table->numLangTagRecords * 4 )            )
+        goto Exit;
+
+      /* load language tags */
+      {
+        TT_LangTag  entry = table->langTags;
+        TT_LangTag  limit = entry + table->numLangTagRecords;
+
+
+        for ( ; entry < limit; entry++ )
+        {
+          (void)FT_STREAM_READ_FIELDS( langTag_record_fields, entry );
+
+          /* check that the langTag string is within the table */
+          entry->stringOffset += table_pos + table->storageOffset;
+          if ( entry->stringOffset                       < storage_start ||
+               entry->stringOffset + entry->stringLength > storage_limit )
+          {
+            /* invalid entry; ignore it */
+            entry->stringLength = 0;
+          }
+        }
+      }
+
+      FT_FRAME_EXIT();
+
+      (void)FT_STREAM_SEEK( table_pos + 6 );
+    }
+
+    /* allocate name records array */
+    if ( FT_NEW_ARRAY( table->names, table->numNameRecords ) ||
+         FT_FRAME_ENTER( table->numNameRecords * 12 )        )
       goto Exit;
 
-    /* Load the name records and determine how much storage is needed */
-    /* to hold the strings themselves.                                */
+    /* load name records */
     {
-      TT_NameEntryRec*  entry = table->names;
+      TT_Name  entry = table->names;
+      FT_UInt  count = table->numNameRecords;
 
 
       for ( ; count > 0; count-- )
@@ -897,22 +944,37 @@
         if ( entry->stringOffset                       < storage_start ||
              entry->stringOffset + entry->stringLength > storage_limit )
         {
-          /* invalid entry - ignore it */
-          entry->stringOffset = 0;
-          entry->stringLength = 0;
+          /* invalid entry; ignore it */
           continue;
         }
 
+        /* assure that we have a valid language tag ID, and   */
+        /* that the corresponding langTag entry is valid, too */
+        if ( table->format == 1 && entry->languageID >= 0x8000U )
+        {
+          if ( entry->languageID - 0x8000U >= table->numLangTagRecords    ||
+               !table->langTags[entry->languageID - 0x8000U].stringLength )
+          {
+            /* invalid entry; ignore it */
+            continue;
+          }
+        }
+
         entry++;
       }
 
-      table->numNameRecords = (FT_UInt)( entry - table->names );
+      /* reduce array size to the actually used elements */
+      count = (FT_UInt)( entry - table->names );
+      (void)FT_RENEW_ARRAY( table->names,
+                            table->numNameRecords,
+                            count );
+      table->numNameRecords = count;
     }
 
     FT_FRAME_EXIT();
 
     /* everything went well, update face->num_names */
-    face->num_names = (FT_UShort) table->numNameRecords;
+    face->num_names = (FT_UShort)table->numNameRecords;
 
   Exit:
     return error;
@@ -935,25 +997,36 @@
   {
     FT_Memory     memory = face->root.driver->root.memory;
     TT_NameTable  table  = &face->name_table;
-    TT_NameEntry  entry  = table->names;
-    FT_UInt       count  = table->numNameRecords;
 
 
     if ( table->names )
     {
-      for ( ; count > 0; count--, entry++ )
-      {
-        FT_FREE( entry->string );
-        entry->stringLength = 0;
-      }
+      TT_Name  entry = table->names;
+      TT_Name  limit = entry + table->numNameRecords;
 
-      /* free strings table */
+
+      for ( ; entry < limit; entry++ )
+        FT_FREE( entry->string );
+
       FT_FREE( table->names );
     }
 
-    table->numNameRecords = 0;
-    table->format         = 0;
-    table->storageOffset  = 0;
+    if ( table->langTags )
+    {
+      TT_LangTag  entry = table->langTags;
+      TT_LangTag  limit = entry + table->numLangTagRecords;
+
+
+      for ( ; entry < limit; entry++ )
+        FT_FREE( entry->string );
+
+      FT_FREE( table->langTags );
+    }
+
+    table->numNameRecords    = 0;
+    table->numLangTagRecords = 0;
+    table->format            = 0;
+    table->storageOffset     = 0;
   }
 
 
diff --git a/src/sfnt/ttload.h b/src/sfnt/ttload.h
index bec42b9..296da86 100644
--- a/src/sfnt/ttload.h
+++ b/src/sfnt/ttload.h
@@ -5,7 +5,7 @@
 /*    Load the basic TrueType tables, i.e., tables that can be either in   */
 /*    TTF or OTF fonts (specification).                                    */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c
index 186f873..394c6db 100644
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Load the metrics tables common to TTF and OTF fonts (body).          */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -20,11 +20,24 @@
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_STREAM_H
 #include FT_TRUETYPE_TAGS_H
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#include FT_SERVICE_METRICS_VARIATIONS_H
+#endif
+
 #include "ttmtx.h"
 
 #include "sferrors.h"
 
 
+  /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should   */
+  /*            be identical except for the names of their fields,      */
+  /*            which are different.                                    */
+  /*                                                                    */
+  /*            This ensures that `tt_face_load_hmtx' is able to read   */
+  /*            both the horizontal and vertical headers.               */
+
+
   /*************************************************************************/
   /*                                                                       */
   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
@@ -214,6 +227,11 @@
     FT_ULong        table_pos, table_size, table_end;
     FT_UShort       k;
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    FT_Service_MetricsVariations  var =
+      (FT_Service_MetricsVariations)face->var;
+#endif
+
 
     if ( vertical )
     {
@@ -274,6 +292,34 @@
       *abearing = 0;
       *aadvance = 0;
     }
+
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    if ( var )
+    {
+      FT_Face  f = FT_FACE( face );
+      FT_Int   a = (FT_Int)*aadvance;
+      FT_Int   b = (FT_Int)*abearing;
+
+
+      if ( vertical )
+      {
+        if ( var->vadvance_adjust )
+          var->vadvance_adjust( f, gindex, &a );
+        if ( var->tsb_adjust )
+          var->tsb_adjust( f, gindex, &b );
+      }
+      else
+      {
+        if ( var->hadvance_adjust )
+          var->hadvance_adjust( f, gindex, &a );
+        if ( var->lsb_adjust )
+          var->lsb_adjust( f, gindex, &b );
+      }
+
+      *aadvance = (FT_UShort)a;
+      *abearing = (FT_Short)b;
+    }
+#endif
   }
 
 
diff --git a/src/sfnt/ttmtx.h b/src/sfnt/ttmtx.h
index 78395de..2b93ab2 100644
--- a/src/sfnt/ttmtx.h
+++ b/src/sfnt/ttmtx.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Load the metrics tables common to TTF and OTF fonts (specification). */
 /*                                                                         */
-/*  Copyright 2006-2016 by                                                 */
+/*  Copyright 2006-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttpost.c b/src/sfnt/ttpost.c
index 3277f1e..6548e85 100644
--- a/src/sfnt/ttpost.c
+++ b/src/sfnt/ttpost.c
@@ -5,7 +5,7 @@
 /*    PostScript name table processing for TrueType and OpenType fonts     */
 /*    (body).                                                              */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -326,7 +326,9 @@
       goto Exit;
 
     /* check the number of glyphs */
-    if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 )
+    if ( num_glyphs > face->max_profile.numGlyphs ||
+         num_glyphs > 258                         ||
+         num_glyphs < 1                           )
     {
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
diff --git a/src/sfnt/ttpost.h b/src/sfnt/ttpost.h
index ede45fd..722485e 100644
--- a/src/sfnt/ttpost.h
+++ b/src/sfnt/ttpost.h
@@ -5,7 +5,7 @@
 /*    PostScript name table processing for TrueType and OpenType fonts     */
 /*    (specification).                                                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/sfnt/ttsbit.c b/src/sfnt/ttsbit.c
index ba89672..9829593 100644
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType and OpenType embedded bitmap support (body).                */
 /*                                                                         */
-/*  Copyright 2005-2016 by                                                 */
+/*  Copyright 2005-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  Copyright 2013 by Google, Inc.                                         */
@@ -107,8 +107,12 @@
         version     = FT_NEXT_LONG( p );
         num_strikes = FT_NEXT_ULONG( p );
 
+        /* there's at least one font (FZShuSong-Z01, version 3)   */
+        /* that uses the wrong byte order for the `version' field */
         if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL &&
-             ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00030000UL )
+             ( (FT_ULong)version & 0x0000FFFFUL ) != 0x00000200UL &&
+             ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00030000UL &&
+             ( (FT_ULong)version & 0x0000FFFFUL ) != 0x00000300UL )
         {
           error = FT_THROW( Unknown_File_Format );
           goto Exit;
@@ -193,12 +197,14 @@
       break;
 
     default:
+      /* we ignore unknown table formats */
       error = FT_THROW( Unknown_File_Format );
       break;
     }
 
     if ( !error )
-      FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes ));
+      FT_TRACE3(( "tt_face_load_sbit_strikes: found %u strikes\n",
+                  face->sbit_num_strikes ));
 
     face->ebdt_start = 0;
     face->ebdt_size  = 0;
@@ -228,6 +234,15 @@
       }
     }
 
+    if ( !face->ebdt_size )
+    {
+      FT_TRACE2(( "tt_face_load_sbit_strikes:"
+                  " no embedded bitmap data table found;\n"
+                  "                          "
+                  " resetting number of strikes to zero\n" ));
+      face->sbit_num_strikes = 0;
+    }
+
     return FT_Err_Ok;
 
   Exit:
diff --git a/src/sfnt/ttsbit.h b/src/sfnt/ttsbit.h
index d8a8167..e859ddd 100644
--- a/src/sfnt/ttsbit.h
+++ b/src/sfnt/ttsbit.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType and OpenType embedded bitmap support (specification).       */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 30fd4e2..1fe558d 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    A new `perfect' anti-aliasing renderer (body).                       */
 /*                                                                         */
-/*  Copyright 2000-2016 by                                                 */
+/*  Copyright 2000-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -286,6 +286,10 @@
 #define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )
 #endif
 
+#ifndef FT_ZERO
+#define FT_ZERO( p )  FT_MEM_ZERO( p, sizeof ( *(p) ) )
+#endif
+
   /* as usual, for the speed hungry :-) */
 
 #undef RAS_ARG
@@ -337,7 +341,8 @@
 
   /* Compute `dividend / divisor' and return both its quotient and     */
   /* remainder, cast to a specific type.  This macro also ensures that */
-  /* the remainder is always positive.                                 */
+  /* the remainder is always positive.  We use the remainder to keep   */
+  /* track of accumulating errors and compensate for them.             */
 #define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
   FT_BEGIN_STMNT                                                   \
     (quotient)  = (type)( (dividend) / (divisor) );                \
@@ -371,8 +376,9 @@
 
   /* These macros speed up repetitive divisions by replacing them */
   /* with multiplications and right shifts.                       */
-#define FT_UDIVPREP( b )                                       \
-  long  b ## _r = (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b )
+#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 ) )
@@ -438,6 +444,7 @@
     TCoord  cover;
     int     invalid;
 
+    PCell*      ycells;
     PCell       cells;
     FT_PtrDist  max_cells;
     FT_PtrDist  num_cells;
@@ -450,8 +457,6 @@
     FT_Raster_Span_Func  render_span;
     void*                render_span_data;
 
-    PCell*     ycells;
-
   } gray_TWorker, *gray_PWorker;
 
 #if defined( _MSC_VER )
@@ -504,8 +509,8 @@
   /*                                                                       */
   /* Record the current cell in the table.                                 */
   /*                                                                       */
-  static PCell
-  gray_find_cell( RAS_ARG )
+  static void
+  gray_record_cell( RAS_ARG )
   {
     PCell  *pcell, cell;
     TCoord  x = ras.ex;
@@ -515,11 +520,11 @@
     for (;;)
     {
       cell = *pcell;
-      if ( cell == NULL || cell->x > x )
+      if ( !cell || cell->x > x )
         break;
 
       if ( cell->x == x )
-        goto Exit;
+        goto Found;
 
       pcell = &cell->next;
     }
@@ -527,30 +532,21 @@
     if ( ras.num_cells >= ras.max_cells )
       ft_longjmp( ras.jump_buffer, 1 );
 
+    /* insert new cell */
     cell        = ras.cells + ras.num_cells++;
     cell->x     = x;
-    cell->area  = 0;
-    cell->cover = 0;
+    cell->area  = ras.area;
+    cell->cover = ras.cover;
 
     cell->next  = *pcell;
     *pcell      = cell;
 
-  Exit:
-    return cell;
-  }
+    return;
 
-
-  static void
-  gray_record_cell( RAS_ARG )
-  {
-    if ( ras.area | ras.cover )
-    {
-      PCell  cell = gray_find_cell( RAS_VAR );
-
-
-      cell->area  += ras.area;
-      cell->cover += ras.cover;
-    }
+  Found:
+    /* update old cell */
+    cell->area  += ras.area;
+    cell->cover += ras.cover;
   }
 
 
@@ -572,9 +568,6 @@
     /* Note that if a cell is to the left of the clipping region, it is    */
     /* actually set to the (min_ex-1) horizontal position.                 */
 
-    /* All cells that are on the left of the clipping region go to the */
-    /* min_ex - 1 horizontal position.                                 */
-
     if ( ex < ras.min_ex )
       ex = ras.min_ex - 1;
 
@@ -605,7 +598,7 @@
                                  TPos    x2,
                                  TCoord  y2 )
   {
-    TCoord  ex1, ex2, fx1, fx2, first, delta, mod;
+    TCoord  ex1, ex2, fx1, fx2, first, dy, delta, mod;
     TPos    p, dx;
     int     incr;
 
@@ -622,31 +615,27 @@
 
     fx1   = (TCoord)( x1 - SUBPIXELS( ex1 ) );
     fx2   = (TCoord)( x2 - SUBPIXELS( ex2 ) );
-    delta = y2 - y1;
 
     /* everything is located in a single cell.  That is easy! */
     /*                                                        */
     if ( ex1 == ex2 )
-    {
-      ras.area  += (TArea)(( fx1 + fx2 ) * delta);
-      ras.cover += delta;
-      return;
-    }
+      goto End;
 
     /* ok, we'll have to render a run of adjacent cells on the same */
     /* scanline...                                                  */
     /*                                                              */
     dx = x2 - x1;
+    dy = y2 - y1;
 
     if ( dx > 0 )
     {
-      p     = ( ONE_PIXEL - fx1 ) * delta;
+      p     = ( ONE_PIXEL - fx1 ) * dy;
       first = ONE_PIXEL;
       incr  = 1;
     }
     else
     {
-      p     = fx1 * delta;
+      p     = fx1 * dy;
       first = 0;
       incr  = -1;
       dx    = -dx;
@@ -654,34 +643,31 @@
 
     FT_DIV_MOD( TCoord, p, dx, delta, mod );
 
-    ras.area  += (TArea)(( fx1 + first ) * delta);
+    ras.area  += (TArea)( ( fx1 + first ) * delta );
     ras.cover += delta;
-
-    ex1 += incr;
+    y1        += delta;
+    ex1       += incr;
     gray_set_cell( RAS_VAR_ ex1, ey );
-    y1  += delta;
 
     if ( ex1 != ex2 )
     {
       TCoord  lift, rem;
 
 
-      p = ONE_PIXEL * ( y2 - y1 + delta );
+      p = ONE_PIXEL * dy;
       FT_DIV_MOD( TCoord, p, dx, lift, rem );
 
-      mod -= (int)dx;
-
       do
       {
         delta = lift;
         mod  += rem;
-        if ( mod >= 0 )
+        if ( mod >= (TCoord)dx )
         {
           mod -= (TCoord)dx;
           delta++;
         }
 
-        ras.area  += (TArea)(ONE_PIXEL * delta);
+        ras.area  += (TArea)( ONE_PIXEL * delta );
         ras.cover += delta;
         y1        += delta;
         ex1       += incr;
@@ -689,9 +675,13 @@
       } while ( ex1 != ex2 );
     }
 
-    delta      = y2 - y1;
-    ras.area  += (TArea)(( fx2 + ONE_PIXEL - first ) * delta);
-    ras.cover += delta;
+    fx1 = ONE_PIXEL - first;
+
+  End:
+    dy = y2 - y1;
+
+    ras.area  += (TArea)( ( fx1 + fx2 ) * dy );
+    ras.cover += dy;
   }
 
 
@@ -803,13 +793,12 @@
 
       p    = ONE_PIXEL * dx;
       FT_DIV_MOD( TCoord, p, dy, lift, rem );
-      mod -= (TCoord)dy;
 
       do
       {
         delta = lift;
         mod  += rem;
-        if ( mod >= 0 )
+        if ( mod >= (TCoord)dy )
         {
           mod -= (TCoord)dy;
           delta++;
@@ -899,8 +888,8 @@
     else                                  /* any other line */
     {
       TPos  prod = dx * fy1 - dy * fx1;
-      FT_UDIVPREP( dx );
-      FT_UDIVPREP( dy );
+      FT_UDIVPREP( ex1 != ex2, dx );
+      FT_UDIVPREP( ey1 != ey2, dy );
 
 
       /* The fundamental value `prod' determines which side and the  */
@@ -1307,29 +1296,23 @@
     int  y;
 
 
-    if ( ras.num_cells == 0 )
-      return;
-
     FT_TRACE7(( "gray_sweep: start\n" ));
 
     for ( y = ras.min_ey; y < ras.max_ey; y++ )
     {
       PCell   cell  = ras.ycells[y - ras.min_ey];
-      TCoord  cover = 0;
       TCoord  x     = ras.min_ex;
+      TArea   cover = 0;
+      TArea   area;
 
 
       for ( ; cell != NULL; cell = cell->next )
       {
-        TArea  area;
-
-
         if ( cover != 0 && cell->x > x )
-          gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ),
-                      cell->x - x );
+          gray_hline( RAS_VAR_ x, y, cover, cell->x - x );
 
-        cover += cell->cover;
-        area   = (TArea)cover * ( ONE_PIXEL * 2 ) - cell->area;
+        cover += (TArea)cell->cover * ( ONE_PIXEL * 2 );
+        area   = cover - cell->area;
 
         if ( area != 0 && cell->x >= ras.min_ex )
           gray_hline( RAS_VAR_ cell->x, y, area, 1 );
@@ -1338,8 +1321,7 @@
       }
 
       if ( cover != 0 )
-        gray_hline( RAS_VAR_ x, y, (TArea)cover * ( ONE_PIXEL * 2 ),
-                    ras.max_ex - x );
+        gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x );
     }
 
     FT_TRACE7(( "gray_sweep: end\n" ));
@@ -1621,7 +1603,7 @@
     return 0;
 
   Exit:
-    FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));
+    FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error ));
     return error;
 
   Invalid_Outline:
@@ -1709,12 +1691,14 @@
   FT_DEFINE_OUTLINE_FUNCS(
     func_interface,
 
-    (FT_Outline_MoveTo_Func) gray_move_to,
-    (FT_Outline_LineTo_Func) gray_line_to,
-    (FT_Outline_ConicTo_Func)gray_conic_to,
-    (FT_Outline_CubicTo_Func)gray_cubic_to,
-    0,
-    0 )
+    (FT_Outline_MoveTo_Func) gray_move_to,   /* move_to  */
+    (FT_Outline_LineTo_Func) gray_line_to,   /* line_to  */
+    (FT_Outline_ConicTo_Func)gray_conic_to,  /* conic_to */
+    (FT_Outline_CubicTo_Func)gray_cubic_to,  /* cubic_to */
+
+    0,                                       /* shift    */
+    0                                        /* delta    */
+  )
 
 
   static int
@@ -1797,18 +1781,15 @@
           cell_start = ( ycount * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) /
                        sizeof ( TCell );
 
-          if ( FT_MAX_GRAY_POOL - cell_start < 2 )
-            goto ReduceBands;
-
           ras.cells     = buffer + cell_start;
           ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - cell_start );
+          ras.num_cells = 0;
 
           ras.ycells = (PCell*)buffer;
           while ( ycount )
             ras.ycells[--ycount] = NULL;
         }
 
-        ras.num_cells = 0;
         ras.invalid   = 1;
         ras.min_ey    = band[1];
         ras.max_ey    = band[0];
@@ -1824,7 +1805,6 @@
         else if ( error != ErrRaster_Memory_Overflow )
           return 1;
 
-      ReduceBands:
         /* render pool overflow; we will reduce the render band by half */
         width >>= 1;
 
@@ -1850,8 +1830,8 @@
   gray_raster_render( FT_Raster                raster,
                       const FT_Raster_Params*  params )
   {
-    const FT_Outline*  outline     = (const FT_Outline*)params->source;
-    const FT_Bitmap*   target_map  = params->target;
+    const FT_Outline*  outline    = (const FT_Outline*)params->source;
+    const FT_Bitmap*   target_map = params->target;
     FT_BBox            cbox, clip;
 
 #ifndef FT_STATIC_RASTER
@@ -1975,7 +1955,7 @@
 
 
     *araster = (FT_Raster)&the_raster;
-    FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
+    FT_ZERO( &the_raster );
 
     return 0;
   }
@@ -2051,11 +2031,12 @@
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Raster_New_Func)     gray_raster_new,
-    (FT_Raster_Reset_Func)   gray_raster_reset,
-    (FT_Raster_Set_Mode_Func)gray_raster_set_mode,
-    (FT_Raster_Render_Func)  gray_raster_render,
-    (FT_Raster_Done_Func)    gray_raster_done )
+    (FT_Raster_New_Func)     gray_raster_new,       /* raster_new      */
+    (FT_Raster_Reset_Func)   gray_raster_reset,     /* raster_reset    */
+    (FT_Raster_Set_Mode_Func)gray_raster_set_mode,  /* raster_set_mode */
+    (FT_Raster_Render_Func)  gray_raster_render,    /* raster_render   */
+    (FT_Raster_Done_Func)    gray_raster_done       /* raster_done     */
+  )
 
 
 /* END */
diff --git a/src/smooth/ftgrays.h b/src/smooth/ftgrays.h
index 21c2bad..a5447da 100644
--- a/src/smooth/ftgrays.h
+++ b/src/smooth/ftgrays.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType smooth renderer declaration                                 */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftsmerrs.h b/src/smooth/ftsmerrs.h
index a759b91..a528c61 100644
--- a/src/smooth/ftsmerrs.h
+++ b/src/smooth/ftsmerrs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    smooth renderer error codes (specification only).                    */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index 7927676..c9292df 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Anti-aliasing renderer interface (body).                             */
 /*                                                                         */
-/*  Copyright 2000-2016 by                                                 */
+/*  Copyright 2000-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -87,7 +87,7 @@
                       FT_GlyphSlot  slot,
                       FT_BBox*      cbox )
   {
-    FT_MEM_ZERO( cbox, sizeof ( *cbox ) );
+    FT_ZERO( cbox );
 
     if ( slot->format == render->glyph_format )
       FT_Outline_Get_CBox( &slot->outline, cbox );
@@ -114,8 +114,8 @@
 #ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
     FT_Pos       height_org, width_org;
 #endif
-    FT_Int       hmul    = mode == FT_RENDER_MODE_LCD;
-    FT_Int       vmul    = mode == FT_RENDER_MODE_LCD_V;
+    FT_Int       hmul    = ( mode == FT_RENDER_MODE_LCD );
+    FT_Int       vmul    = ( mode == FT_RENDER_MODE_LCD_V );
 
     FT_Raster_Params  params;
 
@@ -428,7 +428,8 @@
   }
 
 
-  FT_DEFINE_RENDERER( ft_smooth_renderer_class,
+  FT_DEFINE_RENDERER(
+    ft_smooth_renderer_class,
 
       FT_MODULE_RENDERER,
       sizeof ( FT_RendererRec ),
@@ -437,25 +438,25 @@
       0x10000L,
       0x20000L,
 
-      0,    /* module specific interface */
+      NULL,    /* module specific interface */
 
-      (FT_Module_Constructor)ft_smooth_init,
-      (FT_Module_Destructor) 0,
-      (FT_Module_Requester)  0
-    ,
+      (FT_Module_Constructor)ft_smooth_init,  /* module_init   */
+      (FT_Module_Destructor) NULL,            /* module_done   */
+      (FT_Module_Requester)  NULL,            /* get_interface */
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Renderer_RenderFunc)   ft_smooth_render,
-    (FT_Renderer_TransformFunc)ft_smooth_transform,
-    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,
-    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,
+    (FT_Renderer_RenderFunc)   ft_smooth_render,     /* render_glyph    */
+    (FT_Renderer_TransformFunc)ft_smooth_transform,  /* transform_glyph */
+    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,   /* get_glyph_cbox  */
+    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,   /* set_mode        */
 
-    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET
+    (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET           /* raster_class    */
   )
 
 
-  FT_DEFINE_RENDERER( ft_smooth_lcd_renderer_class,
+  FT_DEFINE_RENDERER(
+    ft_smooth_lcd_renderer_class,
 
       FT_MODULE_RENDERER,
       sizeof ( FT_RendererRec ),
@@ -464,24 +465,25 @@
       0x10000L,
       0x20000L,
 
-      0,    /* module specific interface */
+      NULL,    /* module specific interface */
 
-      (FT_Module_Constructor)ft_smooth_init,
-      (FT_Module_Destructor) 0,
-      (FT_Module_Requester)  0
-    ,
+      (FT_Module_Constructor)ft_smooth_init,  /* module_init   */
+      (FT_Module_Destructor) NULL,            /* module_done   */
+      (FT_Module_Requester)  NULL,            /* get_interface */
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd,
-    (FT_Renderer_TransformFunc)ft_smooth_transform,
-    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,
-    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,
+    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd,  /* render_glyph    */
+    (FT_Renderer_TransformFunc)ft_smooth_transform,   /* transform_glyph */
+    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,    /* get_glyph_cbox  */
+    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,    /* set_mode        */
 
-    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET
+    (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET            /* raster_class    */
   )
 
-  FT_DEFINE_RENDERER( ft_smooth_lcdv_renderer_class,
+
+  FT_DEFINE_RENDERER(
+    ft_smooth_lcdv_renderer_class,
 
       FT_MODULE_RENDERER,
       sizeof ( FT_RendererRec ),
@@ -490,21 +492,20 @@
       0x10000L,
       0x20000L,
 
-      0,    /* module specific interface */
+      NULL,    /* module specific interface */
 
-      (FT_Module_Constructor)ft_smooth_init,
-      (FT_Module_Destructor) 0,
-      (FT_Module_Requester)  0
-    ,
+      (FT_Module_Constructor)ft_smooth_init,  /* module_init   */
+      (FT_Module_Destructor) NULL,            /* module_done   */
+      (FT_Module_Requester)  NULL,            /* get_interface */
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd_v,
-    (FT_Renderer_TransformFunc)ft_smooth_transform,
-    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,
-    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,
+    (FT_Renderer_RenderFunc)   ft_smooth_render_lcd_v,  /* render_glyph    */
+    (FT_Renderer_TransformFunc)ft_smooth_transform,     /* transform_glyph */
+    (FT_Renderer_GetCBoxFunc)  ft_smooth_get_cbox,      /* get_glyph_cbox  */
+    (FT_Renderer_SetModeFunc)  ft_smooth_set_mode,      /* set_mode        */
 
-    (FT_Raster_Funcs*)    &FT_GRAYS_RASTER_GET
+    (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET              /* raster_class    */
   )
 
 
diff --git a/src/smooth/ftsmooth.h b/src/smooth/ftsmooth.h
index c7c28c2..929e260 100644
--- a/src/smooth/ftsmooth.h
+++ b/src/smooth/ftsmooth.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Anti-aliasing renderer interface (specification).                    */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftspic.c b/src/smooth/ftspic.c
index 6c2b232..fb89be3 100644
--- a/src/smooth/ftspic.c
+++ b/src/smooth/ftspic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for smooth module.   */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/ftspic.h b/src/smooth/ftspic.h
index fe76152..9ddd1c7 100644
--- a/src/smooth/ftspic.h
+++ b/src/smooth/ftspic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for smooth module.   */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/smooth/smooth.c b/src/smooth/smooth.c
index 97ca3e5..200f5dc 100644
--- a/src/smooth/smooth.c
+++ b/src/smooth/smooth.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType anti-aliasing rasterer module component (body only).        */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/truetype.c b/src/truetype/truetype.c
index 23e2ea0..4866103 100644
--- a/src/truetype/truetype.c
+++ b/src/truetype/truetype.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType TrueType driver component (body only).                      */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c
index b96a227..6f9b746 100644
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType font driver implementation (body).                          */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -25,6 +25,7 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 #include FT_MULTIPLE_MASTERS_H
 #include FT_SERVICE_MULTIPLE_MASTERS_H
+#include FT_SERVICE_METRICS_VARIATIONS_H
 #endif
 
 #include FT_SERVICE_TRUETYPE_ENGINE_H
@@ -144,8 +145,10 @@
 
   FT_DEFINE_SERVICE_PROPERTIESREC(
     tt_service_properties,
+
     (FT_Properties_SetFunc)tt_property_set,     /* set_property */
-    (FT_Properties_GetFunc)tt_property_get )    /* get_property */
+    (FT_Properties_GetFunc)tt_property_get      /* get_property */
+  )
 
 
   /*************************************************************************/
@@ -221,13 +224,20 @@
                    FT_Fixed  *advances )
   {
     FT_UInt  nn;
-    TT_Face  face = (TT_Face) ttface;
+    TT_Face  face = (TT_Face)ttface;
 
 
     /* XXX: TODO: check for sbits */
 
     if ( flags & FT_LOAD_VERTICAL_LAYOUT )
     {
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      /* no fast retrieval for blended MM fonts without VVAR table */
+      if ( !face->is_default_instance                               &&
+           !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+        return FT_THROW( Unimplemented_Feature );
+#endif
+
       for ( nn = 0; nn < count; nn++ )
       {
         FT_Short   tsb;
@@ -241,6 +251,13 @@
     }
     else
     {
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+      /* no fast retrieval for blended MM fonts without HVAR table */
+      if ( !face->is_default_instance                               &&
+           !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
+        return FT_THROW( Unimplemented_Feature );
+#endif
+
       for ( nn = 0; nn < count; nn++ )
       {
         FT_Short   lsb;
@@ -287,7 +304,7 @@
       /* use the scaled metrics, even when tt_size_reset fails */
       FT_Select_Metrics( size->face, strike_index );
 
-      tt_size_reset( ttsize ); /* ignore return value */
+      tt_size_reset( ttsize, 0 ); /* ignore return value */
     }
     else
     {
@@ -337,7 +354,7 @@
 
     if ( FT_IS_SCALABLE( size->face ) )
     {
-      error = tt_size_reset( ttsize );
+      error                = tt_size_reset( ttsize, 0 );
       ttsize->root.metrics = ttsize->metrics;
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
@@ -462,14 +479,38 @@
   /*************************************************************************/
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+
   FT_DEFINE_SERVICE_MULTIMASTERSREC(
     tt_service_gx_multi_masters,
+
     (FT_Get_MM_Func)        NULL,                   /* get_mm         */
     (FT_Set_MM_Design_Func) NULL,                   /* set_mm_design  */
     (FT_Set_MM_Blend_Func)  TT_Set_MM_Blend,        /* set_mm_blend   */
+    (FT_Get_MM_Blend_Func)  TT_Get_MM_Blend,        /* get_mm_blend   */
     (FT_Get_MM_Var_Func)    TT_Get_MM_Var,          /* get_mm_var     */
-    (FT_Set_Var_Design_Func)TT_Set_Var_Design )     /* set_var_design */
-#endif
+    (FT_Set_Var_Design_Func)TT_Set_Var_Design,      /* set_var_design */
+    (FT_Get_Var_Design_Func)TT_Get_Var_Design,      /* get_var_design */
+
+    (FT_Get_Var_Blend_Func) tt_get_var_blend,       /* get_var_blend  */
+    (FT_Done_Blend_Func)    tt_done_blend           /* done_blend     */
+  )
+
+  FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
+    tt_service_metrics_variations,
+
+    (FT_HAdvance_Adjust_Func)tt_hadvance_adjust,     /* hadvance_adjust */
+    (FT_LSB_Adjust_Func)     NULL,                   /* lsb_adjust      */
+    (FT_RSB_Adjust_Func)     NULL,                   /* rsb_adjust      */
+
+    (FT_VAdvance_Adjust_Func)tt_vadvance_adjust,     /* vadvance_adjust */
+    (FT_TSB_Adjust_Func)     NULL,                   /* tsb_adjust      */
+    (FT_BSB_Adjust_Func)     NULL,                   /* bsb_adjust      */
+    (FT_VOrg_Adjust_Func)    NULL,                   /* vorg_adjust     */
+
+    (FT_Metrics_Adjust_Func) tt_apply_mvar           /* metrics_adjust  */
+  )
+
+#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
 
   static const FT_Service_TrueTypeEngineRec  tt_service_truetype_engine =
@@ -488,20 +529,25 @@
 
   FT_DEFINE_SERVICE_TTGLYFREC(
     tt_service_truetype_glyf,
-    (TT_Glyf_GetLocationFunc)tt_face_get_location )    /* get_location */
+
+    (TT_Glyf_GetLocationFunc)tt_face_get_location      /* get_location */
+  )
 
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-  FT_DEFINE_SERVICEDESCREC5(
+  FT_DEFINE_SERVICEDESCREC6(
     tt_services,
-    FT_SERVICE_ID_FONT_FORMAT,     FT_FONT_FORMAT_TRUETYPE,
-    FT_SERVICE_ID_MULTI_MASTERS,   &TT_SERVICE_GX_MULTI_MASTERS_GET,
-    FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
-    FT_SERVICE_ID_TT_GLYF,         &TT_SERVICE_TRUETYPE_GLYF_GET,
-    FT_SERVICE_ID_PROPERTIES,      &TT_SERVICE_PROPERTIES_GET )
+
+    FT_SERVICE_ID_FONT_FORMAT,        FT_FONT_FORMAT_TRUETYPE,
+    FT_SERVICE_ID_MULTI_MASTERS,      &TT_SERVICE_GX_MULTI_MASTERS_GET,
+    FT_SERVICE_ID_METRICS_VARIATIONS, &TT_SERVICE_METRICS_VARIATIONS_GET,
+    FT_SERVICE_ID_TRUETYPE_ENGINE,    &tt_service_truetype_engine,
+    FT_SERVICE_ID_TT_GLYF,            &TT_SERVICE_TRUETYPE_GLYF_GET,
+    FT_SERVICE_ID_PROPERTIES,         &TT_SERVICE_PROPERTIES_GET )
 #else
   FT_DEFINE_SERVICEDESCREC4(
     tt_services,
+
     FT_SERVICE_ID_FONT_FORMAT,     FT_FONT_FORMAT_TRUETYPE,
     FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine,
     FT_SERVICE_ID_TT_GLYF,         &TT_SERVICE_TRUETYPE_GLYF_GET,
@@ -529,7 +575,7 @@
 #endif
 
     result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface );
-    if ( result != NULL )
+    if ( result )
       return result;
 
 #ifndef FT_CONFIG_OPTION_PIC
@@ -580,7 +626,7 @@
       0x10000L,        /* driver version == 1.0                 */
       0x20000L,        /* driver requires FreeType 2.0 or above */
 
-      0,    /* module-specific interface */
+      NULL,    /* module-specific interface */
 
       tt_driver_init,           /* FT_Module_Constructor  module_init   */
       tt_driver_done,           /* FT_Module_Destructor   module_done   */
@@ -595,12 +641,12 @@
     tt_size_init,               /* FT_Size_InitFunc  init_size */
     tt_size_done,               /* FT_Size_DoneFunc  done_size */
     tt_slot_init,               /* FT_Slot_InitFunc  init_slot */
-    0,                          /* FT_Slot_DoneFunc  done_slot */
+    NULL,                       /* FT_Slot_DoneFunc  done_slot */
 
     tt_glyph_load,              /* FT_Slot_LoadFunc  load_glyph */
 
     tt_get_kerning,             /* FT_Face_GetKerningFunc   get_kerning  */
-    0,                          /* FT_Face_AttachFunc       attach_file  */
+    NULL,                       /* FT_Face_AttachFunc       attach_file  */
     tt_get_advances,            /* FT_Face_GetAdvancesFunc  get_advances */
 
     tt_size_request,            /* FT_Size_RequestFunc  request_size */
diff --git a/src/truetype/ttdriver.h b/src/truetype/ttdriver.h
index 74392bb..3bcba7f 100644
--- a/src/truetype/ttdriver.h
+++ b/src/truetype/ttdriver.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level TrueType driver interface (specification).                */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/tterrors.h b/src/truetype/tterrors.h
index 895989f..a49f205 100644
--- a/src/truetype/tterrors.h
+++ b/src/truetype/tterrors.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType error codes (specification only).                           */
 /*                                                                         */
-/*  Copyright 2001-2016 by                                                 */
+/*  Copyright 2001-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 2d0b29f..64dc05c 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Glyph Loader (body).                                        */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -398,18 +398,18 @@
 
     FT_TRACE5(( "  Instructions size: %u\n", n_ins ));
 
-    /* check it */
-    if ( ( limit - p ) < n_ins )
-    {
-      FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
-      error = FT_THROW( Too_Many_Hints );
-      goto Fail;
-    }
-
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
     if ( IS_HINTED( load->load_flags ) )
     {
+      /* check instructions size */
+      if ( ( limit - p ) < n_ins )
+      {
+        FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
+        error = FT_THROW( Too_Many_Hints );
+        goto Fail;
+      }
+
       /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
       /* and thus update the bytecode array size by ourselves       */
 
@@ -441,7 +441,7 @@
     flag       = (FT_Byte*)outline->tags;
     flag_limit = flag + n_points;
 
-    FT_ASSERT( flag != NULL );
+    FT_ASSERT( flag );
 
     while ( flag < flag_limit )
     {
@@ -886,13 +886,23 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
-    if ( loader->face->doblend )
+    if ( loader->face->doblend && !loader->face->is_default_instance )
     {
       /* Deltas apply to the unscaled data. */
       error = TT_Vary_Apply_Glyph_Deltas( loader->face,
                                           loader->glyph_index,
                                           outline,
                                           (FT_UInt)n_points );
+
+      /* 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 = outline->points[n_points - 3].x -
+                         outline->points[n_points - 4].x;
+      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+        loader->vadvance = outline->points[n_points - 1].x -
+                           outline->points[n_points - 2].x;
+
       if ( error )
         return error;
     }
@@ -1487,7 +1497,7 @@
       offset            = 0;
       loader->byte_len  = glyph_data.length;
 
-      FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) );
+      FT_ZERO( &inc_stream );
       FT_Stream_OpenMemory( &inc_stream,
                             glyph_data.pointer,
                             (FT_ULong)glyph_data.length );
@@ -1505,10 +1515,10 @@
     {
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
       /* for the incremental interface, `glyf_offset' is always zero */
-      if ( !loader->glyf_offset                        &&
+      if ( !face->glyf_offset                          &&
            !face->root.internal->incremental_interface )
 #else
-      if ( !loader->glyf_offset )
+      if ( !face->glyf_offset )
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
       {
         FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
@@ -1517,7 +1527,7 @@
       }
 
       error = face->access_glyph_frame( loader, glyph_index,
-                                        loader->glyf_offset + offset,
+                                        face->glyf_offset + offset,
                                         (FT_UInt)loader->byte_len );
       if ( error )
         goto Exit;
@@ -1564,7 +1574,7 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
-      if ( loader->face->doblend )
+      if ( loader->face->doblend && !loader->face->is_default_instance )
       {
         /* a small outline structure with four elements for */
         /* communication with `TT_Vary_Apply_Glyph_Deltas'  */
@@ -1607,6 +1617,14 @@
         loader->pp3.y = points[2].y;
         loader->pp4.x = points[3].x;
         loader->pp4.y = points[3].y;
+
+
+        /* 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;
+        if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+          loader->vadvance = loader->pp4.x - loader->pp3.x;
       }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1727,7 +1745,7 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
-      if ( face->doblend )
+      if ( face->doblend && !face->is_default_instance )
       {
         short        i, limit;
         FT_SubGlyph  subglyph;
@@ -1796,11 +1814,11 @@
 
         /* this call provides additional offsets */
         /* for each component's translation      */
-        if ( ( error = TT_Vary_Apply_Glyph_Deltas(
-                         face,
-                         glyph_index,
-                         &outline,
-                         (FT_UInt)outline.n_points ) ) != 0 )
+        if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
+                             face,
+                             glyph_index,
+                             &outline,
+                             (FT_UInt)outline.n_points ) ) )
           goto Exit1;
 
         subglyph = gloader->current.subglyphs;
@@ -1824,6 +1842,13 @@
         loader->pp4.x = points[i + 3].x;
         loader->pp4.y = points[i + 3].y;
 
+        /* 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;
+        if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
+          loader->vadvance = loader->pp4.x - loader->pp3.x;
+
       Exit1:
         FT_FREE( outline.points );
         FT_FREE( outline.tags );
@@ -1883,6 +1908,9 @@
         {
           FT_Vector  pp[4];
 
+          FT_Int  linear_hadvance;
+          FT_Int  linear_vadvance;
+
 
           /* Each time we call load_truetype_glyph in this loop, the   */
           /* value of `gloader.base.subglyphs' can change due to table */
@@ -1895,6 +1923,9 @@
           pp[2] = loader->pp3;
           pp[3] = loader->pp4;
 
+          linear_hadvance = loader->linear;
+          linear_vadvance = loader->vadvance;
+
           num_base_points = (FT_UInt)gloader->base.outline.n_points;
 
           error = load_truetype_glyph( loader,
@@ -1914,6 +1945,9 @@
             loader->pp2 = pp[1];
             loader->pp3 = pp[2];
             loader->pp4 = pp[3];
+
+            loader->linear   = linear_hadvance;
+            loader->vadvance = linear_vadvance;
           }
 
           num_points = (FT_UInt)gloader->base.outline.n_points;
@@ -2252,7 +2286,7 @@
     face   = (TT_Face)glyph->face;
     stream = face->root.stream;
 
-    FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) );
+    FT_ZERO( loader );
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
@@ -2497,32 +2531,6 @@
 
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
-    /* seek to the beginning of the glyph table -- for Type 42 fonts     */
-    /* the table might be accessed from a Postscript stream or something */
-    /* else...                                                           */
-
-#ifdef FT_CONFIG_OPTION_INCREMENTAL
-
-    if ( face->root.internal->incremental_interface )
-      loader->glyf_offset = 0;
-    else
-
-#endif
-
-    {
-      error = face->goto_table( face, TTAG_glyf, stream, 0 );
-
-      if ( FT_ERR_EQ( error, Table_Missing ) )
-        loader->glyf_offset = 0;
-      else if ( error )
-      {
-        FT_ERROR(( "tt_loader_init: could not access glyph table\n" ));
-        return error;
-      }
-      else
-        loader->glyf_offset = FT_STREAM_POS();
-    }
-
     /* get face's glyph loader */
     if ( !glyf_table_only )
     {
@@ -2593,17 +2601,21 @@
     FT_Error      error;
     TT_LoaderRec  loader;
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+#define IS_DEFAULT_INSTANCE  ( ( (TT_Face)glyph->face )->is_default_instance )
+#else
+#define IS_DEFAULT_INSTANCE  1
+#endif
+
 
     FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
-    /* try to load embedded bitmap if any              */
-    /*                                                 */
-    /* XXX: The convention should be emphasized in     */
-    /*      the documents because it can be confusing. */
+    /* try to load embedded bitmap (if any) */
     if ( size->strike_index != 0xFFFFFFFFUL      &&
-         ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
+         ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
+         IS_DEFAULT_INSTANCE                     )
     {
       error = load_sbit_image( size, glyph, glyph_index, load_flags );
       if ( !error )
@@ -2637,14 +2649,20 @@
 
     /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
     if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
-      return FT_THROW( Invalid_Size_Handle );
+    {
+      error = FT_THROW( Invalid_Size_Handle );
+      goto Exit;
+    }
 
     if ( load_flags & FT_LOAD_SBITS_ONLY )
-      return FT_THROW( Invalid_Argument );
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Exit;
+    }
 
     error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
     if ( error )
-      return error;
+      goto Exit;
 
     glyph->format        = FT_GLYPH_FORMAT_OUTLINE;
     glyph->num_subglyphs = 0;
@@ -2719,6 +2737,13 @@
          size->root.metrics.y_ppem < 24     )
       glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
 
+  Exit:
+#ifdef FT_DEBUG_LEVEL_TRACE
+    if ( error )
+      FT_TRACE1(( "  failed (error code 0x%x)\n",
+                  error ));
+#endif
+
     return error;
   }
 
diff --git a/src/truetype/ttgload.h b/src/truetype/ttgload.h
index bfa29e4..1dd6c84 100644
--- a/src/truetype/ttgload.h
+++ b/src/truetype/ttgload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Glyph Loader (specification).                               */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index c0d013c..0168120 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType GX Font Variation loader                                    */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.     */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -22,10 +22,6 @@
   /*                                                                       */
   /*   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html */
   /*                                                                       */
-  /* The documentation for `fvar' is inconsistent.  At one point it says   */
-  /* that `countSizePairs' should be 3, at another point 2.  It should     */
-  /* be 2.                                                                 */
-  /*                                                                       */
   /* The documentation for `gvar' is not intelligible; `cvar' refers you   */
   /* to `gvar' and is thus also incomprehensible.                          */
   /*                                                                       */
@@ -50,6 +46,7 @@
 #include FT_INTERNAL_SFNT_H
 #include FT_TRUETYPE_TAGS_H
 #include FT_MULTIPLE_MASTERS_H
+#include FT_LIST_H
 
 #include "ttpload.h"
 #include "ttgxvar.h"
@@ -346,7 +343,7 @@
 
     if ( axisCount != (FT_Long)blend->mmvar->num_axis )
     {
-      FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `cvar'\n"
+      FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `fvar'\n"
                   "                  table are different\n" ));
       goto Exit;
     }
@@ -380,7 +377,7 @@
         segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4;
         segment->correspondence[j].toCoord   = FT_GET_SHORT() * 4;
 
-        FT_TRACE5(( "    mapping %.4f to %.4f\n",
+        FT_TRACE5(( "    mapping %.5f to %.5f\n",
                     segment->correspondence[j].fromCoord / 65536.0,
                     segment->correspondence[j].toCoord / 65536.0 ));
       }
@@ -393,6 +390,985 @@
   }
 
 
+  /* some macros we need */
+  #define FT_FIXED_ONE  ( (FT_Fixed)0x10000 )
+
+  #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 ) )
+
+
+  static FT_Error
+  ft_var_load_item_variation_store( TT_Face          face,
+                                    FT_ULong         offset,
+                                    GX_ItemVarStore  itemStore )
+  {
+    FT_Stream  stream = FT_FACE_STREAM( face );
+    FT_Memory  memory = stream->memory;
+
+    FT_Error   error;
+    FT_UShort  format;
+    FT_ULong   region_offset;
+    FT_UInt    i, j, k;
+    FT_UInt    shortDeltaCount;
+
+    GX_Blend        blend = face->blend;
+    GX_ItemVarData  varData;
+
+    FT_ULong*  dataOffsetArray = NULL;
+
+
+    if ( FT_STREAM_SEEK( offset ) ||
+         FT_READ_USHORT( format ) )
+      goto Exit;
+
+    if ( format != 1 )
+    {
+      FT_TRACE2(( "ft_var_load_item_variation_store: bad store format %d\n",
+                  format ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    /* read top level fields */
+    if ( FT_READ_ULONG( region_offset )         ||
+         FT_READ_USHORT( itemStore->dataCount ) )
+      goto Exit;
+
+    /* we need at least one entry in `itemStore->varData' */
+    if ( !itemStore->dataCount )
+    {
+      FT_TRACE2(( "ft_var_load_item_variation_store: missing varData\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    /* make temporary copy of item variation data offsets; */
+    /* we will parse region list first, then come back     */
+    if ( FT_NEW_ARRAY( dataOffsetArray, itemStore->dataCount ) )
+      goto Exit;
+
+    for ( i = 0; i < itemStore->dataCount; i++ )
+    {
+      if ( FT_READ_ULONG( dataOffsetArray[i] ) )
+        goto Exit;
+    }
+
+    /* parse array of region records (region list) */
+    if ( FT_STREAM_SEEK( offset + region_offset ) )
+      goto Exit;
+
+    if ( FT_READ_USHORT( itemStore->axisCount )   ||
+         FT_READ_USHORT( itemStore->regionCount ) )
+      goto Exit;
+
+    if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis )
+    {
+      FT_TRACE2(( "ft_var_load_item_variation_store:"
+                  " number of axes in item variation store\n"
+                  "                                 "
+                  " and `fvar' table are different\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) )
+      goto Exit;
+
+    for ( i = 0; i < itemStore->regionCount; i++ )
+    {
+      GX_AxisCoords  axisCoords;
+
+
+      if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList,
+                         itemStore->axisCount ) )
+        goto Exit;
+
+      axisCoords = itemStore->varRegionList[i].axisList;
+
+      for ( j = 0; j < itemStore->axisCount; j++ )
+      {
+        FT_Short  start, peak, end;
+
+
+        if ( FT_READ_SHORT( start ) ||
+             FT_READ_SHORT( peak )  ||
+             FT_READ_SHORT( end )   )
+          goto Exit;
+
+        axisCoords[j].startCoord = FT_fdot14ToFixed( start );
+        axisCoords[j].peakCoord  = FT_fdot14ToFixed( peak );
+        axisCoords[j].endCoord   = FT_fdot14ToFixed( end );
+      }
+    }
+
+    /* end of region list parse */
+
+    /* use dataOffsetArray now to parse varData items */
+    if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) )
+      goto Exit;
+
+    for ( i = 0; i < itemStore->dataCount; i++ )
+    {
+      varData = &itemStore->varData[i];
+
+      if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) )
+        goto Exit;
+
+      if ( FT_READ_USHORT( varData->itemCount )      ||
+           FT_READ_USHORT( shortDeltaCount )         ||
+           FT_READ_USHORT( varData->regionIdxCount ) )
+        goto Exit;
+
+      /* check some data consistency */
+      if ( shortDeltaCount > varData->regionIdxCount )
+      {
+        FT_TRACE2(( "bad short count %d or region count %d\n",
+                    shortDeltaCount,
+                    varData->regionIdxCount ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      if ( varData->regionIdxCount > itemStore->regionCount )
+      {
+        FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n",
+                    varData->regionIdxCount,
+                    i ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      /* parse region indices */
+      if ( FT_NEW_ARRAY( varData->regionIndices,
+                         varData->regionIdxCount ) )
+        goto Exit;
+
+      for ( j = 0; j < varData->regionIdxCount; j++ )
+      {
+        if ( FT_READ_USHORT( varData->regionIndices[j] ) )
+          goto Exit;
+
+        if ( varData->regionIndices[j] >= itemStore->regionCount )
+        {
+          FT_TRACE2(( "bad region index %d\n",
+                      varData->regionIndices[j] ));
+          error = FT_THROW( Invalid_Table );
+          goto Exit;
+        }
+      }
+
+      /* Parse delta set.                                                */
+      /*                                                                 */
+      /* On input, deltas are (shortDeltaCount + regionIdxCount) bytes   */
+      /* each; on output, deltas are expanded to `regionIdxCount' shorts */
+      /* each.                                                           */
+      if ( FT_NEW_ARRAY( varData->deltaSet,
+                         varData->regionIdxCount * varData->itemCount ) )
+        goto Exit;
+
+      /* the delta set is stored as a 2-dimensional array of shorts; */
+      /* sign-extend signed bytes to signed shorts                   */
+      for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
+      {
+        for ( k = 0; k < shortDeltaCount; k++, j++ )
+        {
+          /* read the short deltas */
+          FT_Short  delta;
+
+
+          if ( FT_READ_SHORT( delta ) )
+            goto Exit;
+
+          varData->deltaSet[j] = delta;
+        }
+
+        for ( ; k < varData->regionIdxCount; k++, j++ )
+        {
+          /* read the (signed) byte deltas */
+          FT_Char  delta;
+
+
+          if ( FT_READ_CHAR( delta ) )
+            goto Exit;
+
+          varData->deltaSet[j] = delta;
+        }
+      }
+    }
+
+  Exit:
+    FT_FREE( dataOffsetArray );
+
+    return error;
+  }
+
+
+  static FT_Error
+  ft_var_load_delta_set_index_mapping( TT_Face            face,
+                                       FT_ULong           offset,
+                                       GX_DeltaSetIdxMap  map,
+                                       GX_ItemVarStore    itemStore )
+  {
+    FT_Stream  stream = FT_FACE_STREAM( face );
+    FT_Memory  memory = stream->memory;
+
+    FT_Error   error;
+
+    FT_UShort  format;
+    FT_UInt    entrySize;
+    FT_UInt    innerBitCount;
+    FT_UInt    innerIndexMask;
+    FT_UInt    i, j;
+
+
+    if ( FT_STREAM_SEEK( offset )        ||
+         FT_READ_USHORT( format )        ||
+         FT_READ_USHORT( map->mapCount ) )
+      goto Exit;
+
+    if ( format & 0xFFC0 )
+    {
+      FT_TRACE2(( "bad map format %d\n", format ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    /* bytes per entry: 1, 2, 3, or 4 */
+    entrySize      = ( ( format & 0x0030 ) >> 4 ) + 1;
+    innerBitCount  = ( format & 0x000F ) + 1;
+    innerIndexMask = ( 1 << innerBitCount ) - 1;
+
+    if ( FT_NEW_ARRAY( map->innerIndex, map->mapCount ) )
+      goto Exit;
+
+    if ( FT_NEW_ARRAY( map->outerIndex, map->mapCount ) )
+      goto Exit;
+
+    for ( i = 0; i < map->mapCount; i++ )
+    {
+      FT_UInt  mapData = 0;
+      FT_UInt  outerIndex, innerIndex;
+
+
+      /* read map data one unsigned byte at a time, big endian */
+      for ( j = 0; j < entrySize; j++ )
+      {
+        FT_Byte  data;
+
+
+        if ( FT_READ_BYTE( data ) )
+          goto Exit;
+
+        mapData = ( mapData << 8 ) | data;
+      }
+
+      outerIndex = mapData >> innerBitCount;
+
+      if ( outerIndex >= itemStore->dataCount )
+      {
+        FT_TRACE2(( "outerIndex[%d] == %d out of range\n",
+                    i,
+                    outerIndex ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
+      }
+
+      map->outerIndex[i] = outerIndex;
+
+      innerIndex = mapData & innerIndexMask;
+
+      if ( innerIndex >= itemStore->varData[outerIndex].itemCount )
+      {
+        FT_TRACE2(( "innerIndex[%d] == %d out of range\n",
+                    i,
+                    innerIndex ));
+        error = FT_THROW( Invalid_Table );
+          goto Exit;
+      }
+
+      map->innerIndex[i] = innerIndex;
+    }
+
+  Exit:
+    return error;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    ft_var_load_hvvar                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    If `vertical' is zero, parse the `HVAR' table and set              */
+  /*    `blend->hvar_loaded' to TRUE.  On success, `blend->hvar_checked'   */
+  /*    is set to TRUE.                                                    */
+  /*                                                                       */
+  /*    If `vertical' is not zero, parse the `VVAR' table and set          */
+  /*    `blend->vvar_loaded' to TRUE.  On success, `blend->vvar_checked'   */
+  /*    is set to TRUE.                                                    */
+  /*                                                                       */
+  /*    Some memory may remain allocated on error; it is always freed in   */
+  /*    `tt_done_blend', however.                                          */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    face :: The font face.                                             */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  static FT_Error
+  ft_var_load_hvvar( TT_Face  face,
+                     FT_Bool  vertical )
+  {
+    FT_Stream  stream = FT_FACE_STREAM( face );
+    FT_Memory  memory = stream->memory;
+
+    GX_Blend  blend = face->blend;
+
+    GX_HVVarTable  table;
+
+    FT_Error   error;
+    FT_UShort  majorVersion;
+    FT_ULong   table_len;
+    FT_ULong   table_offset;
+    FT_ULong   store_offset;
+    FT_ULong   widthMap_offset;
+
+
+    if ( vertical )
+    {
+      blend->vvar_loaded = TRUE;
+
+      FT_TRACE2(( "VVAR " ));
+
+      error = face->goto_table( face, TTAG_VVAR, stream, &table_len );
+    }
+    else
+    {
+      blend->hvar_loaded = TRUE;
+
+      FT_TRACE2(( "HVAR " ));
+
+      error = face->goto_table( face, TTAG_HVAR, stream, &table_len );
+    }
+
+    if ( error )
+    {
+      FT_TRACE2(( "is missing\n" ));
+      goto Exit;
+    }
+
+    table_offset = FT_STREAM_POS();
+
+    /* skip minor version */
+    if ( FT_READ_USHORT( majorVersion ) ||
+         FT_STREAM_SKIP( 2 )            )
+      goto Exit;
+
+    if ( majorVersion != 1 )
+    {
+      FT_TRACE2(( "bad table version %d\n", majorVersion ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    if ( FT_READ_ULONG( store_offset )    ||
+         FT_READ_ULONG( widthMap_offset ) )
+      goto Exit;
+
+    if ( vertical )
+    {
+      if ( FT_NEW( blend->vvar_table ) )
+        goto Exit;
+      table = blend->vvar_table;
+    }
+    else
+    {
+      if ( FT_NEW( blend->hvar_table ) )
+        goto Exit;
+      table = blend->hvar_table;
+    }
+
+    error = ft_var_load_item_variation_store(
+              face,
+              table_offset + store_offset,
+              &table->itemStore );
+    if ( error )
+      goto Exit;
+
+    if ( widthMap_offset )
+    {
+      error = ft_var_load_delta_set_index_mapping(
+                face,
+                table_offset + widthMap_offset,
+                &table->widthMap,
+                &table->itemStore );
+      if ( error )
+        goto Exit;
+    }
+
+    FT_TRACE2(( "loaded\n" ));
+    error = FT_Err_Ok;
+
+  Exit:
+    if ( !error )
+    {
+      if ( vertical )
+      {
+        blend->vvar_checked = TRUE;
+
+        /* FreeType doesn't provide functions to quickly retrieve    */
+        /* TSB, BSB, or VORG values; we thus don't have to implement */
+        /* support for those three item variation stores.            */
+
+        face->variation_support |= TT_FACE_FLAG_VAR_VADVANCE;
+      }
+      else
+      {
+        blend->hvar_checked = TRUE;
+
+        /* FreeType doesn't provide functions to quickly retrieve */
+        /* LSB or RSB values; we thus don't have to implement     */
+        /* support for those two item variation stores.           */
+
+        face->variation_support |= TT_FACE_FLAG_VAR_HADVANCE;
+      }
+    }
+
+    return error;
+  }
+
+
+  static FT_Int
+  ft_var_get_item_delta( TT_Face          face,
+                         GX_ItemVarStore  itemStore,
+                         FT_UInt          outerIndex,
+                         FT_UInt          innerIndex )
+  {
+    GX_ItemVarData  varData;
+    FT_Short*       deltaSet;
+
+    FT_UInt   master, j;
+    FT_Fixed  netAdjustment = 0;     /* accumulated adjustment */
+    FT_Fixed  scaledDelta;
+    FT_Fixed  delta;
+
+
+    /* See pseudo code from `Font Variations Overview' */
+    /* in the OpenType specification.                  */
+
+    varData  = &itemStore->varData[outerIndex];
+    deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex];
+
+    /* outer loop steps through master designs to be blended */
+    for ( master = 0; master < varData->regionIdxCount; master++ )
+    {
+      FT_Fixed  scalar      = FT_FIXED_ONE;
+      FT_UInt   regionIndex = varData->regionIndices[master];
+
+      GX_AxisCoords  axis = itemStore->varRegionList[regionIndex].axisList;
+
+
+      /* inner loop steps through axes in this region */
+      for ( j = 0; j < itemStore->axisCount; j++, axis++ )
+      {
+        FT_Fixed  axisScalar;
+
+
+        /* compute the scalar contribution of this axis; */
+        /* ignore invalid ranges                         */
+        if ( axis->startCoord > axis->peakCoord ||
+             axis->peakCoord > axis->endCoord   )
+          axisScalar = FT_FIXED_ONE;
+
+        else if ( axis->startCoord < 0 &&
+                  axis->endCoord > 0   &&
+                  axis->peakCoord != 0 )
+          axisScalar = FT_FIXED_ONE;
+
+        /* peak of 0 means ignore this axis */
+        else if ( axis->peakCoord == 0 )
+          axisScalar = FT_FIXED_ONE;
+
+        /* ignore this region if coords are out of range */
+        else if ( face->blend->normalizedcoords[j] < axis->startCoord ||
+                  face->blend->normalizedcoords[j] > axis->endCoord   )
+          axisScalar = 0;
+
+        /* calculate a proportional factor */
+        else
+        {
+          if ( face->blend->normalizedcoords[j] == axis->peakCoord )
+            axisScalar = FT_FIXED_ONE;
+          else if ( face->blend->normalizedcoords[j] < axis->peakCoord )
+            axisScalar =
+              FT_DivFix( face->blend->normalizedcoords[j] - axis->startCoord,
+                         axis->peakCoord - axis->startCoord );
+          else
+            axisScalar =
+              FT_DivFix( axis->endCoord - face->blend->normalizedcoords[j],
+                         axis->endCoord - axis->peakCoord );
+        }
+
+        /* take product of all the axis scalars */
+        scalar = FT_MulFix( scalar, axisScalar );
+
+      } /* per-axis loop */
+
+      /* get the scaled delta for this region */
+      delta       = FT_intToFixed( deltaSet[master] );
+      scaledDelta = FT_MulFix( scalar, delta );
+
+      /* accumulate the adjustments from each region */
+      netAdjustment = netAdjustment + scaledDelta;
+
+    } /* per-region loop */
+
+    return FT_fixedToInt( netAdjustment );
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    tt_hvadvance_adjust                                                */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Apply `HVAR' advance width or `VVAR' advance height adjustment of  */
+  /*    a given glyph.                                                     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    gindex   :: The glyph index.                                       */
+  /*                                                                       */
+  /*    vertical :: If set, handle `VVAR' table.                           */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    face     :: The font face.                                         */
+  /*                                                                       */
+  /*    adelta   :: Points to width or height value that gets modified.    */
+  /*                                                                       */
+  static FT_Error
+  tt_hvadvance_adjust( TT_Face  face,
+                       FT_UInt  gindex,
+                       FT_Int  *avalue,
+                       FT_Bool  vertical )
+  {
+    FT_Error  error = FT_Err_Ok;
+    FT_UInt   innerIndex, outerIndex;
+    FT_Int    delta;
+
+    GX_HVVarTable  table;
+
+
+    if ( !face->doblend || !face->blend )
+      goto Exit;
+
+    if ( vertical )
+    {
+      if ( !face->blend->vvar_loaded )
+      {
+        /* initialize vvar table */
+        face->blend->vvar_error = ft_var_load_hvvar( face, 1 );
+      }
+
+      if ( !face->blend->vvar_checked )
+      {
+        error = face->blend->vvar_error;
+        goto Exit;
+      }
+
+      table = face->blend->vvar_table;
+    }
+    else
+    {
+      if ( !face->blend->hvar_loaded )
+      {
+        /* initialize hvar table */
+        face->blend->hvar_error = ft_var_load_hvvar( face, 0 );
+      }
+
+      if ( !face->blend->hvar_checked )
+      {
+        error = face->blend->hvar_error;
+        goto Exit;
+      }
+
+      table = face->blend->hvar_table;
+    }
+
+    /* advance width or height adjustments are always present in an */
+    /* `HVAR' or `VVAR' table; no need to test for this capability  */
+
+    if ( table->widthMap.innerIndex )
+    {
+      if ( gindex >= table->widthMap.mapCount )
+      {
+        FT_TRACE2(( "gindex %d out of range\n", gindex ));
+        error = FT_THROW( Invalid_Argument );
+        goto Exit;
+      }
+
+      /* trust that HVAR parser has checked indices */
+      outerIndex = table->widthMap.outerIndex[gindex];
+      innerIndex = table->widthMap.innerIndex[gindex];
+    }
+    else
+    {
+      GX_ItemVarData  varData;
+
+
+      /* no widthMap data */
+      outerIndex = 0;
+      innerIndex = gindex;
+
+      varData = &table->itemStore.varData[outerIndex];
+      if ( gindex >= varData->itemCount )
+      {
+        FT_TRACE2(( "gindex %d out of range\n", gindex ));
+        error = FT_THROW( Invalid_Argument );
+        goto Exit;
+      }
+    }
+
+    delta = ft_var_get_item_delta( face,
+                                   &table->itemStore,
+                                   outerIndex,
+                                   innerIndex );
+
+    FT_TRACE5(( "%s value %d adjusted by %d units (%s)\n",
+                vertical ? "vertical height" : "horizontal width",
+                *avalue,
+                delta,
+                vertical ? "VVAR" : "HVAR" ));
+
+    *avalue += delta;
+
+  Exit:
+    return error;
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
+  tt_hadvance_adjust( TT_Face  face,
+                      FT_UInt  gindex,
+                      FT_Int  *avalue )
+  {
+    return tt_hvadvance_adjust( face, gindex, avalue, 0 );
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
+  tt_vadvance_adjust( TT_Face  face,
+                      FT_UInt  gindex,
+                      FT_Int  *avalue )
+  {
+    return tt_hvadvance_adjust( face, gindex, avalue, 1 );
+  }
+
+
+#define GX_VALUE_SIZE  8
+
+  /* all values are FT_Short or FT_UShort entities; */
+  /* we treat them consistently as FT_Short         */
+#define GX_VALUE_CASE( tag, dflt )      \
+          case MVAR_TAG_ ## tag :       \
+            p = (FT_Short*)&face->dflt; \
+            break
+
+#define GX_GASP_CASE( idx )                                       \
+          case MVAR_TAG_GASP_ ## idx :                            \
+            if ( idx < face->gasp.numRanges - 1 )                 \
+              p = (FT_Short*)&face->gasp.gaspRanges[idx].maxPPEM; \
+            else                                                  \
+              p = NULL;                                           \
+            break
+
+
+  static FT_Short*
+  ft_var_get_value_pointer( TT_Face   face,
+                            FT_ULong  mvar_tag )
+  {
+    FT_Short*  p;
+
+
+    switch ( mvar_tag )
+    {
+      GX_GASP_CASE( 0 );
+      GX_GASP_CASE( 1 );
+      GX_GASP_CASE( 2 );
+      GX_GASP_CASE( 3 );
+      GX_GASP_CASE( 4 );
+      GX_GASP_CASE( 5 );
+      GX_GASP_CASE( 6 );
+      GX_GASP_CASE( 7 );
+      GX_GASP_CASE( 8 );
+      GX_GASP_CASE( 9 );
+
+      GX_VALUE_CASE( CPHT, os2.sCapHeight );
+      GX_VALUE_CASE( HASC, os2.sTypoAscender );
+      GX_VALUE_CASE( HCLA, os2.usWinAscent );
+      GX_VALUE_CASE( HCLD, os2.usWinDescent );
+      GX_VALUE_CASE( HCOF, horizontal.caret_Offset );
+      GX_VALUE_CASE( HCRN, horizontal.caret_Slope_Run );
+      GX_VALUE_CASE( HCRS, horizontal.caret_Slope_Rise );
+      GX_VALUE_CASE( HDSC, os2.sTypoDescender );
+      GX_VALUE_CASE( HLGP, os2.sTypoLineGap );
+      GX_VALUE_CASE( SBXO, os2.ySubscriptXOffset);
+      GX_VALUE_CASE( SBXS, os2.ySubscriptXSize );
+      GX_VALUE_CASE( SBYO, os2.ySubscriptYOffset );
+      GX_VALUE_CASE( SBYS, os2.ySubscriptYSize );
+      GX_VALUE_CASE( SPXO, os2.ySuperscriptXOffset );
+      GX_VALUE_CASE( SPXS, os2.ySuperscriptXSize );
+      GX_VALUE_CASE( SPYO, os2.ySuperscriptYOffset );
+      GX_VALUE_CASE( SPYS, os2.ySuperscriptYSize );
+      GX_VALUE_CASE( STRO, os2.yStrikeoutPosition );
+      GX_VALUE_CASE( STRS, os2.yStrikeoutSize );
+      GX_VALUE_CASE( UNDO, postscript.underlinePosition );
+      GX_VALUE_CASE( UNDS, postscript.underlineThickness );
+      GX_VALUE_CASE( VASC, vertical.Ascender );
+      GX_VALUE_CASE( VCOF, vertical.caret_Offset );
+      GX_VALUE_CASE( VCRN, vertical.caret_Slope_Run );
+      GX_VALUE_CASE( VCRS, vertical.caret_Slope_Rise );
+      GX_VALUE_CASE( VDSC, vertical.Descender );
+      GX_VALUE_CASE( VLGP, vertical.Line_Gap );
+      GX_VALUE_CASE( XHGT, os2.sxHeight );
+
+    default:
+      /* ignore unknown tag */
+      p = NULL;
+    }
+
+    return p;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    ft_var_load_mvar                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Parse the `MVAR' table.                                            */
+  /*                                                                       */
+  /*    Some memory may remain allocated on error; it is always freed in   */
+  /*    `tt_done_blend', however.                                          */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    face :: The font face.                                             */
+  /*                                                                       */
+  static void
+  ft_var_load_mvar( TT_Face  face )
+  {
+    FT_Stream  stream = FT_FACE_STREAM( face );
+    FT_Memory  memory = stream->memory;
+
+    GX_Blend         blend = face->blend;
+    GX_ItemVarStore  itemStore;
+    GX_Value         value, limit;
+
+    FT_Error   error;
+    FT_UShort  majorVersion;
+    FT_ULong   table_len;
+    FT_ULong   table_offset;
+    FT_UShort  store_offset;
+    FT_ULong   records_offset;
+
+
+    FT_TRACE2(( "MVAR " ));
+
+    error = face->goto_table( face, TTAG_MVAR, stream, &table_len );
+    if ( error )
+    {
+      FT_TRACE2(( "is missing\n" ));
+      return;
+    }
+
+    table_offset = FT_STREAM_POS();
+
+    /* skip minor version */
+    if ( FT_READ_USHORT( majorVersion ) ||
+         FT_STREAM_SKIP( 2 )            )
+      return;
+
+    if ( majorVersion != 1 )
+    {
+      FT_TRACE2(( "bad table version %d\n", majorVersion ));
+      return;
+    }
+
+    if ( FT_NEW( blend->mvar_table ) )
+      return;
+
+    /* skip reserved entry and value record size */
+    if ( FT_STREAM_SKIP( 4 )                             ||
+         FT_READ_USHORT( blend->mvar_table->valueCount ) ||
+         FT_READ_USHORT( store_offset )                  )
+      return;
+
+    records_offset = FT_STREAM_POS();
+
+    error = ft_var_load_item_variation_store(
+              face,
+              table_offset + store_offset,
+              &blend->mvar_table->itemStore );
+    if ( error )
+      return;
+
+    if ( FT_NEW_ARRAY( blend->mvar_table->values,
+                       blend->mvar_table->valueCount ) )
+      return;
+
+    if ( FT_STREAM_SEEK( records_offset )                                ||
+         FT_FRAME_ENTER( blend->mvar_table->valueCount * GX_VALUE_SIZE ) )
+      return;
+
+    value     = blend->mvar_table->values;
+    limit     = value + blend->mvar_table->valueCount;
+    itemStore = &blend->mvar_table->itemStore;
+
+    for ( ; value < limit; value++ )
+    {
+      value->tag        = FT_GET_ULONG();
+      value->outerIndex = FT_GET_USHORT();
+      value->innerIndex = FT_GET_USHORT();
+
+      if ( value->outerIndex >= itemStore->dataCount                  ||
+           value->innerIndex >= itemStore->varData[value->outerIndex]
+                                                  .itemCount          )
+      {
+        error = FT_THROW( Invalid_Table );
+        break;
+      }
+    }
+
+    FT_FRAME_EXIT();
+
+    if ( error )
+      return;
+
+    FT_TRACE2(( "loaded\n" ));
+
+    value = blend->mvar_table->values;
+    limit = value + blend->mvar_table->valueCount;
+
+    /* save original values of the data MVAR is going to modify */
+    for ( ; value < limit; value++ )
+    {
+      FT_Short*  p = ft_var_get_value_pointer( face, value->tag );
+
+
+      value->unmodified = *p;
+    }
+
+    face->variation_support |= TT_FACE_FLAG_VAR_MVAR;
+  }
+
+
+  static FT_Error
+  tt_size_reset_iterator( FT_ListNode  node,
+                          void*        user )
+  {
+    TT_Size  size = (TT_Size)node->data;
+
+    FT_UNUSED( user );
+
+
+    tt_size_reset( size, 1 );
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    tt_apply_mvar                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Apply `MVAR' table adjustments.                                    */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    face :: The font face.                                             */
+  /*                                                                       */
+  FT_LOCAL_DEF( void )
+  tt_apply_mvar( TT_Face  face )
+  {
+    GX_Blend  blend = face->blend;
+    GX_Value  value, limit;
+
+
+    if ( !( face->variation_support & TT_FACE_FLAG_VAR_MVAR ) )
+      return;
+
+    value = blend->mvar_table->values;
+    limit = value + blend->mvar_table->valueCount;
+
+    for ( ; value < limit; value++ )
+    {
+      FT_Short*  p = ft_var_get_value_pointer( face, value->tag );
+      FT_Int     delta;
+
+
+      delta = ft_var_get_item_delta( face,
+                                     &blend->mvar_table->itemStore,
+                                     value->outerIndex,
+                                     value->innerIndex );
+
+      FT_TRACE5(( "value %c%c%c%c (%d units) adjusted by %d units (MVAR)\n",
+                  (FT_Char)( value->tag >> 24 ),
+                  (FT_Char)( value->tag >> 16 ),
+                  (FT_Char)( value->tag >> 8 ),
+                  (FT_Char)( value->tag ),
+                  value->unmodified,
+                  delta ));
+
+      /* since we handle both signed and unsigned values as FT_Short, */
+      /* ensure proper overflow arithmetic                            */
+      *p = (FT_Short)( value->unmodified + (FT_Short)delta );
+    }
+
+    /* adjust all derived values */
+    {
+      FT_Face  root = &face->root;
+
+
+      if ( face->os2.version != 0xFFFFU )
+      {
+        if ( face->os2.sTypoAscender || face->os2.sTypoDescender )
+        {
+          root->ascender  = face->os2.sTypoAscender;
+          root->descender = face->os2.sTypoDescender;
+
+          root->height = root->ascender - root->descender +
+                         face->os2.sTypoLineGap;
+        }
+        else
+        {
+          root->ascender  =  (FT_Short)face->os2.usWinAscent;
+          root->descender = -(FT_Short)face->os2.usWinDescent;
+
+          root->height = root->ascender - root->descender;
+        }
+      }
+
+      root->underline_position  = face->postscript.underlinePosition -
+                                  face->postscript.underlineThickness / 2;
+      root->underline_thickness = face->postscript.underlineThickness;
+
+      /* iterate over all FT_Size objects and call `tt_size_reset' */
+      /* to propagate the metrics changes                          */
+      FT_List_Iterate( &root->sizes_list,
+                       tt_size_reset_iterator,
+                       NULL );
+    }
+  }
+
+
   typedef struct  GX_GVar_Head_
   {
     FT_Long    version;
@@ -454,10 +1430,10 @@
 
     FT_TRACE2(( "GVAR " ));
 
-    if ( ( error = face->goto_table( face,
-                                     TTAG_gvar,
-                                     stream,
-                                     &table_len ) ) != 0 )
+    if ( FT_SET_ERROR( face->goto_table( face,
+                                         TTAG_gvar,
+                                         stream,
+                                         &table_len ) ) )
     {
       FT_TRACE2(( "is missing\n" ));
       goto Exit;
@@ -492,10 +1468,9 @@
       goto Exit;
     }
 
-    /* rough sanity check: offsets can be either 2 or 4 bytes, */
-    /* and a single variation needs at least 4 bytes per glyph */
+    /* rough sanity check: offsets can be either 2 or 4 bytes */
     if ( (FT_ULong)gvar_head.glyphCount *
-           ( ( gvar_head.flags & 1 ) ? 8 : 6 ) > table_len )
+           ( ( gvar_head.flags & 1 ) ? 4 : 2 ) > table_len )
     {
       FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" ));
       error = FT_THROW( Invalid_Table );
@@ -556,7 +1531,7 @@
         {
           blend->tuplecoords[i * gvar_head.axisCount + j] =
             FT_GET_SHORT() * 4;                 /* convert to FT_Fixed */
-          FT_TRACE5(( "%.4f ",
+          FT_TRACE5(( "%.5f ",
             blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
         }
         FT_TRACE5(( "]\n" ));
@@ -612,10 +1587,10 @@
 
     for ( i = 0; i < blend->num_axis; i++ )
     {
-      FT_TRACE6(( "    axis coordinate %d (%.4f):\n",
+      FT_TRACE6(( "    axis coordinate %d (%.5f):\n",
                   i, blend->normalizedcoords[i] / 65536.0 ));
       if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) )
-        FT_TRACE6(( "      intermediate coordinates %d (%.4f, %.4f):\n",
+        FT_TRACE6(( "      intermediate coordinates %d (%.5f, %.5f):\n",
                     i,
                     im_start_coords[i] / 65536.0,
                     im_end_coords[i] / 65536.0 ));
@@ -640,7 +1615,7 @@
 
       if ( blend->normalizedcoords[i] == tuple_coords[i] )
       {
-        FT_TRACE6(( "      tuple coordinate value %.4f fits perfectly\n",
+        FT_TRACE6(( "      tuple coordinate value %.5f fits perfectly\n",
                     tuple_coords[i] / 65536.0 ));
         /* `apply' does not change */
         continue;
@@ -653,13 +1628,13 @@
         if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) ||
              blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) )
         {
-          FT_TRACE6(( "      tuple coordinate value %.4f is exceeded, stop\n",
+          FT_TRACE6(( "      tuple coordinate value %.5f is exceeded, stop\n",
                       tuple_coords[i] / 65536.0 ));
           apply = 0;
           break;
         }
 
-        FT_TRACE6(( "      tuple coordinate value %.4f fits\n",
+        FT_TRACE6(( "      tuple coordinate value %.5f fits\n",
                     tuple_coords[i] / 65536.0 ));
         apply = FT_MulDiv( apply,
                            blend->normalizedcoords[i],
@@ -672,7 +1647,7 @@
         if ( blend->normalizedcoords[i] < im_start_coords[i] ||
              blend->normalizedcoords[i] > im_end_coords[i]   )
         {
-          FT_TRACE6(( "      intermediate tuple range [%.4f;%.4f] is exceeded,"
+          FT_TRACE6(( "      intermediate tuple range [%.5f;%.5f] is exceeded,"
                       " stop\n",
                       im_start_coords[i] / 65536.0,
                       im_end_coords[i] / 65536.0 ));
@@ -682,7 +1657,7 @@
 
         else if ( blend->normalizedcoords[i] < tuple_coords[i] )
         {
-          FT_TRACE6(( "      intermediate tuple range [%.4f;%.4f] fits\n",
+          FT_TRACE6(( "      intermediate tuple range [%.5f;%.5f] fits\n",
                       im_start_coords[i] / 65536.0,
                       im_end_coords[i] / 65536.0 ));
           apply = FT_MulDiv( apply,
@@ -692,7 +1667,7 @@
 
         else
         {
-          FT_TRACE6(( "      intermediate tuple range [%.4f;%.4f] fits\n",
+          FT_TRACE6(( "      intermediate tuple range [%.5f;%.5f] fits\n",
                       im_start_coords[i] / 65536.0,
                       im_end_coords[i] / 65536.0 ));
           apply = FT_MulDiv( apply,
@@ -702,7 +1677,7 @@
       }
     }
 
-    FT_TRACE6(( "    apply factor is %.4f\n", apply / 65536.0 ));
+    FT_TRACE6(( "    apply factor is %.5f\n", apply / 65536.0 ));
 
     return apply;
   }
@@ -721,7 +1696,6 @@
   {
     FT_Long    version;
     FT_UShort  offsetToData;
-    FT_UShort  countSizePairs;
     FT_UShort  axisCount;
     FT_UShort  axisSize;
     FT_UShort  instanceCount;
@@ -749,7 +1723,8 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    Check that the font's `fvar' table is valid, parse it, and return  */
-  /*    those data.                                                        */
+  /*    those data.  It also loads (and parses) the `MVAR' table, if       */
+  /*    possible.                                                          */
   /*                                                                       */
   /* <InOut>                                                               */
   /*    face   :: The font face.                                           */
@@ -778,6 +1753,7 @@
     FT_Var_Axis*         a;
     FT_Var_Named_Style*  ns;
     GX_FVar_Head         fvar_head;
+    FT_Bool              usePsName;
 
     static const FT_Frame_Field  fvar_fields[] =
     {
@@ -786,13 +1762,13 @@
 #define FT_STRUCTURE  GX_FVar_Head
 
       FT_FRAME_START( 16 ),
-        FT_FRAME_LONG  ( version ),
-        FT_FRAME_USHORT( offsetToData ),
-        FT_FRAME_USHORT( countSizePairs ),
-        FT_FRAME_USHORT( axisCount ),
-        FT_FRAME_USHORT( axisSize ),
-        FT_FRAME_USHORT( instanceCount ),
-        FT_FRAME_USHORT( instanceSize ),
+        FT_FRAME_LONG      ( version ),
+        FT_FRAME_USHORT    ( offsetToData ),
+        FT_FRAME_SKIP_SHORT,
+        FT_FRAME_USHORT    ( axisCount ),
+        FT_FRAME_USHORT    ( axisSize ),
+        FT_FRAME_USHORT    ( instanceCount ),
+        FT_FRAME_USHORT    ( instanceSize ),
       FT_FRAME_END
     };
 
@@ -816,21 +1792,26 @@
     /* read the font data and set up the internal representation */
     /* if not already done                                       */
 
-    if ( face->blend == NULL )
+    if ( !face->blend )
     {
       FT_TRACE2(( "FVAR " ));
 
       /* both `fvar' and `gvar' must be present */
-      if ( ( error = face->goto_table( face, TTAG_gvar,
-                                       stream, &table_len ) ) != 0 )
+      if ( FT_SET_ERROR( face->goto_table( face, TTAG_gvar,
+                                           stream, &table_len ) ) )
       {
-        FT_TRACE1(( "\n"
-                    "TT_Get_MM_Var: `gvar' table is missing\n" ));
-        goto Exit;
+        /* CFF2 is an alternate to gvar here */
+        if ( FT_SET_ERROR( face->goto_table( face, TTAG_CFF2,
+                                             stream, &table_len ) ) )
+        {
+          FT_TRACE1(( "\n"
+                      "TT_Get_MM_Var: `gvar' or `CFF2' table is missing\n" ));
+          goto Exit;
+        }
       }
 
-      if ( ( error = face->goto_table( face, TTAG_fvar,
-                                       stream, &table_len ) ) != 0 )
+      if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar,
+                                           stream, &table_len ) ) )
       {
         FT_TRACE1(( "is missing\n" ));
         goto Exit;
@@ -838,30 +1819,13 @@
 
       fvar_start = FT_STREAM_POS( );
 
+      /* the validity of the `fvar' header data was already checked */
+      /* in function `sfnt_init_face'                               */
       if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) )
         goto Exit;
 
-      if ( fvar_head.version != (FT_Long)0x00010000L                      ||
-#if 0
-           /* fonts like `JamRegular.ttf' have an incorrect value for */
-           /* `countSizePairs'; since value 2 is hard-coded in `fvar' */
-           /* version 1.0, we simply ignore it                        */
-           fvar_head.countSizePairs != 2                                  ||
-#endif
-           fvar_head.axisSize != 20                                       ||
-           /* axisCount limit implied by 16-bit instanceSize */
-           fvar_head.axisCount > 0x3FFE                                   ||
-           fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount          ||
-           /* instanceCount limit implied by limited range of name IDs */
-           fvar_head.instanceCount > 0x7EFF                               ||
-           fvar_head.offsetToData + fvar_head.axisCount * 20U +
-             fvar_head.instanceCount * fvar_head.instanceSize > table_len )
-      {
-        FT_TRACE1(( "\n"
-                    "TT_Get_MM_Var: invalid `fvar' header\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
-      }
+      usePsName = FT_BOOL( fvar_head.instanceSize ==
+                           6 + 4 * fvar_head.axisCount );
 
       FT_TRACE2(( "loaded\n" ));
 
@@ -938,7 +1902,18 @@
         a->name[3] = (FT_String)( ( a->tag       ) & 0xFF );
         a->name[4] = '\0';
 
-        FT_TRACE5(( "  \"%s\": minimum=%.4f, default=%.4f, maximum=%.4f\n",
+        if ( a->minimum > a->def ||
+             a->def > a->maximum )
+        {
+          FT_TRACE2(( "TT_Get_MM_Var:"
+                      " invalid \"%s\" axis record; disabling\n",
+                      a->name ));
+
+          a->minimum = a->def;
+          a->maximum = a->def;
+        }
+
+        FT_TRACE5(( "  \"%s\": minimum=%.5f, default=%.5f, maximum=%.5f\n",
                     a->name,
                     a->minimum / 65536.0,
                     a->def / 65536.0,
@@ -952,7 +1927,9 @@
       ns = mmvar->namedstyle;
       for ( i = 0; i < fvar_head.instanceCount; i++, ns++ )
       {
-        if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) )
+        /* PostScript names add 2 bytes to the instance record size */
+        if ( FT_FRAME_ENTER( ( usePsName ? 6L : 4L ) +
+                             4L * fvar_head.axisCount ) )
           goto Exit;
 
         ns->strid       =    FT_GET_USHORT();
@@ -961,13 +1938,18 @@
         for ( j = 0; j < fvar_head.axisCount; j++ )
           ns->coords[j] = FT_GET_LONG();
 
+        if ( usePsName )
+          ns->psid = FT_GET_USHORT();
+
         FT_FRAME_EXIT();
       }
+
+      ft_var_load_mvar( face );
     }
 
     /* fill the output array if requested */
 
-    if ( master != NULL )
+    if ( master )
     {
       FT_UInt  n;
 
@@ -1051,6 +2033,7 @@
     GX_Blend    blend;
     FT_MM_Var*  mmvar;
     FT_UInt     i;
+    FT_Bool     is_default_instance = 1;
     FT_Memory   memory = face->root.memory;
 
     enum
@@ -1064,9 +2047,9 @@
 
     face->doblend = FALSE;
 
-    if ( face->blend == NULL )
+    if ( !face->blend )
     {
-      if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 )
+      if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         goto Exit;
     }
 
@@ -1084,24 +2067,27 @@
 
     for ( i = 0; i < num_coords; i++ )
     {
-      FT_TRACE5(( "  %.4f\n", coords[i] / 65536.0 ));
+      FT_TRACE5(( "  %.5f\n", coords[i] / 65536.0 ));
       if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
       {
-        FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.4f\n"
+        FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n"
                     "                 is out of range [-1;1]\n",
                     coords[i] / 65536.0 ));
         error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
+
+      if ( coords[i] != 0 )
+        is_default_instance = 0;
     }
 
     FT_TRACE5(( "\n" ));
 
-    if ( blend->glyphoffsets == NULL )
-      if ( ( error = ft_var_load_gvar( face ) ) != 0 )
+    if ( !face->isCFF2 && !blend->glyphoffsets )
+      if ( FT_SET_ERROR( ft_var_load_gvar( face ) ) )
         goto Exit;
 
-    if ( blend->normalizedcoords == NULL )
+    if ( !blend->normalizedcoords )
     {
       if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) )
         goto Exit;
@@ -1147,7 +2133,7 @@
 
     face->doblend = TRUE;
 
-    if ( face->cvt != NULL )
+    if ( face->cvt )
     {
       switch ( manageCvt )
       {
@@ -1172,6 +2158,8 @@
       }
     }
 
+    face->is_default_instance = is_default_instance;
+
   Exit:
     return error;
   }
@@ -1180,6 +2168,73 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    TT_Get_MM_Blend                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Get the blend (normalized) coordinates for this instance of the    */
+  /*    font.                                                              */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    face       :: The font.                                            */
+  /*                  Initialize the blend structure with `gvar' data.     */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    num_coords :: The number of available coordinates.  If it is       */
+  /*                  larger than the number of axes, set the excess       */
+  /*                  values to 0.                                         */
+  /*                                                                       */
+  /*    coords     :: An array of `num_coords', each between [-1,1].       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  FT_LOCAL_DEF( FT_Error )
+  TT_Get_MM_Blend( TT_Face    face,
+                   FT_UInt    num_coords,
+                   FT_Fixed*  coords )
+  {
+    FT_Error  error = FT_Err_Ok;
+    GX_Blend  blend;
+    FT_UInt   i, nc;
+
+
+    if ( !face->blend )
+    {
+      if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
+        return error;
+    }
+
+    blend = face->blend;
+
+    nc = num_coords;
+    if ( num_coords > blend->num_axis )
+    {
+      FT_TRACE2(( "TT_Get_MM_Blend: only using first %d of %d coordinates\n",
+                  blend->num_axis, num_coords ));
+      nc = blend->num_axis;
+    }
+
+    if ( face->doblend )
+    {
+      for ( i = 0; i < nc; i++ )
+        coords[i] = blend->normalizedcoords[i];
+    }
+    else
+    {
+      for ( i = 0; i < nc; i++ )
+        coords[i] = 0;
+    }
+
+    for ( ; i < num_coords; i++ )
+      coords[i] = 0;
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    TT_Set_Var_Design                                                  */
   /*                                                                       */
   /* <Description>                                                         */
@@ -1217,9 +2272,9 @@
     FT_Memory       memory = face->root.memory;
 
 
-    if ( face->blend == NULL )
+    if ( !face->blend )
     {
-      if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 )
+      if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         goto Exit;
     }
 
@@ -1234,7 +2289,7 @@
       num_coords = mmvar->num_axis;
     }
 
-    /* Axis normalization is a two stage process.  First we normalize */
+    /* Axis normalization is a two-stage process.  First we normalize */
     /* based on the [min,def,max] values for the axis to be [-1,0,1]. */
     /* Then, if there's an `avar' table, we renormalize this range.   */
 
@@ -1246,26 +2301,33 @@
     a = mmvar->axis;
     for ( i = 0; i < num_coords; i++, a++ )
     {
-      FT_TRACE5(( "  %.4f\n", coords[i] / 65536.0 ));
-      if ( coords[i] > a->maximum || coords[i] < a->minimum )
+      FT_Fixed  coord = coords[i];
+
+
+      FT_TRACE5(( "  %.5f\n", coord / 65536.0 ));
+      if ( coord > a->maximum || coord < a->minimum )
       {
-        FT_TRACE1(( "TT_Set_Var_Design: normalized design coordinate %.4f\n"
-                    "                   is out of range [%.4f;%.4f]\n",
-                    coords[i] / 65536.0,
-                    a->minimum / 65536.0,
-                    a->maximum / 65536.0 ));
-        error = FT_THROW( Invalid_Argument );
-        goto Exit;
+        FT_TRACE1((
+          "TT_Set_Var_Design: design coordinate %.5f\n"
+          "                   is out of range [%.5f;%.5f]; clamping\n",
+          coord / 65536.0,
+          a->minimum / 65536.0,
+          a->maximum / 65536.0 ));
+
+        if ( coord > a->maximum)
+          coord = a->maximum;
+        else
+          coord = a->minimum;
       }
 
-      if ( coords[i] < a->def )
+      if ( coord < a->def )
         normalized[i] = -FT_DivFix( coords[i] - a->def,
                                     a->minimum - a->def );
-      else if ( a->maximum == a->def )
-        normalized[i] = 0;
-      else
+      else if ( coord > a->def )
         normalized[i] = FT_DivFix( coords[i] - a->def,
                                    a->maximum - a->def );
+      else
+        normalized[i] = 0;
     }
 
     FT_TRACE5(( "\n" ));
@@ -1276,7 +2338,7 @@
     if ( !blend->avar_checked )
       ft_var_load_avar( face );
 
-    if ( blend->avar_segment != NULL )
+    if ( blend->avar_segment )
     {
       FT_TRACE5(( "normalized design coordinates"
                   " before applying `avar' data:\n" ));
@@ -1286,9 +2348,10 @@
       {
         for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
         {
-          FT_TRACE5(( "  %.4f\n", normalized[i] / 65536.0 ));
           if ( normalized[i] < av->correspondence[j].fromCoord )
           {
+            FT_TRACE5(( "  %.5f\n", normalized[i] / 65536.0 ));
+
             normalized[i] =
               FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord,
                          av->correspondence[j].toCoord -
@@ -1311,6 +2374,123 @@
 
 
   /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Get_Var_Design                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Get the design coordinates of the currently selected interpolated  */
+  /*    font.                                                              */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face       :: A handle to the source face.                         */
+  /*                                                                       */
+  /*    num_coords :: The number of design coordinates to retrieve.  If it */
+  /*                  is larger than the number of axes, set the excess    */
+  /*                  values to~0.                                         */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    coords     :: The design coordinates array.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0~means success.                             */
+  /*                                                                       */
+  FT_LOCAL_DEF( FT_Error )
+  TT_Get_Var_Design( TT_Face    face,
+                     FT_UInt    num_coords,
+                     FT_Fixed*  coords )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+    GX_Blend      blend;
+    FT_MM_Var*    mmvar;
+    FT_Var_Axis*  a;
+
+    FT_UInt  i, j, nc;
+
+
+    if ( !face->blend )
+    {
+      if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
+        return error;
+    }
+
+    blend = face->blend;
+
+    nc = num_coords;
+    if ( num_coords > blend->num_axis )
+    {
+      FT_TRACE2(( "TT_Get_Var_Design: only using first %d of %d coordinates\n",
+                  blend->num_axis, num_coords ));
+      nc = blend->num_axis;
+    }
+
+    if ( face->doblend )
+    {
+      for ( i = 0; i < nc; i++ )
+        coords[i] = blend->normalizedcoords[i];
+    }
+    else
+    {
+      for ( i = 0; i < nc; i++ )
+        coords[i] = 0;
+    }
+
+    for ( ; i < num_coords; i++ )
+      coords[i] = 0;
+
+    if ( !blend->avar_checked )
+      ft_var_load_avar( face );
+
+    if ( blend->avar_segment )
+    {
+      GX_AVarSegment  av = blend->avar_segment;
+
+
+      FT_TRACE5(( "design coordinates"
+                  " after removing `avar' distortion:\n" ));
+
+      for ( i = 0; i < nc; i++, av++ )
+      {
+        for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
+        {
+          if ( coords[i] < av->correspondence[j].toCoord )
+          {
+            coords[i] =
+              FT_MulDiv( coords[i] - av->correspondence[j - 1].toCoord,
+                         av->correspondence[j].fromCoord -
+                           av->correspondence[j - 1].fromCoord,
+                         av->correspondence[j].toCoord -
+                           av->correspondence[j - 1].toCoord ) +
+              av->correspondence[j - 1].fromCoord;
+
+            FT_TRACE5(( "  %.5f\n", coords[i] / 65536.0 ));
+            break;
+          }
+        }
+      }
+    }
+
+    mmvar = blend->mmvar;
+    a     = mmvar->axis;
+
+    for ( i = 0; i < nc; i++, a++ )
+    {
+      if ( coords[i] < 0 )
+        coords[i] = a->def + FT_MulFix( coords[i],
+                                        a->def - a->minimum );
+      else if ( coords[i] > 0 )
+        coords[i] = a->def + FT_MulFix( coords[i],
+                                        a->maximum - a->def );
+      else
+        coords[i] = a->def;
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+  /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
   /*****                     GX VAR PARSING ROUTINES                   *****/
@@ -1363,7 +2543,7 @@
 
     FT_TRACE2(( "CVAR " ));
 
-    if ( blend == NULL )
+    if ( !blend )
     {
       FT_TRACE2(( "\n"
                   "tt_face_vary_cvt: no blend specified\n" ));
@@ -1371,7 +2551,7 @@
       goto Exit;
     }
 
-    if ( face->cvt == NULL )
+    if ( !face->cvt )
     {
       FT_TRACE2(( "\n"
                   "tt_face_vary_cvt: no `cvt ' table\n" ));
@@ -1414,7 +2594,8 @@
     offsetToData = FT_GET_USHORT();
 
     /* rough sanity test */
-    if ( offsetToData + tupleCount * 4 > table_len )
+    if ( offsetToData + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 >
+           table_len )
     {
       FT_TRACE2(( "tt_face_vary_cvt:"
                   " invalid CVT variation array header\n" ));
@@ -1498,7 +2679,7 @@
                                              table_len,
                                              point_count == 0 ? face->cvt_size
                                                               : point_count );
-      if ( localpoints == NULL || deltas == NULL )
+      if ( !localpoints || !deltas )
         ; /* failure, ignore it */
 
       else if ( localpoints == ALL_POINTS )
@@ -1546,10 +2727,15 @@
 
         for ( j = 0; j < point_count; j++ )
         {
-          int      pindex   = localpoints[j];
-          FT_Long  orig_cvt = face->cvt[pindex];
+          int      pindex;
+          FT_Long  orig_cvt;
 
 
+          pindex = localpoints[j];
+          if ( (FT_ULong)pindex >= face->cvt_size )
+            continue;
+
+          orig_cvt          = face->cvt[pindex];
           face->cvt[pindex] = (FT_Short)( orig_cvt +
                                           FT_MulFix( deltas[j], apply ) );
 
@@ -1858,7 +3044,7 @@
     FT_Short    *deltas_x, *deltas_y;
 
 
-    if ( !face->doblend || blend == NULL )
+    if ( !face->doblend || !blend )
       return FT_THROW( Invalid_Argument );
 
     if ( glyph_index >= blend->gv_glyphcnt      ||
@@ -2004,7 +3190,7 @@
                                           point_count == 0 ? n_points
                                                            : point_count );
 
-      if ( points == NULL || deltas_y == NULL || deltas_x == NULL )
+      if ( !points || !deltas_y || !deltas_x )
         ; /* failure, ignore it */
 
       else if ( points == ALL_POINTS )
@@ -2023,8 +3209,36 @@
           FT_Pos  delta_y = FT_MulFix( deltas_y[j], apply );
 
 
-          outline->points[j].x += delta_x;
-          outline->points[j].y += delta_y;
+          if ( j < n_points - 3 )
+          {
+            outline->points[j].x += delta_x;
+            outline->points[j].y += delta_y;
+          }
+          else
+          {
+            /* To avoid double adjustment of advance width or height, */
+            /* adjust phantom points only if there is no HVAR or VVAR */
+            /* support, respectively.                                 */
+            if ( j == ( n_points - 3 )          &&
+                 !( face->variation_support   &
+                    TT_FACE_FLAG_VAR_HADVANCE ) )
+              outline->points[j].x += delta_x;
+
+            else if ( j == ( n_points - 2 )        &&
+                      !( face->variation_support &
+                         TT_FACE_FLAG_VAR_LSB    ) )
+              outline->points[j].x += delta_x;
+
+            else if ( j == ( n_points - 1 )          &&
+                      !( face->variation_support   &
+                         TT_FACE_FLAG_VAR_VADVANCE ) )
+              outline->points[j].y += delta_y;
+
+            else if ( j == ( n_points - 0 )        &&
+                      !( face->variation_support &
+                         TT_FACE_FLAG_VAR_TSB    ) )
+              outline->points[j].y += delta_y;
+          }
 
 #ifdef FT_DEBUG_LEVEL_TRACE
           if ( delta_x || delta_y )
@@ -2146,30 +3360,123 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
+  /*    tt_get_var_blend                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An extended internal version of `TT_Get_MM_Blend' that returns     */
+  /*    pointers instead of copying data, without any initialization of    */
+  /*    the MM machinery in case it isn't loaded yet.                      */
+  /*                                                                       */
+  FT_LOCAL_DEF( FT_Error )
+  tt_get_var_blend( TT_Face      face,
+                    FT_UInt     *num_coords,
+                    FT_Fixed*   *coords,
+                    FT_MM_Var*  *mm_var )
+  {
+    if ( face->blend )
+    {
+      if ( num_coords )
+        *num_coords = face->blend->num_axis;
+      if ( coords )
+        *coords     = face->blend->normalizedcoords;
+      if ( mm_var )
+        *mm_var     = face->blend->mmvar;
+    }
+    else
+    {
+      if ( num_coords )
+        *num_coords = 0;
+      if ( coords )
+        *coords     = NULL;
+      if ( mm_var )
+        *mm_var     = NULL;
+    }
+
+    return FT_Err_Ok;
+  }
+
+
+  static void
+  ft_var_done_item_variation_store( TT_Face          face,
+                                    GX_ItemVarStore  itemStore )
+  {
+    FT_Memory  memory = FT_FACE_MEMORY( face );
+    FT_UInt    i;
+
+
+    if ( itemStore->varData )
+    {
+      for ( i = 0; i < itemStore->dataCount; i++ )
+      {
+        FT_FREE( itemStore->varData[i].regionIndices );
+        FT_FREE( itemStore->varData[i].deltaSet );
+      }
+
+      FT_FREE( itemStore->varData );
+    }
+
+    if ( itemStore->varRegionList )
+    {
+      for ( i = 0; i < itemStore->regionCount; i++ )
+        FT_FREE( itemStore->varRegionList[i].axisList );
+
+      FT_FREE( itemStore->varRegionList );
+    }
+  }
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
   /*    tt_done_blend                                                      */
   /*                                                                       */
   /* <Description>                                                         */
   /*    Free the blend internal data structure.                            */
   /*                                                                       */
   FT_LOCAL_DEF( void )
-  tt_done_blend( FT_Memory  memory,
-                 GX_Blend   blend )
+  tt_done_blend( TT_Face  face )
   {
-    if ( blend != NULL )
-    {
-      FT_UInt  i;
+    FT_Memory  memory = FT_FACE_MEMORY( face );
+    GX_Blend   blend  = face->blend;
 
 
+    if ( blend )
+    {
+      FT_UInt  i, num_axes;
+
+
+      /* blend->num_axis might not be set up yet */
+      num_axes = blend->mmvar->num_axis;
+
       FT_FREE( blend->normalizedcoords );
       FT_FREE( blend->mmvar );
 
-      if ( blend->avar_segment != NULL )
+      if ( blend->avar_segment )
       {
-        for ( i = 0; i < blend->num_axis; i++ )
+        for ( i = 0; i < num_axes; i++ )
           FT_FREE( blend->avar_segment[i].correspondence );
         FT_FREE( blend->avar_segment );
       }
 
+      if ( blend->hvar_table )
+      {
+        ft_var_done_item_variation_store( face,
+                                          &blend->hvar_table->itemStore );
+
+        FT_FREE( blend->hvar_table->widthMap.innerIndex );
+        FT_FREE( blend->hvar_table->widthMap.outerIndex );
+        FT_FREE( blend->hvar_table );
+      }
+
+      if ( blend->mvar_table )
+      {
+        ft_var_done_item_variation_store( face,
+                                          &blend->mvar_table->itemStore );
+
+        FT_FREE( blend->mvar_table->values );
+        FT_FREE( blend->mvar_table );
+      }
+
       FT_FREE( blend->tuplecoords );
       FT_FREE( blend->glyphoffsets );
       FT_FREE( blend );
diff --git a/src/truetype/ttgxvar.h b/src/truetype/ttgxvar.h
index aa8f6ea..e431983 100644
--- a/src/truetype/ttgxvar.h
+++ b/src/truetype/ttgxvar.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType GX Font Variation loader (specification)                    */
 /*                                                                         */
-/*  Copyright 2004-2016 by                                                 */
+/*  Copyright 2004-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, Werner Lemberg and George Williams.      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -61,6 +61,152 @@
   } GX_AVarSegmentRec, *GX_AVarSegment;
 
 
+  typedef struct  GX_ItemVarDataRec_
+  {
+    FT_UInt    itemCount;      /* number of delta sets per item         */
+    FT_UInt    regionIdxCount; /* number of region indices in this data */
+    FT_UInt*   regionIndices;  /* array of `regionCount' indices;       */
+                               /* these index `varRegionList'           */
+    FT_Short*  deltaSet;       /* array of `itemCount' deltas           */
+                               /* use `innerIndex' for this array       */
+
+  } GX_ItemVarDataRec, *GX_ItemVarData;
+
+
+  /* contribution of one axis to a region */
+  typedef struct  GX_AxisCoordsRec_
+  {
+    FT_Fixed  startCoord;
+    FT_Fixed  peakCoord;      /* zero means no effect (factor = 1) */
+    FT_Fixed  endCoord;
+
+  } GX_AxisCoordsRec, *GX_AxisCoords;
+
+
+  typedef struct  GX_VarRegionRec_
+  {
+    GX_AxisCoords  axisList;               /* array of axisCount records */
+
+  } GX_VarRegionRec, *GX_VarRegion;
+
+
+  /* item variation store */
+  typedef struct  GX_ItemVarStoreRec_
+  {
+    FT_UInt         dataCount;
+    GX_ItemVarData  varData;            /* array of dataCount records;     */
+                                        /* use `outerIndex' for this array */
+    FT_UShort     axisCount;
+    FT_UInt       regionCount;          /* total number of regions defined */
+    GX_VarRegion  varRegionList;
+
+  } GX_ItemVarStoreRec, *GX_ItemVarStore;
+
+
+  typedef struct  GX_DeltaSetIdxMapRec_
+  {
+    FT_UInt   mapCount;
+    FT_UInt*  outerIndex;             /* indices to item var data */
+    FT_UInt*  innerIndex;             /* indices to delta set     */
+
+  } GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    GX_HVVarTableRec                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Data from either the `HVAR' or `VVAR' table.                       */
+  /*                                                                       */
+  typedef struct  GX_HVVarTableRec_
+  {
+    GX_ItemVarStoreRec    itemStore;        /* Item Variation Store  */
+    GX_DeltaSetIdxMapRec  widthMap;         /* Advance Width Mapping */
+
+#if 0
+    GX_DeltaSetIdxMapRec  lsbMap;           /* not implemented */
+    GX_DeltaSetIdxMapRec  rsbMap;           /* not implemented */
+
+    GX_DeltaSetIdxMapRec  tsbMap;           /* not implemented */
+    GX_DeltaSetIdxMapRec  bsbMap;           /* not implemented */
+    GX_DeltaSetIdxMapRec  vorgMap;          /* not implemented */
+#endif
+
+  } GX_HVVarTableRec, *GX_HVVarTable;
+
+
+#define MVAR_TAG_GASP_0  FT_MAKE_TAG( 'g', 's', 'p', '0' )
+#define MVAR_TAG_GASP_1  FT_MAKE_TAG( 'g', 's', 'p', '1' )
+#define MVAR_TAG_GASP_2  FT_MAKE_TAG( 'g', 's', 'p', '2' )
+#define MVAR_TAG_GASP_3  FT_MAKE_TAG( 'g', 's', 'p', '3' )
+#define MVAR_TAG_GASP_4  FT_MAKE_TAG( 'g', 's', 'p', '4' )
+#define MVAR_TAG_GASP_5  FT_MAKE_TAG( 'g', 's', 'p', '5' )
+#define MVAR_TAG_GASP_6  FT_MAKE_TAG( 'g', 's', 'p', '6' )
+#define MVAR_TAG_GASP_7  FT_MAKE_TAG( 'g', 's', 'p', '7' )
+#define MVAR_TAG_GASP_8  FT_MAKE_TAG( 'g', 's', 'p', '8' )
+#define MVAR_TAG_GASP_9  FT_MAKE_TAG( 'g', 's', 'p', '9' )
+
+#define MVAR_TAG_CPHT  FT_MAKE_TAG( 'c', 'p', 'h', 't' )
+#define MVAR_TAG_HASC  FT_MAKE_TAG( 'h', 'a', 's', 'c' )
+#define MVAR_TAG_HCLA  FT_MAKE_TAG( 'h', 'c', 'l', 'a' )
+#define MVAR_TAG_HCLD  FT_MAKE_TAG( 'h', 'c', 'l', 'd' )
+#define MVAR_TAG_HCOF  FT_MAKE_TAG( 'h', 'c', 'o', 'f' )
+#define MVAR_TAG_HCRN  FT_MAKE_TAG( 'h', 'c', 'r', 'n' )
+#define MVAR_TAG_HCRS  FT_MAKE_TAG( 'h', 'c', 'r', 's' )
+#define MVAR_TAG_HDSC  FT_MAKE_TAG( 'h', 'd', 's', 'c' )
+#define MVAR_TAG_HLGP  FT_MAKE_TAG( 'h', 'l', 'g', 'p' )
+#define MVAR_TAG_SBXO  FT_MAKE_TAG( 's', 'b', 'x', 'o' )
+#define MVAR_TAG_SBXS  FT_MAKE_TAG( 's', 'b', 'x', 's' )
+#define MVAR_TAG_SBYO  FT_MAKE_TAG( 's', 'b', 'y', 'o' )
+#define MVAR_TAG_SBYS  FT_MAKE_TAG( 's', 'b', 'y', 's' )
+#define MVAR_TAG_SPXO  FT_MAKE_TAG( 's', 'p', 'x', 'o' )
+#define MVAR_TAG_SPXS  FT_MAKE_TAG( 's', 'p', 'x', 's' )
+#define MVAR_TAG_SPYO  FT_MAKE_TAG( 's', 'p', 'y', 'o' )
+#define MVAR_TAG_SPYS  FT_MAKE_TAG( 's', 'p', 'y', 's' )
+#define MVAR_TAG_STRO  FT_MAKE_TAG( 's', 't', 'r', 'o' )
+#define MVAR_TAG_STRS  FT_MAKE_TAG( 's', 't', 'r', 's' )
+#define MVAR_TAG_UNDO  FT_MAKE_TAG( 'u', 'n', 'd', 'o' )
+#define MVAR_TAG_UNDS  FT_MAKE_TAG( 'u', 'n', 'd', 's' )
+#define MVAR_TAG_VASC  FT_MAKE_TAG( 'v', 'a', 's', 'c' )
+#define MVAR_TAG_VCOF  FT_MAKE_TAG( 'v', 'c', 'o', 'f' )
+#define MVAR_TAG_VCRN  FT_MAKE_TAG( 'v', 'c', 'r', 'n' )
+#define MVAR_TAG_VCRS  FT_MAKE_TAG( 'v', 'c', 'r', 's' )
+#define MVAR_TAG_VDSC  FT_MAKE_TAG( 'v', 'd', 's', 'c' )
+#define MVAR_TAG_VLGP  FT_MAKE_TAG( 'v', 'l', 'g', 'p' )
+#define MVAR_TAG_XHGT  FT_MAKE_TAG( 'x', 'h', 'g', 't' )
+
+
+  typedef struct  GX_ValueRec_
+  {
+    FT_ULong   tag;
+    FT_UShort  outerIndex;
+    FT_UShort  innerIndex;
+
+    FT_Short  unmodified;  /* values are either FT_Short or FT_UShort */
+
+  } GX_ValueRec, *GX_Value;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    GX_MVarTableRec                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Data from the `MVAR' table.                                        */
+  /*                                                                       */
+  typedef struct  GX_MVarTableRec_
+  {
+    FT_UShort  valueCount;
+
+    GX_ItemVarStoreRec  itemStore;        /* Item Variation Store  */
+    GX_Value            values;           /* Value Records         */
+
+  } GX_MVarTableRec, *GX_MVarTable;
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Struct>                                                              */
@@ -89,6 +235,18 @@
     FT_Bool         avar_checked;
     GX_AVarSegment  avar_segment;
 
+    FT_Bool         hvar_loaded;
+    FT_Bool         hvar_checked;
+    FT_Error        hvar_error;
+    GX_HVVarTable   hvar_table;
+
+    FT_Bool         vvar_loaded;
+    FT_Bool         vvar_checked;
+    FT_Error        vvar_error;
+    GX_HVVarTable   vvar_table;
+
+    GX_MVarTable    mvar_table;
+
     FT_UInt         tuplecount;      /* shared tuples in `gvar'           */
     FT_Fixed*       tuplecoords;     /* tuplecoords[tuplecount][num_axis] */
 
@@ -149,6 +307,11 @@
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
+  TT_Get_MM_Blend( TT_Face    face,
+                   FT_UInt    num_coords,
+                   FT_Fixed*  coords );
+
+  FT_LOCAL( FT_Error )
   TT_Set_Var_Design( TT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
@@ -157,6 +320,10 @@
   TT_Get_MM_Var( TT_Face      face,
                  FT_MM_Var*  *master );
 
+  FT_LOCAL( FT_Error )
+  TT_Get_Var_Design( TT_Face    face,
+                     FT_UInt    num_coords,
+                     FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
   tt_face_vary_cvt( TT_Face    face,
@@ -169,10 +336,27 @@
                               FT_Outline*  outline,
                               FT_UInt      n_points );
 
+  FT_LOCAL( FT_Error )
+  tt_hadvance_adjust( TT_Face  face,
+                      FT_UInt  gindex,
+                      FT_Int  *adelta );
+
+  FT_LOCAL( FT_Error )
+  tt_vadvance_adjust( TT_Face  face,
+                      FT_UInt  gindex,
+                      FT_Int  *adelta );
 
   FT_LOCAL( void )
-  tt_done_blend( FT_Memory  memory,
-                 GX_Blend   blend );
+  tt_apply_mvar( TT_Face  face );
+
+  FT_LOCAL( FT_Error )
+  tt_get_var_blend( TT_Face      face,
+                    FT_UInt     *num_coords,
+                    FT_Fixed*   *coords,
+                    FT_MM_Var*  *mm_var );
+
+  FT_LOCAL( void )
+  tt_done_blend( TT_Face  face );
 
 
 FT_END_HEADER
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 2d15ea7..7179ffd 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType bytecode interpreter (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -129,7 +129,7 @@
 
     coderange = &exec->codeRangeTable[range - 1];
 
-    FT_ASSERT( coderange->base != NULL );
+    FT_ASSERT( coderange->base );
 
     /* NOTE: Because the last instruction of a program may be a CALL */
     /*       which will return to the first byte *after* the code    */
@@ -423,7 +423,7 @@
 
       /* In case of multi-threading it can happen that the old size object */
       /* no longer exists, thus we must clear all glyph zone references.   */
-      ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) );
+      FT_ZERO( &exec->zp0 );
       exec->zp1 = exec->zp0;
       exec->zp2 = exec->zp0;
     }
@@ -1613,7 +1613,7 @@
 
     range = &exc->codeRangeTable[aRange - 1];
 
-    if ( range->base == NULL )     /* invalid coderange */
+    if ( !range->base )     /* invalid coderange */
     {
       exc->error = FT_THROW( Invalid_CodeRange );
       return FAILURE;
@@ -3388,13 +3388,27 @@
             FT_Long*        args )
   {
     if ( args[0] == 0 && exc->args == 0 )
+    {
       exc->error = FT_THROW( Bad_Argument );
+      return;
+    }
+
     exc->IP += args[0];
     if ( exc->IP < 0                                             ||
          ( exc->callTop > 0                                    &&
            exc->IP > exc->callStack[exc->callTop - 1].Def->end ) )
+    {
       exc->error = FT_THROW( Bad_Argument );
+      return;
+    }
+
     exc->step_ins = FALSE;
+
+    if ( args[0] < 0 )
+    {
+      if ( ++exc->neg_jump_counter > exc->neg_jump_counter_max )
+        exc->error = FT_THROW( Execution_Too_Long );
+    }
   }
 
 
@@ -3949,6 +3963,10 @@
       Ins_Goto_CodeRange( exc, def->range, def->start );
 
       exc->step_ins = FALSE;
+
+      exc->loopcall_counter += (FT_ULong)args[0];
+      if ( exc->loopcall_counter > exc->loopcall_counter_max )
+        exc->error = FT_THROW( Execution_Too_Long );
     }
 
     return;
@@ -5155,14 +5173,14 @@
   /*                                                                       */
   /* SCANTYPE[]:   SCAN TYPE                                               */
   /* Opcode range: 0x8D                                                    */
-  /* Stack:        uint32? -->                                             */
+  /* Stack:        uint16 -->                                              */
   /*                                                                       */
   static void
   Ins_SCANTYPE( TT_ExecContext  exc,
                 FT_Long*        args )
   {
     if ( args[0] >= 0 )
-      exc->GS.scan_type = (FT_Int)args[0];
+      exc->GS.scan_type = (FT_Int)args[0] & 0xFFFF;
   }
 
 
@@ -5559,9 +5577,9 @@
     FT_Int      B1, B2;
 #endif
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-    FT_Bool     in_twilight = exc->GS.gep0 == 0 || \
-                              exc->GS.gep1 == 0 || \
-                              exc->GS.gep2 == 0;
+    FT_Bool     in_twilight = FT_BOOL( exc->GS.gep0 == 0 ||
+                                       exc->GS.gep1 == 0 ||
+                                       exc->GS.gep2 == 0 );
 #endif
 
 
@@ -5675,8 +5693,8 @@
         /* Special case: allow SHPIX to move points in the twilight zone.  */
         /* Otherwise, treat SHPIX the same as DELTAP.  Unbreaks various    */
         /* fonts such as older versions of Rokkitt and DTL Argo T Light    */
-        /* that would glitch severly after calling ALIGNRP after a blocked */
-        /* SHPIX.                                                          */
+        /* that would glitch severely after calling ALIGNRP after a        */
+        /* blocked SHPIX.                                                  */
         if ( in_twilight                                                ||
              ( !( exc->iupx_called && exc->iupy_called )              &&
                ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
@@ -6519,7 +6537,9 @@
      * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0),
      * for every n.
      */
-    twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0;
+    twilight = ( exc->GS.gep0 == 0 ||
+                 exc->GS.gep1 == 0 ||
+                 exc->GS.gep2 == 0 );
 
     if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) )
     {
@@ -6567,7 +6587,7 @@
       cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base );
     }
 
-    for ( ; exc->GS.loop > 0; --exc->GS.loop )
+    for ( ; exc->GS.loop > 0; exc->GS.loop-- )
     {
       FT_UInt     point = (FT_UInt)exc->stack[--exc->args];
       FT_F26Dot6  org_dist, cur_dist, new_dist;
@@ -7532,7 +7552,8 @@
   FT_EXPORT_DEF( FT_Error )
   TT_RunIns( TT_ExecContext  exc )
   {
-    FT_Long    ins_counter = 0;  /* executed instructions counter */
+    FT_ULong   ins_counter = 0;  /* executed instructions counter */
+    FT_ULong   num_twilight_points;
     FT_UShort  i;
 
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
@@ -7568,6 +7589,50 @@
     exc->iupy_called = FALSE;
 #endif
 
+    /* We restrict the number of twilight points to a reasonable,     */
+    /* heuristic value to avoid slow execution of malformed bytecode. */
+    num_twilight_points = FT_MAX( 30,
+                                  2 * ( exc->pts.n_points + exc->cvtSize ) );
+    if ( exc->twilight.n_points > num_twilight_points )
+    {
+      if ( num_twilight_points > 0xFFFFU )
+        num_twilight_points = 0xFFFFU;
+
+      FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n"
+                  "           from %d to the more reasonable value %d\n",
+                  exc->twilight.n_points,
+                  num_twilight_points ));
+      exc->twilight.n_points = (FT_UShort)num_twilight_points;
+    }
+
+    /* Set up loop detectors.  We restrict the number of LOOPCALL loops  */
+    /* and the number of JMPR, JROT, and JROF calls with a negative      */
+    /* argument to values that depend on the size of the CVT table and   */
+    /* the number of points in the current glyph (if applicable).        */
+    /*                                                                   */
+    /* The idea is that in real-world bytecode you either iterate over   */
+    /* all CVT entries (in the `prep' table), or over all points (or     */
+    /* contours, in the `glyf' table) of a glyph, and such iterations    */
+    /* don't happen very often.                                          */
+    exc->loopcall_counter = 0;
+    exc->neg_jump_counter = 0;
+
+    /* The maximum values are heuristic. */
+    if ( exc->pts.n_points )
+      exc->loopcall_counter_max = FT_MAX( 50,
+                                          10 * exc->pts.n_points ) +
+                                  FT_MAX( 50,
+                                          exc->cvtSize / 10 );
+    else
+      exc->loopcall_counter_max = FT_MAX( 100,
+                                          5 * exc->cvtSize );
+    FT_TRACE5(( "TT_RunIns: Limiting total number of loops in LOOPCALL"
+                " to %d\n", exc->loopcall_counter_max ));
+
+    exc->neg_jump_counter_max = exc->loopcall_counter_max;
+    FT_TRACE5(( "TT_RunIns: Limiting total number of backward jumps"
+                " to %d\n", exc->neg_jump_counter_max ));
+
     /* set PPEM and CVT functions */
     exc->tt_metrics.ratio = 0;
     if ( exc->metrics.x_ppem != exc->metrics.y_ppem )
@@ -8328,6 +8393,7 @@
     } while ( !exc->instruction_trap );
 
   LNo_Error_:
+    FT_TRACE4(( "  %d instructions executed\n", ins_counter ));
     return FT_Err_Ok;
 
   LErrorCodeOverflow_:
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index 53f0944..6625e16 100644
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType bytecode interpreter (specification).                       */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -408,6 +408,14 @@
 
 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
+    /* We maintain two counters (in addition to the instruction counter) */
+    /* that act as loop detectors for LOOPCALL and jump opcodes with     */
+    /* negative arguments.                                               */
+    FT_ULong           loopcall_counter;
+    FT_ULong           loopcall_counter_max;
+    FT_ULong           neg_jump_counter;
+    FT_ULong           neg_jump_counter_max;
+
   } TT_ExecContextRec;
 
 
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index ed3be2d..00207bb 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Objects manager (body).                                              */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -117,7 +117,7 @@
     FT_Error  error;
 
 
-    FT_MEM_ZERO( zone, sizeof ( *zone ) );
+    FT_ZERO( zone );
     zone->memory = memory;
 
     if ( FT_NEW_ARRAY( zone->org,      maxPoints   ) ||
@@ -536,6 +536,7 @@
       goto Exit;
 
     /* check that we have a valid TrueType file */
+    FT_TRACE2(( "  " ));
     error = sfnt->init_face( stream, face, face_index, num_params, params );
 
     /* Stream may have changed. */
@@ -577,58 +578,50 @@
 
     if ( FT_IS_SCALABLE( ttface ) )
     {
-
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
-
       if ( !ttface->internal->incremental_interface )
-        error = tt_face_load_loca( face, stream );
-      if ( !error )
-        error = tt_face_load_cvt( face, stream );
-      if ( !error )
-        error = tt_face_load_fpgm( face, stream );
-      if ( !error )
-        error = tt_face_load_prep( face, stream );
-
-      /* Check the scalable flag based on `loca'. */
-      if ( !ttface->internal->incremental_interface &&
-           ttface->num_fixed_sizes                  &&
-           face->glyph_locations                    &&
-           tt_check_single_notdef( ttface )         )
+#endif
       {
-        FT_TRACE5(( "tt_face_init:"
-                    " Only the `.notdef' glyph has an outline.\n"
-                    "             "
-                    " Resetting scalable flag to FALSE.\n" ));
+        error = tt_face_load_loca( face, stream );
 
-        ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
+        /* having a (non-zero) `glyf' table without */
+        /* a `loca' table is not valid              */
+        if ( face->glyf_len && FT_ERR_EQ( error, Table_Missing ) )
+          goto Exit;
+        if ( error )
+          goto Exit;
       }
 
-#else /* !FT_CONFIG_OPTION_INCREMENTAL */
+      /* `fpgm', `cvt', and `prep' are optional */
+      error = tt_face_load_cvt( face, stream );
+      if ( error && FT_ERR_NEQ( error, Table_Missing ) )
+        goto Exit;
 
-      if ( !error )
-        error = tt_face_load_loca( face, stream );
-      if ( !error )
-        error = tt_face_load_cvt( face, stream );
-      if ( !error )
-        error = tt_face_load_fpgm( face, stream );
-      if ( !error )
-        error = tt_face_load_prep( face, stream );
+      error = tt_face_load_fpgm( face, stream );
+      if ( error && FT_ERR_NEQ( error, Table_Missing ) )
+        goto Exit;
+
+      error = tt_face_load_prep( face, stream );
+      if ( error && FT_ERR_NEQ( error, Table_Missing ) )
+        goto Exit;
 
       /* Check the scalable flag based on `loca'. */
-      if ( ttface->num_fixed_sizes          &&
-           face->glyph_locations            &&
-           tt_check_single_notdef( ttface ) )
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+      if ( !ttface->internal->incremental_interface )
+#endif
       {
-        FT_TRACE5(( "tt_face_init:"
-                    " Only the `.notdef' glyph has an outline.\n"
-                    "             "
-                    " Resetting scalable flag to FALSE.\n" ));
+        if ( ttface->num_fixed_sizes          &&
+             face->glyph_locations            &&
+             tt_check_single_notdef( ttface ) )
+        {
+          FT_TRACE5(( "tt_face_init:"
+                      " Only the `.notdef' glyph has an outline.\n"
+                      "             "
+                      " Resetting scalable flag to FALSE.\n" ));
 
-        ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
+          ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE;
+        }
       }
-
-#endif /* !FT_CONFIG_OPTION_INCREMENTAL */
-
     }
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
@@ -671,6 +664,8 @@
                                      named_style->coords );
           if ( error )
             goto Exit;
+
+          tt_apply_mvar( face );
         }
       }
     }
@@ -739,7 +734,7 @@
     face->cvt_program_size  = 0;
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    tt_done_blend( memory, face->blend );
+    tt_done_blend( face );
     face->blend = NULL;
 #endif
   }
@@ -827,6 +822,11 @@
 
       FT_TRACE4(( "Executing `fpgm' table.\n" ));
       error = face->interpreter( exec );
+#ifdef FT_DEBUG_LEVEL_TRACE
+      if ( error )
+        FT_TRACE4(( "  interpretation failed with error code 0x%x\n",
+                    error ));
+#endif
     }
     else
       error = FT_Err_Ok;
@@ -890,8 +890,12 @@
       TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
 
       FT_TRACE4(( "Executing `prep' table.\n" ));
-
       error = face->interpreter( exec );
+#ifdef FT_DEBUG_LEVEL_TRACE
+      if ( error )
+        FT_TRACE4(( "  interpretation failed with error code 0x%x\n",
+                    error ));
+#endif
     }
     else
       error = FT_Err_Ok;
@@ -1083,8 +1087,10 @@
 
     if ( size->bytecode_ready < 0 )
       error = tt_size_init_bytecode( (FT_Size)size, pedantic );
+    else
+      error = size->bytecode_ready;
 
-    if ( error || size->bytecode_ready )
+    if ( error )
       goto Exit;
 
     /* rescale CVT when needed */
@@ -1116,6 +1122,8 @@
 
       error = tt_size_run_prep( size, pedantic );
     }
+    else
+      error = size->cvt_ready;
 
   Exit:
     return error;
@@ -1192,20 +1200,26 @@
   /*    have been changed.                                                 */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    size :: A handle to the target size object.                        */
+  /*    size        :: A handle to the target size object.                 */
+  /*                                                                       */
+  /*    only_height :: Only recompute ascender, descender, and height.     */
   /*                                                                       */
   FT_LOCAL_DEF( FT_Error )
-  tt_size_reset( TT_Size  size )
+  tt_size_reset( TT_Size  size,
+                 FT_Bool  only_height )
   {
     TT_Face           face;
-    FT_Error          error = FT_Err_Ok;
     FT_Size_Metrics*  metrics;
 
 
-    size->ttmetrics.valid = FALSE;
-
     face = (TT_Face)size->root.face;
 
+    /* nothing to do for CFF2 */
+    if ( face->isCFF2 )
+      return FT_Err_Ok;
+
+    size->ttmetrics.valid = FALSE;
+
     metrics = &size->metrics;
 
     /* copy the result from base layer */
@@ -1220,17 +1234,26 @@
     /*                                                               */
     if ( face->header.Flags & 8 )
     {
-      metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
-                                    face->root.units_per_EM );
-      metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
-                                    face->root.units_per_EM );
-
       metrics->ascender =
         FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
       metrics->descender =
         FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
       metrics->height =
         FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
+    }
+
+    size->ttmetrics.valid = TRUE;
+
+    if ( only_height )
+      return FT_Err_Ok;
+
+    if ( face->header.Flags & 8 )
+    {
+      metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
+                                    face->root.units_per_EM );
+      metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
+                                    face->root.units_per_EM );
+
       metrics->max_advance =
         FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
                                  metrics->x_scale ) );
@@ -1258,10 +1281,7 @@
     size->cvt_ready = -1;
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
-    if ( !error )
-      size->ttmetrics.valid = TRUE;
-
-    return error;
+    return FT_Err_Ok;
   }
 
 
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index 98ad383..65929e5 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Objects manager (specification).                                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -389,7 +389,8 @@
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
   FT_LOCAL( FT_Error )
-  tt_size_reset( TT_Size  size );
+  tt_size_reset( TT_Size  size,
+                 FT_Bool  only_height );
 
 
   /*************************************************************************/
diff --git a/src/truetype/ttpic.c b/src/truetype/ttpic.c
index 54a5b8b..66bd7e1 100644
--- a/src/truetype/ttpic.c
+++ b/src/truetype/ttpic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for truetype module. */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttpic.h b/src/truetype/ttpic.h
index f725865..1410cd7 100644
--- a/src/truetype/ttpic.h
+++ b/src/truetype/ttpic.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType position independent code services for truetype module. */
 /*                                                                         */
-/*  Copyright 2009-2016 by                                                 */
+/*  Copyright 2009-2017 by                                                 */
 /*  Oran Agra and Mickey Gabel.                                            */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -25,15 +25,17 @@
 
 #ifndef FT_CONFIG_OPTION_PIC
 
-#define TT_SERVICES_GET                  tt_services
-#define TT_SERVICE_GX_MULTI_MASTERS_GET  tt_service_gx_multi_masters
-#define TT_SERVICE_TRUETYPE_GLYF_GET     tt_service_truetype_glyf
-#define TT_SERVICE_PROPERTIES_GET        tt_service_properties
+#define TT_SERVICES_GET                    tt_services
+#define TT_SERVICE_GX_MULTI_MASTERS_GET    tt_service_gx_multi_masters
+#define TT_SERVICE_METRICS_VARIATIONS_GET  tt_service_metrics_variations
+#define TT_SERVICE_TRUETYPE_GLYF_GET       tt_service_truetype_glyf
+#define TT_SERVICE_PROPERTIES_GET          tt_service_properties
 
 #else /* FT_CONFIG_OPTION_PIC */
 
 #include FT_MULTIPLE_MASTERS_H
 #include FT_SERVICE_MULTIPLE_MASTERS_H
+#include FT_SERVICE_METRICS_VARIATIONS_H
 #include FT_SERVICE_TRUETYPE_GLYF_H
 #include FT_SERVICE_PROPERTIES_H
 
@@ -42,12 +44,13 @@
 
   typedef struct  TTModulePIC_
   {
-    FT_ServiceDescRec*          tt_services;
+    FT_ServiceDescRec*               tt_services;
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    FT_Service_MultiMastersRec  tt_service_gx_multi_masters;
+    FT_Service_MultiMastersRec       tt_service_gx_multi_masters;
+    FT_Service_MetricsVariationsRec  tt_service_metrics_variations;
 #endif
-    FT_Service_TTGlyfRec        tt_service_truetype_glyf;
-    FT_Service_PropertiesRec    tt_service_properties;
+    FT_Service_TTGlyfRec             tt_service_truetype_glyf;
+    FT_Service_PropertiesRec         tt_service_properties;
 
   } TTModulePIC;
 
@@ -56,6 +59,8 @@
           ( (TTModulePIC*)((lib)->pic_container.truetype) )
 #define TT_SERVICES_GET                       \
           ( GET_PIC( library )->tt_services )
+#define TT_SERVICE_METRICS_VARIATIONS_GET                       \
+          ( GET_PIC( library )->tt_service_metrics_variations )
 #define TT_SERVICE_GX_MULTI_MASTERS_GET                       \
           ( GET_PIC( library )->tt_service_gx_multi_masters )
 #define TT_SERVICE_TRUETYPE_GLYF_GET                       \
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index ca158ac..70ac15d 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType-specific tables loader (body).                              */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -73,9 +73,21 @@
     /* it is possible that a font doesn't have a glyf table at all */
     /* or its size is zero                                         */
     if ( FT_ERR_EQ( error, Table_Missing ) )
-      face->glyf_len = 0;
+    {
+      face->glyf_len    = 0;
+      face->glyf_offset = 0;
+    }
     else if ( error )
       goto Exit;
+    else
+    {
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+      if ( face->root.internal->incremental_interface )
+        face->glyf_offset = 0;
+      else
+#endif
+        face->glyf_offset = FT_STREAM_POS();
+    }
 
     FT_TRACE2(( "Locations " ));
     error = face->goto_table( face, TTAG_loca, stream, &table_len );
@@ -92,8 +104,7 @@
       if ( table_len >= 0x40000L )
       {
         FT_TRACE2(( "table too large\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
+        table_len = 0x3FFFFL;
       }
       face->num_locations = table_len >> shift;
     }
@@ -104,8 +115,7 @@
       if ( table_len >= 0x20000L )
       {
         FT_TRACE2(( "table too large\n" ));
-        error = FT_THROW( Invalid_Table );
-        goto Exit;
+        table_len = 0x1FFFFL;
       }
       face->num_locations = table_len >> shift;
     }
@@ -222,13 +232,13 @@
       }
     }
 
-    /* Check broken location data */
+    /* Check broken location data. */
     if ( pos1 > face->glyf_len )
     {
       FT_TRACE1(( "tt_face_get_location:"
-                  " too large offset=0x%08lx found for gid=0x%04lx,\n"
+                  " too large offset (0x%08lx) found for glyph index %ld,\n"
                   "                     "
-                  " exceeding the end of glyf table (0x%08lx)\n",
+                  " exceeding the end of `glyf' table (0x%08lx)\n",
                   pos1, gindex, face->glyf_len ));
       *asize = 0;
       return 0;
@@ -236,12 +246,26 @@
 
     if ( pos2 > face->glyf_len )
     {
-      FT_TRACE1(( "tt_face_get_location:"
-                  " too large offset=0x%08lx found for gid=0x%04lx,\n"
-                  "                     "
-                  " truncate at the end of glyf table (0x%08lx)\n",
-                  pos2, gindex + 1, face->glyf_len ));
-      pos2 = face->glyf_len;
+      /* We try to sanitize the last `loca' entry. */
+      if ( gindex == face->num_locations - 1 )
+      {
+        FT_TRACE1(( "tt_face_get_location:"
+                    " too large offset (0x%08lx) found for glyph index %ld,\n"
+                    "                     "
+                    " truncating at the end of `glyf' table (0x%08lx)\n",
+                    pos2, gindex + 1, face->glyf_len ));
+        pos2 = face->glyf_len;
+      }
+      else
+      {
+        FT_TRACE1(( "tt_face_get_location:"
+                    " too large offset (0x%08lx) found for glyph index %ld,\n"
+                    "                     "
+                    " exceeding the end of `glyf' table (0x%08lx)\n",
+                    pos2, gindex + 1, face->glyf_len ));
+        *asize = 0;
+        return 0;
+      }
     }
 
     /* The `loca' table must be ordered; it refers to the length of */
@@ -500,7 +524,7 @@
   {
     FT_Error   error;
     FT_Memory  memory = stream->memory;
-    FT_UInt    version, nn, num_records;
+    FT_UInt    nn, num_records;
     FT_ULong   table_size, record_size;
     FT_Byte*   p;
     FT_Byte*   limit;
@@ -517,7 +541,10 @@
     p     = face->hdmx_table;
     limit = p + table_size;
 
-    version     = FT_NEXT_USHORT( p );
+    /* Given that `hdmx' tables are losing its importance (for example, */
+    /* variation fonts introduced in OpenType 1.8 must not have this    */
+    /* table) we no longer test for a correct `version' field.          */
+    p          += 2;
     num_records = FT_NEXT_USHORT( p );
     record_size = FT_NEXT_ULONG( p );
 
@@ -536,10 +563,10 @@
       record_size &= 0xFFFFU;
 
     /* The limit for `num_records' is a heuristic value. */
-    if ( version != 0           ||
-         num_records > 255      ||
-         record_size > 0x10001L ||
-         record_size < 4        )
+    if ( num_records > 255              ||
+         ( num_records > 0            &&
+           ( record_size > 0x10001L ||
+             record_size < 4        ) ) )
     {
       error = FT_THROW( Invalid_File_Format );
       goto Fail;
diff --git a/src/truetype/ttpload.h b/src/truetype/ttpload.h
index aa2e38e..79079f3 100644
--- a/src/truetype/ttpload.h
+++ b/src/truetype/ttpload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType-specific tables loader (specification).                     */
 /*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
+/*  Copyright 1996-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c
index 0395096..5d803cd 100644
--- a/src/truetype/ttsubpix.c
+++ b/src/truetype/ttsubpix.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Subpixel Hinting.                                           */
 /*                                                                         */
-/*  Copyright 2010-2016 by                                                 */
+/*  Copyright 2010-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
diff --git a/src/truetype/ttsubpix.h b/src/truetype/ttsubpix.h
index 86844da..c68f97f 100644
--- a/src/truetype/ttsubpix.h
+++ b/src/truetype/ttsubpix.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType Subpixel Hinting.                                           */
 /*                                                                         */
-/*  Copyright 2010-2016 by                                                 */
+/*  Copyright 2010-2017 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */